90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package coursed
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
var (
|
|
ErrNoCurrentCourse = errors.New("error: no current course was found")
|
|
)
|
|
|
|
// `Schedule` represents a set of courses that the user is taking
|
|
//
|
|
// It stores this as a mapping between the course's short code, and the actual
|
|
// information about the course
|
|
type Schedule struct {
|
|
Courses map[string]CourseConfig
|
|
}
|
|
|
|
// `CurrentCourse` returns the current course for the user, based on the
|
|
// current time, and the schedule that they defined
|
|
//
|
|
// It is assumed courses cannot overlap, so this will never return multiple
|
|
// possible courses
|
|
//
|
|
// If no course is found, the error will be of type `ErrNoCurrentCourse`
|
|
func (s Schedule) CurrentCourse() (string, error) {
|
|
currentTime, err := time.Parse(time.Kitchen, time.Now().Format(time.Kitchen))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
for courseName, courseInfo := range s.Courses {
|
|
// Skip times that are TBD
|
|
if courseInfo.StartTime == "TBD" || courseInfo.EndTime == "TBD" {
|
|
continue
|
|
}
|
|
|
|
startTime, err := time.Parse(time.Kitchen, courseInfo.StartTime)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
endTime, err := time.Parse(time.Kitchen, courseInfo.EndTime)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if currentTime.After(startTime) && currentTime.Before(endTime) {
|
|
return courseName, nil
|
|
}
|
|
}
|
|
|
|
return "", ErrNoCurrentCourse
|
|
}
|
|
|
|
// `CourseConfig` represents all the information that is needed about a single
|
|
// course to place it on the schedule
|
|
type CourseConfig struct {
|
|
StartTime string `toml:"start_time"`
|
|
EndTime string `toml:"end_time"`
|
|
Days string `toml:"days"`
|
|
}
|
|
|
|
func (c CourseConfig) String() string {
|
|
return fmt.Sprintf("CourseConfig { start: %v, end: %v, days: %v }", c.StartTime, c.EndTime, c.Days)
|
|
}
|
|
|
|
// `LoadSchedule` loads a course schedule from the given file, and returns a
|
|
// `Schdule` object containing the parsed schedule
|
|
func LoadSchedule(fileName string) (Schedule, error) {
|
|
var v Schedule
|
|
|
|
configFile, err := os.Open(fileName)
|
|
if err != nil {
|
|
return v, err
|
|
}
|
|
defer configFile.Close()
|
|
|
|
if _, err := toml.NewDecoder(configFile).Decode(&v); err != nil {
|
|
return v, err
|
|
}
|
|
|
|
return v, nil
|
|
}
|