package schedule_parser import ( "context" "log" "pinned_message/internal/models" "pinned_message/internal/modules/data_parser" "pinned_message/internal/modules/date_parser" "pinned_message/internal/services/schedule_storage" "strings" "time" ) type performance struct { Date string `csv:"ДАТА"` Day string `csv:"день недели"` Name string `csv:"НАЗВАНИЕ"` Place string `csv:"МЕСТО"` TimeCollection string `csv:"время СБОРА (для концерта)"` TimeStart string `csv:"время НАЧАЛА"` Numbers string `csv:"ЧТО ТАНЦУЕМ"` Costumes string `csv:"КОСТЮМЫ"` } type ScheduleParser struct { dataParser data_parser.IDataParser dateParser date_parser.IDateParser scheduleStorage *schedule_storage.ScheduleStorage } func NewScheduleParser( dataParser data_parser.IDataParser, dateParser date_parser.IDateParser, scheduleStorage *schedule_storage.ScheduleStorage, ) *ScheduleParser { return &ScheduleParser{ dataParser: dataParser, dateParser: dateParser, scheduleStorage: scheduleStorage, } } func (p *ScheduleParser) Run(ctx context.Context) { ticker := time.NewTicker(30 * time.Minute) defer ticker.Stop() sheetURL := "https://docs.google.com/spreadsheets/d/1v57bCAG764j1ULXDMb3amNFMzkkLmObKWsl5oE0Xq00/edit?gid=57461713#gid=57461713" for { select { case <-ctx.Done(): return case <-ticker.C: days, err := p.parseSchedule(ctx, sheetURL) if err != nil { log.Printf("Error parse schedule: %s\n", sheetURL) break } if err := p.scheduleStorage.SaveSchedule(days); err != nil { log.Printf("Error save err: %s schedule: %s\n", err, sheetURL) } } } } func (p *ScheduleParser) parseSchedule(ctx context.Context, sheetURL string) ([]*models.Day, error) { var performances []performance if err := p.dataParser.Parse(ctx, sheetURL, &performances); err != nil { return nil, err } return p.mapSchedule(performances), nil } func (p *ScheduleParser) mapSchedule(performances []performance) []*models.Day { days := []*models.Day{} currentDay := &models.Day{} for i, performance := range performances { if performance.Name == "" || performance.Name == "-" { continue } if performance.Date != "" { if i > 0 { days = append(days, currentDay) currentDay = &models.Day{} } date, err := p.mapDate(performance.Date) if err != nil { panic(err) } currentDay.Date = date } currentDay.Performances = append( currentDay.Performances, &models.DayPerformance{ TimeCollection: performance.TimeCollection, TimeStart: performance.TimeStart, Place: performance.Place, Name: performance.Name, Numbers: p.mapNumbers(performance.Numbers), Costumes: performance.Costumes, }, ) } days = append(days, currentDay) return days } func (p *ScheduleParser) mapDate(date string) (time.Time, error) { if date == "" { return time.Time{}, nil } return p.dateParser.Parse(date) } func (p *ScheduleParser) mapNumbers(numbers string) []*models.Number { names := strings.Split(numbers, ",") res := make([]*models.Number, 0, len(names)) for _, name := range names { res = append( res, &models.Number{ Name: name, }, ) } return res }