transition time ranged queries to timeframe (#117)

This commit is contained in:
Gabe Farrell 2026-01-01 01:56:16 -05:00 committed by GitHub
parent ad3c51a70e
commit d327729bff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 2032 additions and 335 deletions

View file

@ -5,7 +5,6 @@ import (
"net/http"
"strconv"
"strings"
"time"
"github.com/gabehf/koito/internal/db"
"github.com/gabehf/koito/internal/logger"
@ -37,17 +36,6 @@ func OptsFromRequest(r *http.Request) db.GetItemsOpts {
page = 1
}
weekStr := r.URL.Query().Get("week")
week, _ := strconv.Atoi(weekStr)
monthStr := r.URL.Query().Get("month")
month, _ := strconv.Atoi(monthStr)
yearStr := r.URL.Query().Get("year")
year, _ := strconv.Atoi(yearStr)
fromStr := r.URL.Query().Get("from")
from, _ := strconv.Atoi(fromStr)
toStr := r.URL.Query().Get("to")
to, _ := strconv.Atoi(toStr)
artistIdStr := r.URL.Query().Get("artist_id")
artistId, _ := strconv.Atoi(artistIdStr)
albumIdStr := r.URL.Query().Get("album_id")
@ -55,6 +43,8 @@ func OptsFromRequest(r *http.Request) db.GetItemsOpts {
trackIdStr := r.URL.Query().Get("track_id")
trackId, _ := strconv.Atoi(trackIdStr)
tf := TimeframeFromRequest(r)
var period db.Period
switch strings.ToLower(r.URL.Query().Get("period")) {
case "day":
@ -67,108 +57,48 @@ func OptsFromRequest(r *http.Request) db.GetItemsOpts {
period = db.PeriodYear
case "all_time":
period = db.PeriodAllTime
default:
l.Debug().Msgf("OptsFromRequest: Using default value '%s' for period", db.PeriodDay)
period = db.PeriodDay
}
l.Debug().Msgf("OptsFromRequest: Parsed options: limit=%d, page=%d, week=%d, month=%d, year=%d, from=%d, to=%d, artist_id=%d, album_id=%d, track_id=%d, period=%s",
limit, page, week, month, year, from, to, artistId, albumId, trackId, period)
limit, page, tf.Week, tf.Month, tf.Year, tf.FromUnix, tf.ToUnix, artistId, albumId, trackId, period)
return db.GetItemsOpts{
Limit: limit,
Period: period,
Page: page,
Week: week,
Month: month,
Year: year,
From: int64(from),
To: int64(to),
ArtistID: artistId,
AlbumID: albumId,
TrackID: trackId,
Limit: limit,
Page: page,
Timeframe: tf,
ArtistID: artistId,
AlbumID: albumId,
TrackID: trackId,
}
}
// Takes a request and returns a db.Timeframe representing the week, month, year, period, or unix
// time range specified by the request parameters
func TimeframeFromRequest(r *http.Request) db.Timeframe {
opts := OptsFromRequest(r)
now := time.Now()
loc := now.Location()
q := r.URL.Query()
// if 'from' is set, but 'to' is not set, assume 'to' should be now
if opts.From != 0 && opts.To == 0 {
opts.To = now.Unix()
}
// YEAR
if opts.Year != 0 && opts.Month == 0 && opts.Week == 0 {
start := time.Date(opts.Year, 1, 1, 0, 0, 0, 0, loc)
end := time.Date(opts.Year+1, 1, 1, 0, 0, 0, 0, loc).Add(-time.Second)
opts.From = start.Unix()
opts.To = end.Unix()
}
// MONTH (+ optional year)
if opts.Month != 0 {
year := opts.Year
if year == 0 {
year = now.Year()
if int(now.Month()) < opts.Month {
year--
}
parseInt := func(key string) int {
v := q.Get(key)
if v == "" {
return 0
}
start := time.Date(year, time.Month(opts.Month), 1, 0, 0, 0, 0, loc)
end := endOfMonth(year, time.Month(opts.Month), loc)
opts.From = start.Unix()
opts.To = end.Unix()
i, _ := strconv.Atoi(v)
return i
}
// WEEK (+ optional year)
if opts.Week != 0 {
year := opts.Year
if year == 0 {
year = now.Year()
_, currentWeek := now.ISOWeek()
if currentWeek < opts.Week {
year--
}
parseInt64 := func(key string) int64 {
v := q.Get(key)
if v == "" {
return 0
}
// ISO week 1 is defined as the week with Jan 4 in it
jan4 := time.Date(year, 1, 4, 0, 0, 0, 0, loc)
week1Start := startOfWeek(jan4)
start := week1Start.AddDate(0, 0, (opts.Week-1)*7)
end := endOfWeek(start)
opts.From = start.Unix()
opts.To = end.Unix()
i, _ := strconv.ParseInt(v, 10, 64)
return i
}
return db.Timeframe{
Period: opts.Period,
T1u: opts.From,
T2u: opts.To,
Period: db.Period(q.Get("period")),
Year: parseInt("year"),
Month: parseInt("month"),
Week: parseInt("week"),
FromUnix: parseInt64("from"),
ToUnix: parseInt64("to"),
}
}
func startOfWeek(t time.Time) time.Time {
// ISO week: Monday = 1
weekday := int(t.Weekday())
if weekday == 0 { // Sunday
weekday = 7
}
return time.Date(t.Year(), t.Month(), t.Day()-weekday+1, 0, 0, 0, 0, t.Location())
}
func endOfWeek(t time.Time) time.Time {
return startOfWeek(t).AddDate(0, 0, 7).Add(-time.Second)
}
func endOfMonth(year int, month time.Month, loc *time.Location) time.Time {
startNextMonth := time.Date(year, month+1, 1, 0, 0, 0, 0, loc)
return startNextMonth.Add(-time.Second)
}