diff --git a/commands.go b/commands.go index 2547681..10b4ed3 100644 --- a/commands.go +++ b/commands.go @@ -7,6 +7,8 @@ import ( "time" "github.com/bwmarrin/discordgo" + "github.com/rs/zerolog/log" + "github.com/samber/lo" ) var ( @@ -283,8 +285,27 @@ func IcsCommandHandler(s *discordgo.Session, i *discordgo.InteractionCreate) err return fmt.Errorf("Error requesting meeting time: %w", err) } - events := []string{} + if len(meetingTimes) == 0 { + return fmt.Errorf("unexpected - no meeting time data found for course") + } + // Check if the course has any meeting times + _, exists := lo.Find(meetingTimes, func(mt MeetingTimeResponse) bool { + switch mt.MeetingTime.MeetingType { + case "ID", "OA": + return false + default: + return true + } + }) + + if !exists { + log.Warn().Str("crn", course.CourseReferenceNumber).Msg("Non-meeting course requested for ICS file") + RespondError(s, i.Interaction, "The course requested does not meet at a defined moment in time.", nil) + return nil + } + + events := []string{} for _, meeting := range meetingTimes { now := time.Now().In(CentralTimeLocation) uid := fmt.Sprintf("%d-%s@ical.banner.xevion.dev", now.Unix(), meeting.CourseReferenceNumber) diff --git a/types.go b/types.go index 6d710d9..19ec960 100644 --- a/types.go +++ b/types.go @@ -56,8 +56,9 @@ type MeetingTimeResponse struct { // The number of credit hours this class is worth (assumably) CreditHourSession float64 `json:"creditHourSession"` // The number of hours per week this class meets (e.g. 2.5) - HoursWeek float64 `json:"hoursWeek"` - MeetingScheduleType string `json:"meetingScheduleType"` + HoursWeek float64 `json:"hoursWeek"` + // Unknown meaning - e.g. AFF, AIN, AHB, FFF, AFF, EFF, DFF, IFF, EHB, JFF, KFF, BFF, BIN + MeetingScheduleType string `json:"meetingScheduleType"` // The short identifier for the meeting type (e.g. FF, HB, OS, OA) MeetingType string `json:"meetingType"` // The long name of the meeting type (e.g. Traditional in-person) @@ -95,7 +96,7 @@ func (m *MeetingTimeResponse) String() string { case "OH": return fmt.Sprintf("%s\nOnline Partial", m.TimeString()) case "ID": - return "TBA" + return "To Be Arranged" case "FF": return fmt.Sprintf("%s\n%s", m.TimeString(), m.PlaceString()) } @@ -119,6 +120,7 @@ func (m *MeetingTimeResponse) TimeString() string { func (m *MeetingTimeResponse) PlaceString() string { mt := m.MeetingTime + // TODO: ADd format case for partial online classes if mt.Room == "" { return "Online" } @@ -195,7 +197,7 @@ func (m *MeetingTimeResponse) EndDay() time.Time { func (m *MeetingTimeResponse) StartTime() *NaiveTime { raw := m.MeetingTime.BeginTime if raw == "" { - return nil + log.Fatal().Stack().Msg("Start time is empty") } value, err := strconv.ParseUint(raw, 10, 32)