2024-03-27 23:35:03 +00:00
package cif
import (
2024-03-30 01:09:12 +00:00
"sort"
"time"
2024-03-27 23:35:03 +00:00
2024-03-28 22:47:08 +00:00
"git.fjla.uk/owlboard/timetable-mgr/dbAccess"
2024-03-29 13:45:58 +00:00
"git.fjla.uk/owlboard/timetable-mgr/helpers"
2024-03-27 23:35:03 +00:00
"git.fjla.uk/owlboard/timetable-mgr/log"
2024-03-29 13:45:58 +00:00
"git.fjla.uk/owlboard/timetable-mgr/nrod"
2024-03-27 23:35:03 +00:00
"go.uber.org/zap"
)
2024-03-29 13:45:58 +00:00
// 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:35:03 +00:00
}
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.
2024-03-29 13:45:58 +00:00
// 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-27 23:35:03 +00:00
}
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
}