2024-03-27 23:35:03 +00:00
package cif
import (
2024-04-08 22:13:08 +01:00
"errors"
2024-04-10 20:46:20 +01:00
"io"
2024-03-30 01:09:12 +00:00
"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-04-04 22:39:09 +01:00
// Replaces all existing CIF Data with a new download
func runCifFullDownload ( cfg * helpers . Configuration ) error {
log . Msg . Info ( "Downloading all CIF Data" )
// Download CIF Data file
2024-03-29 13:45:58 +00:00
url , err := getUpdateUrl ( "full" )
if err != nil {
2024-04-04 22:39:09 +01:00
log . Msg . Error ( "Error getting download URL" , zap . Error ( err ) )
2024-03-29 13:45:58 +00:00
}
2024-04-10 20:19:16 +01:00
dataStream , err := nrod . NrodStream ( url , cfg )
2024-03-29 13:45:58 +00:00
if err != nil {
2024-04-04 22:39:09 +01:00
log . Msg . Error ( "Error downloading CIF data" , zap . Error ( err ) )
2024-03-29 13:45:58 +00:00
}
2024-04-04 22:39:09 +01:00
// Parse CIF file
2024-04-10 20:19:16 +01:00
parsed , err := parseCifDataStream ( dataStream )
2024-04-04 22:39:09 +01:00
if err != nil {
log . Msg . Error ( "Error parsing CIF data" , zap . Error ( err ) )
return err
2024-03-30 01:09:12 +00:00
}
2024-04-04 22:39:09 +01:00
// Drop timetable collection
2024-04-08 21:22:56 +01:00
dbAccess . DropCollection ( dbAccess . TimetableCollection ) // I should edit this to prevent removal of VSTP entries in the database.
2024-03-30 01:09:12 +00:00
2024-04-04 22:39:09 +01:00
// Process CIF file
err = processParsedCif ( parsed )
if err != nil {
log . Msg . Error ( "Error processing CIF data" , zap . Error ( err ) )
2024-03-30 01:09:12 +00:00
}
2024-04-08 21:08:07 +01:00
newMeta := generateMetadata ( & parsed . header )
ok := dbAccess . PutCifMetadata ( newMeta )
if ! ok {
log . Msg . Warn ( "CIF Data updated, but metadata write failed" )
}
2024-03-30 01:09:12 +00:00
2024-04-04 22:39:09 +01:00
return nil
}
2024-03-30 01:09:12 +00:00
2024-04-04 22:39:09 +01:00
// Runs a CIF Update for up to five days
func runCifUpdateDownload ( cfg * helpers . Configuration , metadata * dbAccess . CifMetadata , days [ ] time . Time ) error {
log . Msg . Info ( "Downloading CIF Updates" )
2024-03-30 01:09:12 +00:00
2024-04-04 22:39:09 +01:00
// Loop over dates
for _ , time := range days {
log . Msg . Info ( "Downloading CIF File" , zap . Time ( "CIF Data from" , time ) )
2024-04-02 21:07:01 +01:00
2024-04-04 22:39:09 +01:00
// Download CIF data file
data , err := fetchUpdate ( time , cfg )
2024-03-30 01:09:12 +00:00
if err != nil {
2024-04-04 22:39:09 +01:00
log . Msg . Error ( "Error fetching CIF update" , zap . Error ( err ) )
return err
2024-04-03 22:25:27 +01:00
}
2024-04-09 20:55:26 +01:00
2024-04-10 20:46:20 +01:00
// DOES NOT WORK WITH NEW NROD STREAMER
2024-04-09 20:55:26 +01:00
// If debug mode is on, call debugWriteDownload
2024-04-10 20:46:20 +01:00
// if helpers.Runtime == "debug" {
// debugWriteDownload(data)
// }
2024-04-09 20:55:26 +01:00
2024-04-04 22:39:09 +01:00
// Parse CIF file
2024-04-10 20:46:20 +01:00
parsed , err := parseCifDataStream ( data )
2024-04-03 22:25:27 +01:00
if err != nil {
2024-04-04 22:39:09 +01:00
log . Msg . Error ( "Error parsing CIF data" , zap . Error ( err ) )
return err
2024-04-03 22:25:27 +01:00
}
2024-03-29 13:45:58 +00:00
2024-04-09 21:07:21 +01:00
// Make `data` a nil pointer as it is no longer required
data = nil
2024-04-09 21:26:56 +01:00
log . Msg . Debug ( "Starting metadata checks" )
2024-04-08 22:13:08 +01:00
// Check CIF Sequence
// Skip if LastSequence is >= to this sequence
if metadata . LastSequence >= parsed . header . Metadata . Sequence {
log . Msg . Info ( "Skipping CIF file, already processed" , zap . Int64 ( "LastSequence" , metadata . LastSequence ) , zap . Int64 ( "New sequence" , parsed . header . Metadata . Sequence ) )
continue
}
// Fail if sequence number is not as expected
if parsed . header . Metadata . Sequence != metadata . LastSequence + 1 {
err := errors . New ( "out of sequence CIF data" )
log . Msg . Error ( "CIF sequence not as expected" , zap . Error ( err ) , zap . Int64 ( "LastSequence" , metadata . LastSequence ) , zap . Int64 ( "New Sequence" , parsed . header . Metadata . Sequence ) )
return err
}
2024-04-09 21:26:56 +01:00
log . Msg . Debug ( "Metadata checks complete" )
2024-04-08 22:13:08 +01:00
// Do further sequence checks - parsed.header.Metadata.Sequence MUST = metadata.LastSequence + 1
log . Msg . Debug ( "CIF Data has passed checks and should now be processed <<<<<<" )
2024-04-04 22:39:09 +01:00
// Process CIF file
2024-04-06 22:31:38 +01:00
2024-04-10 20:46:20 +01:00
// Temporarily disable METADATA GENERATION AND WRITING
// metadata = generateMetadata(&parsed.header)
2024-04-03 22:25:27 +01:00
}
2024-04-04 22:39:09 +01:00
2024-04-08 22:13:08 +01:00
ok := dbAccess . PutCifMetadata ( metadata )
if ! ok {
log . Msg . Warn ( "CIF Data updated, but metadata write failed." )
}
2024-04-06 22:28:26 +01:00
2024-04-04 22:39:09 +01:00
return nil
2024-03-27 23:35:03 +00:00
}
2024-03-30 01:09:12 +00:00
2024-04-04 22:39:09 +01:00
// Wraps nrod.NrodDownload() into a function which can handle downloading data for a given day
2024-04-10 20:46:20 +01:00
func fetchUpdate ( t time . Time , cfg * helpers . Configuration ) ( io . ReadCloser , error ) {
2024-03-30 01:09:12 +00:00
url , err := getUpdateUrl ( "daily" )
if err != nil {
return nil , err
}
2024-04-04 22:39:09 +01:00
// Append day string to URL
2024-03-30 01:09:12 +00:00
url = url + getDayString ( t )
2024-04-10 20:46:20 +01:00
dataStream , err := nrod . NrodStream ( url , cfg )
2024-03-30 01:09:12 +00:00
if err != nil {
return nil , err
}
2024-04-10 20:46:20 +01:00
return dataStream , nil
2024-03-30 01:09:12 +00:00
}