mirror of
https://github.com/Xevion/banner.git
synced 2025-12-06 01:14:22 -06:00
refactor: rearrange & rename files, fix meeting times response decode
This commit is contained in:
@@ -22,10 +22,10 @@ import (
|
||||
"github.com/samber/lo"
|
||||
"resty.dev/v3"
|
||||
|
||||
"banner/internal"
|
||||
"banner/internal/api"
|
||||
"banner/internal/bot"
|
||||
"banner/internal/config"
|
||||
"banner/internal/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -57,25 +57,25 @@ func init() {
|
||||
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
|
||||
|
||||
// Use the custom console writer if we're in development
|
||||
isDevelopment := utils.GetFirstEnv("ENVIRONMENT", "RAILWAY_ENVIRONMENT")
|
||||
isDevelopment := internal.GetFirstEnv("ENVIRONMENT", "RAILWAY_ENVIRONMENT")
|
||||
if isDevelopment == "" {
|
||||
isDevelopment = "development"
|
||||
}
|
||||
|
||||
if isDevelopment == "development" {
|
||||
log.Logger = zerolog.New(utils.NewConsoleWriter()).With().Timestamp().Logger()
|
||||
log.Logger = zerolog.New(config.NewConsoleWriter()).With().Timestamp().Logger()
|
||||
} else {
|
||||
log.Logger = zerolog.New(utils.LogSplitter{Std: os.Stdout, Err: os.Stderr}).With().Timestamp().Logger()
|
||||
log.Logger = zerolog.New(config.LogSplitter{Std: os.Stdout, Err: os.Stderr}).With().Timestamp().Logger()
|
||||
}
|
||||
log.Debug().Str("environment", isDevelopment).Msg("Loggers Setup")
|
||||
|
||||
// Set discordgo's logger to use zerolog
|
||||
discordgo.Logger = utils.DiscordGoLogger
|
||||
discordgo.Logger = internal.DiscordGoLogger
|
||||
}
|
||||
|
||||
func initRedis(cfg *config.Config) {
|
||||
// Setup redis
|
||||
redisUrl := utils.GetFirstEnv("REDIS_URL", "REDIS_PRIVATE_URL")
|
||||
redisUrl := internal.GetFirstEnv("REDIS_URL", "REDIS_PRIVATE_URL")
|
||||
if redisUrl == "" {
|
||||
log.Fatal().Stack().Msg("REDIS_URL/REDIS_PRIVATE_URL not set")
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Try to grab the environment variable, or default to development
|
||||
environment := utils.GetFirstEnv("ENVIRONMENT", "RAILWAY_ENVIRONMENT")
|
||||
environment := internal.GetFirstEnv("ENVIRONMENT", "RAILWAY_ENVIRONMENT")
|
||||
if environment == "" {
|
||||
environment = "development"
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"banner/internal"
|
||||
"banner/internal/config"
|
||||
"banner/internal/models"
|
||||
"banner/internal/utils"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -51,7 +51,7 @@ func SessionMiddleware(c *resty.Client, r *resty.Response) error {
|
||||
// GenerateSession generates a new session ID (nonce) for use with the Banner API.
|
||||
// Don't use this function directly, use GetSession instead.
|
||||
func GenerateSession() string {
|
||||
return utils.RandomString(5) + utils.Nonce()
|
||||
return internal.RandomString(5) + internal.Nonce()
|
||||
}
|
||||
|
||||
var terms []BannerTerm
|
||||
@@ -131,7 +131,7 @@ func (a *API) GetTerms(search string, page int, maxResults int) ([]BannerTerm, e
|
||||
SetQueryParam("searchTerm", search).
|
||||
SetQueryParam("offset", strconv.Itoa(page)).
|
||||
SetQueryParam("max", strconv.Itoa(maxResults)).
|
||||
SetQueryParam("_", utils.Nonce()).
|
||||
SetQueryParam("_", internal.Nonce()).
|
||||
SetExpectResponseContentType("application/json").
|
||||
SetResult(&[]BannerTerm{})
|
||||
|
||||
@@ -206,7 +206,7 @@ func (a *API) GetPartOfTerms(search string, term int, offset int, maxResults int
|
||||
SetQueryParam("offset", strconv.Itoa(offset)).
|
||||
SetQueryParam("max", strconv.Itoa(maxResults)).
|
||||
SetQueryParam("uniqueSessionId", a.EnsureSession()).
|
||||
SetQueryParam("_", utils.Nonce()).
|
||||
SetQueryParam("_", internal.Nonce()).
|
||||
SetExpectResponseContentType("application/json").
|
||||
SetResult(&[]BannerTerm{})
|
||||
|
||||
@@ -239,7 +239,7 @@ func (a *API) GetInstructors(search string, term string, offset int, maxResults
|
||||
SetQueryParam("offset", strconv.Itoa(offset)).
|
||||
SetQueryParam("max", strconv.Itoa(maxResults)).
|
||||
SetQueryParam("uniqueSessionId", a.EnsureSession()).
|
||||
SetQueryParam("_", utils.Nonce()).
|
||||
SetQueryParam("_", internal.Nonce()).
|
||||
SetExpectResponseContentType("application/json").
|
||||
SetResult(&[]Instructor{})
|
||||
|
||||
@@ -337,7 +337,7 @@ func (a *API) GetSubjects(search string, term string, offset int, maxResults int
|
||||
SetQueryParam("offset", strconv.Itoa(offset)).
|
||||
SetQueryParam("max", strconv.Itoa(maxResults)).
|
||||
SetQueryParam("uniqueSessionId", a.EnsureSession()).
|
||||
SetQueryParam("_", utils.Nonce()).
|
||||
SetQueryParam("_", internal.Nonce()).
|
||||
SetExpectResponseContentType("application/json").
|
||||
SetResult(&[]Pair{})
|
||||
|
||||
@@ -370,7 +370,7 @@ func (a *API) GetCampuses(search string, term int, offset int, maxResults int) (
|
||||
SetQueryParam("offset", strconv.Itoa(offset)).
|
||||
SetQueryParam("max", strconv.Itoa(maxResults)).
|
||||
SetQueryParam("uniqueSessionId", a.EnsureSession()).
|
||||
SetQueryParam("_", utils.Nonce()).
|
||||
SetQueryParam("_", internal.Nonce()).
|
||||
SetExpectResponseContentType("application/json").
|
||||
SetResult(&[]Pair{})
|
||||
|
||||
@@ -403,7 +403,7 @@ func (a *API) GetInstructionalMethods(search string, term string, offset int, ma
|
||||
SetQueryParam("offset", strconv.Itoa(offset)).
|
||||
SetQueryParam("max", strconv.Itoa(maxResults)).
|
||||
SetQueryParam("uniqueSessionId", a.EnsureSession()).
|
||||
SetQueryParam("_", utils.Nonce()).
|
||||
SetQueryParam("_", internal.Nonce()).
|
||||
SetExpectResponseContentType("application/json").
|
||||
SetResult(&[]Pair{})
|
||||
|
||||
@@ -423,23 +423,27 @@ func (a *API) GetInstructionalMethods(search string, term string, offset int, ma
|
||||
// It makes an HTTP GET request to the appropriate API endpoint and parses the response to extract the meeting time data.
|
||||
// The function returns a MeetingTimeResponse struct containing the extracted information.
|
||||
func (a *API) GetCourseMeetingTime(term int, crn int) ([]models.MeetingTimeResponse, error) {
|
||||
type responseWrapper struct {
|
||||
Fmt []models.MeetingTimeResponse `json:"fmt"`
|
||||
}
|
||||
|
||||
req := a.config.Client.NewRequest().
|
||||
SetQueryParam("term", strconv.Itoa(term)).
|
||||
SetQueryParam("courseReferenceNumber", strconv.Itoa(crn)).
|
||||
SetExpectResponseContentType("application/json").
|
||||
SetResult(&[]models.MeetingTimeResponse{})
|
||||
SetResult(&responseWrapper{})
|
||||
|
||||
res, err := req.Get("/searchResults/getFacultyMeetingTimes")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get meeting time: %w", err)
|
||||
}
|
||||
|
||||
meetingTimes, ok := res.Result().(*[]models.MeetingTimeResponse)
|
||||
result, ok := res.Result().(*responseWrapper)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("meeting times parsing failed to cast: %v", res.Result())
|
||||
}
|
||||
|
||||
return *meetingTimes, nil
|
||||
return result.Fmt, nil
|
||||
}
|
||||
|
||||
// ResetDataForm makes a POST request that needs to be made upon before new search requests can be made.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"banner/internal"
|
||||
"banner/internal/models"
|
||||
"banner/internal/utils"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@@ -70,7 +70,7 @@ func (a *API) Scrape() error {
|
||||
|
||||
// GetExpiredSubjects returns a list of subjects that are expired and should be scraped.
|
||||
func (a *API) GetExpiredSubjects() ([]string, error) {
|
||||
term := utils.Default(time.Now()).ToString()
|
||||
term := Default(time.Now()).ToString()
|
||||
subjects := make([]string, 0)
|
||||
|
||||
// Create a timeout context for Redis operations
|
||||
@@ -109,7 +109,7 @@ func (a *API) ScrapeMajor(subject string) error {
|
||||
for {
|
||||
// Build & execute the query
|
||||
query := NewQuery().Offset(offset).MaxResults(MaxPageSize * 2).Subject(subject)
|
||||
term := utils.Default(time.Now()).ToString()
|
||||
term := Default(time.Now()).ToString()
|
||||
result, err := a.Search(term, query, "subjectDescription", false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("search failed: %w (%s)", err, query.String())
|
||||
@@ -152,7 +152,7 @@ func (a *API) ScrapeMajor(subject string) error {
|
||||
break
|
||||
}
|
||||
|
||||
term := utils.Default(time.Now()).ToString()
|
||||
term := Default(time.Now()).ToString()
|
||||
|
||||
// Calculate the expiry time for the scrape (1 hour for every 200 classes, random +-15%) with a minimum of 1 hour
|
||||
var scrapeExpiry time.Duration
|
||||
@@ -190,7 +190,7 @@ func (a *API) CalculateExpiry(term string, count int, priority bool) time.Durati
|
||||
// Subjects with less than 50 classes have a reversed expiry (less classes, longer interval)
|
||||
// 1 class => 12 hours, 49 classes => 1 hour
|
||||
if count < 50 {
|
||||
hours := utils.Slope(utils.Point{X: 1, Y: 12}, utils.Point{X: 49, Y: 1}, float64(count)).Y
|
||||
hours := internal.Slope(internal.Point{X: 1, Y: 12}, internal.Point{X: 49, Y: 1}, float64(count)).Y
|
||||
baseExpiry = time.Duration(hours * float64(time.Hour))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"banner/internal/utils"
|
||||
"banner/internal"
|
||||
"net/url"
|
||||
|
||||
log "github.com/rs/zerolog/log"
|
||||
@@ -18,7 +18,7 @@ func (a *API) Setup() {
|
||||
|
||||
for _, path := range requestQueue {
|
||||
req := a.config.Client.NewRequest().
|
||||
SetQueryParam("_", utils.Nonce()).
|
||||
SetQueryParam("_", internal.Nonce()).
|
||||
SetExpectResponseContentType("application/json")
|
||||
|
||||
res, err := req.Get(path)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package utils
|
||||
package api
|
||||
|
||||
import (
|
||||
"banner/internal/config"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Term selection should yield smart results based on the current time, as well as the input provided.
|
||||
@@ -32,9 +30,6 @@ var (
|
||||
func init() {
|
||||
loc, _ := time.LoadLocation(config.CentralTimezoneName)
|
||||
SpringRange, SummerRange, FallRange = GetYearDayRange(loc, uint16(time.Now().Year()))
|
||||
|
||||
currentTerm, nextTerm := GetCurrentTerm(time.Now())
|
||||
log.Debug().Str("CurrentTerm", fmt.Sprintf("%+v", currentTerm)).Str("NextTerm", fmt.Sprintf("%+v", nextTerm)).Msg("GetCurrentTerm")
|
||||
}
|
||||
|
||||
type YearDayRange struct {
|
||||
@@ -1,9 +1,9 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"banner/internal"
|
||||
"banner/internal/api"
|
||||
"banner/internal/models"
|
||||
"banner/internal/utils"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"regexp"
|
||||
@@ -40,7 +40,7 @@ var SearchCommandDefinition = &discordgo.ApplicationCommand{
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
MinLength: utils.GetIntPointer(0),
|
||||
MinLength: internal.GetIntPointer(0),
|
||||
MaxLength: 48,
|
||||
Name: "title",
|
||||
Description: "Course Title (exact, use autocomplete)",
|
||||
@@ -50,7 +50,7 @@ var SearchCommandDefinition = &discordgo.ApplicationCommand{
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Name: "code",
|
||||
MinLength: utils.GetIntPointer(4),
|
||||
MinLength: internal.GetIntPointer(4),
|
||||
Description: "Course Code (e.g. 3743, 3000-3999, 3xxx, 3000-)",
|
||||
Required: false,
|
||||
},
|
||||
@@ -248,8 +248,8 @@ func SearchCommandHandler(b *Bot, s *discordgo.Session, i *discordgo.Interaction
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Embeds: []*discordgo.MessageEmbed{
|
||||
{
|
||||
Footer: utils.GetFetchedFooter(b.Config, fetch_time),
|
||||
Description: fmt.Sprintf("%d Class%s", courses.TotalCount, utils.Plural(courses.TotalCount)),
|
||||
Footer: internal.GetFetchedFooter(b.Config, fetch_time),
|
||||
Description: fmt.Sprintf("%d Class%s", courses.TotalCount, internal.Plural(courses.TotalCount)),
|
||||
Fields: fields[:min(25, len(fields))],
|
||||
Color: color,
|
||||
},
|
||||
@@ -267,7 +267,7 @@ var TermCommandDefinition = &discordgo.ApplicationCommand{
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
MinLength: utils.GetIntPointer(0),
|
||||
MinLength: internal.GetIntPointer(0),
|
||||
MaxLength: 8,
|
||||
Name: "search",
|
||||
Description: "Term to search for",
|
||||
@@ -278,7 +278,7 @@ var TermCommandDefinition = &discordgo.ApplicationCommand{
|
||||
Name: "page",
|
||||
Description: "Page Number",
|
||||
Required: false,
|
||||
MinValue: utils.GetFloatPointer(1),
|
||||
MinValue: internal.GetFloatPointer(1),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func TermCommandHandler(b *Bot, s *discordgo.Session, i *discordgo.InteractionCr
|
||||
termResult, err := b.API.GetTerms(searchTerm, pageNumber, 25)
|
||||
|
||||
if err != nil {
|
||||
utils.RespondError(s, i.Interaction, "Error while fetching terms", err)
|
||||
internal.RespondError(s, i.Interaction, "Error while fetching terms", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -328,8 +328,8 @@ func TermCommandHandler(b *Bot, s *discordgo.Session, i *discordgo.InteractionCr
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Embeds: []*discordgo.MessageEmbed{
|
||||
{
|
||||
Footer: utils.GetFetchedFooter(b.Config, fetch_time),
|
||||
Description: fmt.Sprintf("%d term%s (page %d)", len(termResult), utils.Plural(len(termResult)), pageNumber),
|
||||
Footer: internal.GetFetchedFooter(b.Config, fetch_time),
|
||||
Description: fmt.Sprintf("%d term%s (page %d)", len(termResult), internal.Plural(len(termResult)), pageNumber),
|
||||
Fields: fields[:min(25, len(fields))],
|
||||
},
|
||||
},
|
||||
@@ -387,7 +387,7 @@ func TimeCommandHandler(b *Bot, s *discordgo.Session, i *discordgo.InteractionCr
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Embeds: []*discordgo.MessageEmbed{
|
||||
{
|
||||
Footer: utils.GetFetchedFooter(b.Config, fetch_time),
|
||||
Footer: internal.GetFetchedFooter(b.Config, fetch_time),
|
||||
Description: "",
|
||||
Fields: []*discordgo.MessageEmbedField{
|
||||
{
|
||||
@@ -404,7 +404,7 @@ func TimeCommandHandler(b *Bot, s *discordgo.Session, i *discordgo.InteractionCr
|
||||
},
|
||||
{
|
||||
Name: "Days of Week",
|
||||
Value: utils.WeekdaysToString(meetingTime.Days()),
|
||||
Value: internal.WeekdaysToString(meetingTime.Days()),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -430,7 +430,7 @@ var IcsCommandDefinition = &discordgo.ApplicationCommand{
|
||||
|
||||
func IcsCommandHandler(b *Bot, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
||||
// Parse all options
|
||||
options := utils.ParseOptions(i.ApplicationCommandData().Options)
|
||||
options := internal.ParseOptions(i.ApplicationCommandData().Options)
|
||||
crn := options.GetInt("crn")
|
||||
|
||||
course, err := b.API.GetCourse(strconv.Itoa(int(crn)))
|
||||
@@ -460,7 +460,7 @@ func IcsCommandHandler(b *Bot, s *discordgo.Session, i *discordgo.InteractionCre
|
||||
|
||||
if !exists {
|
||||
log.Warn().Str("crn", course.CourseReferenceNumber).Msg("Non-meeting course requested for ICS file")
|
||||
utils.RespondError(s, i.Interaction, "The course requested does not meet at a defined moment in time.", nil)
|
||||
internal.RespondError(s, i.Interaction, "The course requested does not meet at a defined moment in time.", nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"banner/internal/utils"
|
||||
"banner/internal"
|
||||
"fmt"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
@@ -13,7 +13,7 @@ func (b *Bot) RegisterHandlers() {
|
||||
b.Session.AddHandler(func(internalSession *discordgo.Session, interaction *discordgo.InteractionCreate) {
|
||||
// Handle commands during restart (highly unlikely, but just in case)
|
||||
if b.isClosing {
|
||||
err := utils.RespondError(internalSession, interaction.Interaction, "Bot is currently restarting, try again later.", nil)
|
||||
err := internal.RespondError(internalSession, interaction.Interaction, "Bot is currently restarting, try again later.", nil)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to respond with restart error feedback")
|
||||
}
|
||||
@@ -28,18 +28,18 @@ func (b *Bot) RegisterHandlers() {
|
||||
options.Str(option.Name, fmt.Sprintf("%v", option.Value))
|
||||
}
|
||||
|
||||
event := log.Info().Str("name", name).Str("user", utils.GetUser(interaction).Username).Dict("options", options)
|
||||
event := log.Info().Str("name", name).Str("user", internal.GetUser(interaction).Username).Dict("options", options)
|
||||
|
||||
// If the command was invoked in a guild, add guild & channel info to the log
|
||||
if interaction.Member != nil {
|
||||
guild := zerolog.Dict()
|
||||
guild.Str("id", interaction.GuildID)
|
||||
guild.Str("name", utils.GetGuildName(b.Config, internalSession, interaction.GuildID))
|
||||
guild.Str("name", internal.GetGuildName(b.Config, internalSession, interaction.GuildID))
|
||||
event.Dict("guild", guild)
|
||||
|
||||
channel := zerolog.Dict()
|
||||
channel.Str("id", interaction.ChannelID)
|
||||
guild.Str("name", utils.GetChannelName(b.Config, internalSession, interaction.ChannelID))
|
||||
guild.Str("name", internal.GetChannelName(b.Config, internalSession, interaction.ChannelID))
|
||||
event.Dict("channel", channel)
|
||||
} else {
|
||||
// If the command was invoked in a DM, add the user info to the log
|
||||
@@ -58,7 +58,7 @@ func (b *Bot) RegisterHandlers() {
|
||||
log.Error().Stack().Str("commandName", name).Interface("detail", err).Msg("Command Handler Panic")
|
||||
|
||||
// Respond with error
|
||||
err := utils.RespondError(internalSession, interaction.Interaction, "Unexpected Error: command handler panic", nil)
|
||||
err := internal.RespondError(internalSession, interaction.Interaction, "Unexpected Error: command handler panic", nil)
|
||||
if err != nil {
|
||||
log.Error().Stack().Str("commandName", name).Err(err).Msg("Failed to respond with panic error feedback")
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (b *Bot) RegisterHandlers() {
|
||||
log.Error().Str("commandName", name).Err(err).Msg("Command Handler Error")
|
||||
|
||||
// Respond with error
|
||||
err = utils.RespondError(internalSession, interaction.Interaction, fmt.Sprintf("Unexpected Error: %s", err.Error()), nil)
|
||||
err = internal.RespondError(internalSession, interaction.Interaction, fmt.Sprintf("Unexpected Error: %s", err.Error()), nil)
|
||||
if err != nil {
|
||||
log.Error().Stack().Str("commandName", name).Err(err).Msg("Failed to respond with error feedback")
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func (b *Bot) RegisterHandlers() {
|
||||
log.Error().Stack().Str("commandName", name).Msg("Command Interaction Has No Handler")
|
||||
|
||||
// Respond with error
|
||||
utils.RespondError(internalSession, interaction.Interaction, "Unexpected Error: interaction has no handler", nil)
|
||||
internal.RespondError(internalSession, interaction.Interaction, "Unexpected Error: interaction has no handler", nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package bot
|
||||
import (
|
||||
"banner/internal/api"
|
||||
"banner/internal/config"
|
||||
"banner/internal/utils"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -28,7 +27,7 @@ func (b *Bot) SetClosing() {
|
||||
|
||||
func (b *Bot) GetSession() (string, error) {
|
||||
sessionID := b.API.EnsureSession()
|
||||
term := utils.Default(time.Now()).ToString()
|
||||
term := api.Default(time.Now()).ToString()
|
||||
|
||||
log.Info().Str("term", term).Str("sessionID", sessionID).Msg("Setting selected term")
|
||||
err := b.API.SelectTerm(term, sessionID)
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package config
|
||||
|
||||
import (
|
||||
"io"
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package internal
|
||||
|
||||
import "fmt"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package internal
|
||||
|
||||
import (
|
||||
"banner/internal/config"
|
||||
@@ -1,7 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"banner/internal/utils"
|
||||
"banner/internal"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -11,8 +11,6 @@ import (
|
||||
log "github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const JsonContentType = "application/json"
|
||||
|
||||
type FacultyItem struct {
|
||||
BannerId string `json:"bannerId"`
|
||||
Category *string `json:"category"`
|
||||
@@ -114,7 +112,7 @@ func (m *MeetingTimeResponse) TimeString() string {
|
||||
return "???"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %s-%s", utils.WeekdaysToString(m.Days()), m.StartTime().String(), m.EndTime().String())
|
||||
return fmt.Sprintf("%s %s-%s", internal.WeekdaysToString(m.Days()), m.StartTime().String(), m.EndTime().String())
|
||||
}
|
||||
|
||||
// PlaceString returns a formatted string best representing the place of the meeting time
|
||||
@@ -195,7 +193,7 @@ func (m *MeetingTimeResponse) EndDay() time.Time {
|
||||
|
||||
// StartTime returns the start time of the meeting time as a NaiveTime object
|
||||
// This is not cached and is parsed on each invocation. It may also panic without handling.
|
||||
func (m *MeetingTimeResponse) StartTime() *utils.NaiveTime {
|
||||
func (m *MeetingTimeResponse) StartTime() *internal.NaiveTime {
|
||||
raw := m.MeetingTime.BeginTime
|
||||
if raw == "" {
|
||||
log.Panic().Stack().Msg("Start time is empty")
|
||||
@@ -206,12 +204,12 @@ func (m *MeetingTimeResponse) StartTime() *utils.NaiveTime {
|
||||
log.Panic().Stack().Err(err).Str("raw", raw).Msg("Cannot parse start time integer")
|
||||
}
|
||||
|
||||
return utils.ParseNaiveTime(value)
|
||||
return internal.ParseNaiveTime(value)
|
||||
}
|
||||
|
||||
// EndTime returns the end time of the meeting time as a NaiveTime object
|
||||
// This is not cached and is parsed on each invocation. It may also panic without handling.
|
||||
func (m *MeetingTimeResponse) EndTime() *utils.NaiveTime {
|
||||
func (m *MeetingTimeResponse) EndTime() *internal.NaiveTime {
|
||||
raw := m.MeetingTime.EndTime
|
||||
if raw == "" {
|
||||
return nil
|
||||
@@ -222,7 +220,7 @@ func (m *MeetingTimeResponse) EndTime() *utils.NaiveTime {
|
||||
log.Panic().Stack().Err(err).Str("raw", raw).Msg("Cannot parse end time integer")
|
||||
}
|
||||
|
||||
return utils.ParseNaiveTime(value)
|
||||
return internal.ParseNaiveTime(value)
|
||||
}
|
||||
|
||||
type RRule struct {
|
||||
|
||||
Reference in New Issue
Block a user