package cif import ( "sort" "time" "git.fjla.uk/owlboard/timetable-mgr/dbAccess" "git.fjla.uk/owlboard/timetable-mgr/helpers" "git.fjla.uk/owlboard/timetable-mgr/log" "git.fjla.uk/owlboard/timetable-mgr/nrod" "go.uber.org/zap" ) // Runs a full update of the CIF Data, discarding any existing data and returns a new metadata struct func runFullUpdate(cfg *helpers.Configuration) (*dbAccess.CifMetadata, error) { log.Msg.Warn("All existing timetable data will be deleted") url, err := getUpdateUrl("full") if err != nil { log.Msg.Error("Unable to get update URL", zap.Error(err)) return nil, err } fullCifData, err := nrod.NrodDownload(url, cfg) if err != nil { log.Msg.Error("Unable to get CIF Data", zap.Error(err)) return nil, err } log.Msg.Debug("CIF Data Downloaded", zap.ByteString("CIF Data", fullCifData)) // I now need to define a processing function and ensure a valid type exists, then I can pass that type to a CIF Put Full function // which will handle placing the data into the database return nil, nil } // Runs the daily update for CIF Data, can handle up to five days updates at once. func runUpdate(metadata *dbAccess.CifMetadata, cfg *helpers.Configuration) (*dbAccess.CifMetadata, error) { // Do not run update if last update was on same day if isSameToday(metadata.LastUpdate) { log.Msg.Info("No CIF Update Required", zap.Time("Last update", metadata.LastUpdate)) return nil, nil } // Do not run update before 0600 as todays data will not be available if time.Now().Hour() < 6 { log.Msg.Info("Too early to update CIF Data") return nil, nil } // Check how many days ago last update was lastUpateDays := howManyDaysAgo(metadata.LastUpdate) if lastUpateDays > 5 { log.Msg.Warn("CIF Data is more than five days old. Running Full Update") newMeta, err := runFullUpdate(cfg) if err != nil { log.Msg.Error("CIF Update failed", zap.Error(err)) } return newMeta, nil } // Create a slice containing which dates need updating firstUpdate := time.Now().In(time.UTC).AddDate(0, 0, -lastUpateDays) finalUpdate := time.Now().In(time.UTC) var dates []time.Time for d := firstUpdate; d.Before(finalUpdate) || d.Equal(finalUpdate); d = d.AddDate(0, 0, 1) { dates = append(dates, d) } sort.Slice(dates, func(i, j int) bool { return dates[i].Before(dates[j]) }) // Iterate over each date, fetching then parsing the data for _, date := range dates { data, err := fetchUpdate(date, cfg) if err != nil { log.Msg.Error("Error fetching data", zap.Time("date", date)) continue } // parseCifData function needs writing parsedData, err := parseCifData(data, metadata) if err != nil { log.Msg.Error("Error parsing data", zap.Time("date", date)) } // Apply data to Database log.Msg.Info("CIF Data updated", zap.Time("date", date)) } // Use the values in metadata to determine which day to attempt to update. // First check if the last update was today, if so, I can return nil, nil - No update required ////// If the update was on the previous day, download todays data and check the sequence number and timestamp indicate that todays data is the next file that I need. ////// If the sequence number and timestamp indicate I have missed a day, download that days data first, then todays. // Write a parsing function that can handle VSTP as well as SCHEDULE data // Handle database management } // Fetches CIF Updates for a given day func fetchUpdate(t time.Time, cfg *helpers.Configuration) ([]byte, error) { url, err := getUpdateUrl("daily") if err != nil { return nil, err } url = url + getDayString(t) downloadedData, err := nrod.NrodDownload(url, cfg) if err != nil { return nil, err } return downloadedData, nil }