143 lines
4.0 KiB
Go
143 lines
4.0 KiB
Go
package cif
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"time"
|
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/helpers"
|
|
"git.fjla.uk/owlboard/timetable-mgr/log"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// Fetches the day string for the provided date.
|
|
func getDayString(t time.Time) string {
|
|
london, err := time.LoadLocation("Europe/London")
|
|
if err != nil {
|
|
log.Msg.Error("Unable to load time zone info", zap.Error(err))
|
|
}
|
|
|
|
timeNow := t.In(london)
|
|
day := timeNow.Weekday()
|
|
|
|
dayStrings := [...]string{"sun", "mon", "tue", "wed", "thu", "fri", "sat"}
|
|
|
|
return dayStrings[day]
|
|
}
|
|
|
|
// Simply returns the correct URL for either a 'daily' or 'full' update.
|
|
func getUpdateUrl(updateType string) (string, error) {
|
|
if updateType == "daily" {
|
|
return dailyUpdateUrl, nil
|
|
} else if updateType == "full" {
|
|
return fullUpdateUrl, nil
|
|
}
|
|
err := errors.New("invalid update type provided, must be one of 'daily' or 'full'")
|
|
return "", err
|
|
}
|
|
|
|
// Takes a time.Time as input and returns True if it is
|
|
// the same day as now, or false if it is not the same day as now
|
|
func isSameToday(t time.Time) bool {
|
|
test := t.In(time.UTC)
|
|
today := time.Now().In(time.UTC)
|
|
return test.Year() == today.Year() && test.Month() == today.Month() && test.Day() == today.Day()
|
|
}
|
|
|
|
// Returns how many days ago `t` was compared to today
|
|
func howManyDaysAgo(t time.Time) int {
|
|
log.Msg.Debug("Calculating how many days ago", zap.Time("Input time", t))
|
|
// Truncate both times to midnight in UTC timezone
|
|
today := time.Now().UTC().Truncate(24 * time.Hour)
|
|
input := t.UTC().Truncate(24 * time.Hour)
|
|
|
|
diff := today.Sub(input)
|
|
days := int(diff / (24 * time.Hour))
|
|
return days
|
|
}
|
|
|
|
// Generates a slice of time.Time values representing which days files need downloading
|
|
func generateUpdateDays(days int) []time.Time {
|
|
var updateDays []time.Time
|
|
|
|
for i := 0; i < days; i++ {
|
|
day := time.Now().Add(-time.Duration(i) * 24 * time.Hour)
|
|
updateDays = append(updateDays, day)
|
|
}
|
|
|
|
// Reverse slice to ensure chronological order
|
|
for i, j := 0, len(updateDays)-1; i < j; i, j = i+1, j-1 {
|
|
updateDays[i], updateDays[j] = updateDays[j], updateDays[i]
|
|
}
|
|
|
|
return updateDays
|
|
}
|
|
|
|
// Parses CIF Schedule Start/End Dates (YYYY-MM-DD) into time.Time types (00:00:00 for start, 23:59:59 for end)
|
|
func ParseCifDate(input *string, startOrEnd string) time.Time {
|
|
layout := "2006-01-02" // Layout of input
|
|
t, err := time.ParseInLocation(layout, *input, londonTimezone)
|
|
if err != nil {
|
|
log.Msg.Error("Error parsing date string", zap.String("date string", *input), zap.Error(err))
|
|
return time.Time{}
|
|
}
|
|
|
|
if startOrEnd == "start" {
|
|
t = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, londonTimezone)
|
|
} else if startOrEnd == "end" {
|
|
t = time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 0, londonTimezone)
|
|
} else {
|
|
log.Msg.Error("Error parsing date string", zap.String("date string", *input), zap.Error(err))
|
|
return time.Time{}
|
|
}
|
|
|
|
return t
|
|
}
|
|
|
|
// Parses CIF days_run field and converts to array of day strings
|
|
func parseDaysRun(daysBinary *string) []string {
|
|
shortDays := []string{"m", "t", "w", "th", "f", "s", "su"}
|
|
var result []string
|
|
for i, digit := range *daysBinary {
|
|
if digit == '1' {
|
|
result = append(result, shortDays[i])
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func debugWriteDownload(input *[]byte) {
|
|
if helpers.Runtime == "debug" {
|
|
log.Msg.Debug("Writing CIF Download to file")
|
|
filepath := "./cif_debug_data/"
|
|
filename := time.Now().In(londonTimezone).Format("2006-01-02_15:04:05_RawCIF")
|
|
|
|
err := os.MkdirAll(filepath, 0777)
|
|
if err != nil {
|
|
log.Msg.Error("Error creating directory", zap.Error(err))
|
|
return
|
|
}
|
|
|
|
file, err := os.Create(filepath + filename + ".jsonl")
|
|
if err != nil {
|
|
log.Msg.Error("Error creating file", zap.Error(err))
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
// Write data to file in smaller chunks
|
|
bufferSize := 4096 // Adjust the buffer size as needed
|
|
for i := 0; i < len(*input); i += bufferSize {
|
|
end := i + bufferSize
|
|
if end > len(*input) {
|
|
end = len(*input)
|
|
}
|
|
_, err := file.Write((*input)[i:end])
|
|
if err != nil {
|
|
log.Msg.Error("Error writing data to file", zap.Error(err))
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|