package schedule_storage import ( "encoding/json" "fmt" "log" "os" "pinned_message/internal/models" "regexp" "strings" "time" ) type ScheduleStorage struct { filepath string } func NewScheduleStorage( filepath string, ) *ScheduleStorage { return &ScheduleStorage{ filepath: filepath, } } func (s *ScheduleStorage) SaveSchedule(schedule *models.Schedule) error { data, err := json.Marshal(schedule) if err != nil { return err } if err := os.WriteFile(s.filepath, data, 0644); err != nil { return err } log.Printf("save schedule to: %s", s.filepath) return nil } func (s *ScheduleStorage) GetSchedule() (*models.Schedule, error) { data, err := os.ReadFile(s.filepath) if err != nil { return nil, fmt.Errorf("schedule file %s not found", s.filepath) } log.Printf("load schedule from: %s", s.filepath) schedule := &models.Schedule{} if err := json.Unmarshal(data, &schedule); err != nil { return nil, err } filterDays := make([]*models.Day, 0, len(schedule.Days)) for _, day := range schedule.Days { if isBeforeToday(day.Date) { continue } for i := range day.Performances { if day.Performances[i].TimeCollection == "" || day.Performances[i].TimeCollection == "-" { day.Performances[i].TimeCollection = GetStartTime(day.Performances[i].TimeStart) } filterNumbers := make([]*models.Number, 0, len(day.Performances[i].Numbers)) for _, number := range day.Performances[i].Numbers { name := strings.TrimSpace(number.Name) if name == "" || name == "-" { continue } filterNumbers = append(filterNumbers, number) } day.Performances[i].Numbers = filterNumbers } filterDays = append(filterDays, day) } schedule.Days = filterDays return schedule, nil } func isBeforeToday(targetDate time.Time) bool { now := time.Now() todayMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) targetMidnight := time.Date(targetDate.Year(), targetDate.Month(), targetDate.Day(), 0, 0, 0, 0, targetDate.Location()) return targetMidnight.Before(todayMidnight) } // Компилируем регулярное выражение один раз (для производительности) // Ищем от 1 до 2 цифр, затем двоеточие, затем ровно 2 цифры var timeRegex = regexp.MustCompile(`\d{1,2}:\d{2}`) // GetStartTime извлекает первое найденное время из строки func GetStartTime(timeRange string) string { // FindString возвращает самое первое совпадение в строке return timeRegex.FindString(timeRange) }