feat: time-gated imports via cfg

pull/20/head
Gabe Farrell 6 months ago
parent 6d000d87e4
commit c14df8c2fb

@ -6,6 +6,7 @@ import (
"strconv"
"strings"
"sync"
"time"
)
const (
@ -37,6 +38,8 @@ const (
ALLOWED_HOSTS_ENV = "KOITO_ALLOWED_HOSTS"
DISABLE_RATE_LIMIT_ENV = "KOITO_DISABLE_RATE_LIMIT"
THROTTLE_IMPORTS_MS = "KOITO_THROTTLE_IMPORTS_MS"
IMPORT_BEFORE_UNIX_ENV = "KOITO_IMPORT_BEFORE_UNIX"
IMPORT_AFTER_UNIX_ENV = "KOITO_IMPORT_AFTER_UNIX"
)
type config struct {
@ -64,6 +67,8 @@ type config struct {
disableRateLimit bool
importThrottleMs int
userAgent string
importBefore time.Time
importAfter time.Time
}
var (
@ -112,6 +117,16 @@ func loadConfig(getenv func(string) string) (*config, error) {
cfg.lbzRelayUrl = getenv(LBZ_RELAY_URL_ENV)
}
beforeutx, _ := strconv.ParseInt(getenv(IMPORT_BEFORE_UNIX_ENV), 10, 64)
afterutx, _ := strconv.ParseInt(getenv(IMPORT_AFTER_UNIX_ENV), 10, 64)
if beforeutx > 0 {
cfg.importBefore = time.Unix(beforeutx, 0)
}
if afterutx > 0 {
cfg.importAfter = time.Unix(afterutx, 0)
}
cfg.importThrottleMs, _ = strconv.Atoi(getenv(THROTTLE_IMPORTS_MS))
cfg.disableRateLimit = parseBool(getenv(DISABLE_RATE_LIMIT_ENV))
@ -308,3 +323,8 @@ func ThrottleImportMs() int {
defer lock.RUnlock()
return globalConfig.importThrottleMs
}
// returns the before, after times, in that order
func ImportWindow() (time.Time, time.Time) {
return globalConfig.importBefore, globalConfig.importAfter
}

@ -4,11 +4,13 @@ import (
"context"
"os"
"path"
"time"
"github.com/gabehf/koito/internal/cfg"
"github.com/gabehf/koito/internal/logger"
)
// runs after every importer
func finishImport(ctx context.Context, filename string, numImported int) error {
l := logger.FromContext(ctx)
_, err := os.Stat(path.Join(cfg.ConfigDir(), "import_complete"))
@ -27,3 +29,18 @@ func finishImport(ctx context.Context, filename string, numImported int) error {
}
return nil
}
// from https://stackoverflow.com/a/55093788 with modification to use cfg and check for zero values
func inImportTimeWindow(check time.Time) bool {
end, start := cfg.ImportWindow()
if start.IsZero() && end.IsZero() {
return true
}
if !start.IsZero() && end.IsZero() {
return !check.Before(start)
}
if start.IsZero() && !end.IsZero() {
return !check.After(end)
}
return !check.Before(start) && !check.After(end)
}

@ -93,6 +93,10 @@ func ImportLastFMFile(ctx context.Context, store db.DB, mbzc mbz.MusicBrainzCall
} else {
ts = time.Unix(unix, 0).UTC()
}
if !inImportTimeWindow(ts) {
l.Debug().Msgf("Skipping import due to import time rules")
continue
}
opts := catalog.SubmitListenOpts{
MbzCaller: mbzc,
Artist: track.Artist.Text,

@ -78,6 +78,11 @@ func ImportListenBrainzFile(ctx context.Context, store db.DB, mbzc mbz.MusicBrai
fmt.Println("Error unmarshaling JSON:", err)
continue
}
ts := time.Unix(payload.ListenedAt, 0)
if !inImportTimeWindow(ts) {
l.Debug().Msgf("Skipping import due to import time rules")
continue
}
artistMbzIDs, err := utils.ParseUUIDSlice(payload.TrackMeta.AdditionalInfo.ArtistMBIDs)
if err != nil {
l.Debug().Err(err).Msg("Failed to parse one or more uuids")
@ -119,7 +124,7 @@ func ImportListenBrainzFile(ctx context.Context, store db.DB, mbzc mbz.MusicBrai
ReleaseMbzID: releaseMbzID,
ReleaseGroupMbzID: rgMbzID,
Duration: duration,
Time: time.Unix(payload.ListenedAt, 0),
Time: ts,
UserID: 1,
Client: client,
}

@ -65,14 +65,18 @@ func ImportMalojaFile(ctx context.Context, store db.DB, filename string) error {
l.Debug().Msg("Skipping invalid maloja import item")
continue
}
ts := time.Unix(item.Time, 0).UTC()
ts := time.Unix(item.Time, 0)
if !inImportTimeWindow(ts) {
l.Debug().Msgf("Skipping import due to import time rules")
continue
}
opts := catalog.SubmitListenOpts{
MbzCaller: &mbz.MusicBrainzClient{},
Artist: item.Track.Artists[0],
ArtistNames: artists,
TrackTitle: item.Track.Title,
ReleaseTitle: item.Track.Album.Title,
Time: ts,
Time: ts.Local(),
UserID: 1,
}
err = catalog.SubmitListen(ctx, store, opts)

@ -43,10 +43,15 @@ func ImportSpotifyFile(ctx context.Context, store db.DB, filename string) error
if err != nil {
return err
}
for _, item := range export {
if item.ReasonEnd != "trackdone" {
continue
}
if !inImportTimeWindow(item.Timestamp) {
l.Debug().Msgf("Skipping import due to import time rules")
continue
}
dur := item.MsPlayed
if item.TrackName == "" || item.ArtistName == "" {
l.Debug().Msg("Skipping non-track item")
@ -58,7 +63,7 @@ func ImportSpotifyFile(ctx context.Context, store db.DB, filename string) error
TrackTitle: item.TrackName,
ReleaseTitle: item.AlbumName,
Duration: dur / 1000,
Time: item.Timestamp.UTC(),
Time: item.Timestamp,
UserID: 1,
}
err = catalog.SubmitListen(ctx, store, opts)

Loading…
Cancel
Save