timetable-mgr/src/cif/update.go

114 lines
3.7 KiB
Go
Raw Normal View History

package cif
import (
2024-03-30 01:09:12 +00:00
"sort"
"time"
2024-03-28 22:47:08 +00:00
"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
}
2024-03-30 01:09:12 +00:00
// 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))
}
2024-03-27 23:38:39 +00:00
2024-03-28 22:47:08 +00:00
// 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.
2024-03-27 23:38:39 +00:00
// Write a parsing function that can handle VSTP as well as SCHEDULE data
// Handle database management
}
2024-03-30 01:09:12 +00:00
// 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
}