Publish current app and server
This commit is contained in:
@@ -4,7 +4,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/ponzischeme89/memby/server/internal/foryou"
|
||||
"github.com/ponzischeme89/memby/server/internal/library"
|
||||
"github.com/ponzischeme89/memby/server/internal/logging"
|
||||
"github.com/ponzischeme89/memby/server/internal/radarr"
|
||||
"github.com/ponzischeme89/memby/server/internal/recommend"
|
||||
"github.com/ponzischeme89/memby/server/internal/sonarr"
|
||||
"github.com/ponzischeme89/memby/server/internal/store"
|
||||
@@ -43,7 +44,8 @@ func main() {
|
||||
}
|
||||
|
||||
logLevel := logging.ParseLevel(os.Getenv("MEMBY_LOG_LEVEL"))
|
||||
log, events := logging.NewBuffered(os.Stdout, logLevel, 20_000)
|
||||
logCapacity := logging.ParseCapacity(os.Getenv("MEMBY_LOG_BUFFER_CAPACITY"), 5_000)
|
||||
log, events := logging.NewBuffered(os.Stdout, logLevel, logCapacity)
|
||||
|
||||
if err := run(log, events); err != nil {
|
||||
log.Error("fatal", "error", err)
|
||||
@@ -88,36 +90,21 @@ func run(log *slog.Logger, events *logging.Buffer) error {
|
||||
}
|
||||
|
||||
embyClient := emby.New(cfg.EmbyURL, cfg.EmbyPublicURL, cfg.ClientName, cfg.UpstreamTimeout)
|
||||
retiredSessions, err := st.TrimSessionsToLimit(ctx, cfg.MaxClientsPerUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, sess := range retiredSessions {
|
||||
_ = ca.Delete(ctx, cache.SessionKey(hex.EncodeToString(sess.TokenHash)))
|
||||
if err := embyClient.Logout(ctx, emby.Credentials{
|
||||
UserID: sess.EmbyUserID, Token: sess.EmbyToken,
|
||||
DeviceID: sess.DeviceID, DeviceName: sess.DeviceName,
|
||||
}); err != nil {
|
||||
log.Warn("could not retire excess emby session",
|
||||
"username", sess.Username,
|
||||
"device", sess.DeviceName,
|
||||
"error", err,
|
||||
)
|
||||
}
|
||||
}
|
||||
if len(retiredSessions) > 0 {
|
||||
log.Info("enforced per-user device allowance",
|
||||
"retired_sessions", len(retiredSessions),
|
||||
"max_clients_per_user", cfg.MaxClientsPerUser,
|
||||
)
|
||||
}
|
||||
var sonarrClient *sonarr.Client
|
||||
if cfg.SonarrURL != "" {
|
||||
sonarrClient = sonarr.New(cfg.SonarrURL, cfg.SonarrAPIKey, cfg.UpstreamTimeout)
|
||||
log.Info("sonarr integration enabled", "url", cfg.SonarrURL)
|
||||
}
|
||||
var radarrClient *radarr.Client
|
||||
if cfg.RadarrURL != "" {
|
||||
radarrClient = radarr.New(cfg.RadarrURL, cfg.RadarrAPIKey, cfg.UpstreamTimeout)
|
||||
log.Info("radarr integration enabled", "url", cfg.RadarrURL)
|
||||
}
|
||||
|
||||
recommender := recommend.NewEngine(embyClient, log)
|
||||
if cfg.RecommendationWeights != "" {
|
||||
_ = json.Unmarshal([]byte(cfg.RecommendationWeights), &recommender.WeightedConfig)
|
||||
}
|
||||
// Candidates come from the imported library when one exists, which keeps the
|
||||
// recommendation rebuild off Emby entirely.
|
||||
recommender.Library = st
|
||||
@@ -145,18 +132,11 @@ func run(log *slog.Logger, events *logging.Buffer) error {
|
||||
st, tracearrClient, recommender, log,
|
||||
cfg.ForYouMinRebuildAge, cfg.ForYouRefreshInterval,
|
||||
)
|
||||
forYouService.ConfigureTimeContext(cfg.SonarrLocation)
|
||||
forYouService.ConfigureHouseholdUsers(embyClient, emby.Credentials{
|
||||
UserID: cfg.SyncUserID, Token: cfg.SyncAPIKey,
|
||||
DeviceID: "memby-for-you-builder", DeviceName: "Memby For You builder",
|
||||
})
|
||||
syncer.SetAfterSync(func() {
|
||||
go func() {
|
||||
rebuildCtx, cancel := context.WithTimeout(context.Background(), cfg.RecommendTimeout)
|
||||
defer cancel()
|
||||
forYouService.MarkAllDirty(rebuildCtx)
|
||||
_ = forYouService.RebuildAll(rebuildCtx, false)
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
server := api.New(cfg, api.Deps{
|
||||
@@ -166,15 +146,31 @@ func run(log *slog.Logger, events *logging.Buffer) error {
|
||||
Recommender: recommender,
|
||||
ForYou: forYouService,
|
||||
Sonarr: sonarrClient,
|
||||
Radarr: radarrClient,
|
||||
Syncer: syncer,
|
||||
Log: log,
|
||||
Events: events,
|
||||
})
|
||||
|
||||
// Installed after the server exists, because both halves of a finished import are
|
||||
// its business: derived data has to be invalidated, and the TVs told the catalogue
|
||||
// moved. Kept off the syncer itself so library stays ignorant of the API.
|
||||
syncer.SetAfterSync(func(result library.Result) {
|
||||
afterCtx, cancel := context.WithTimeout(context.Background(), cfg.RecommendTimeout)
|
||||
defer cancel()
|
||||
server.AnnounceLibrarySync(afterCtx, result)
|
||||
if forYouService == nil || (result.Changed == 0 && result.Removed == 0) {
|
||||
return
|
||||
}
|
||||
forYouService.MarkAllDirty(afterCtx)
|
||||
})
|
||||
|
||||
if err := server.LoadMaintenance(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
go server.WatchMaintenance(ctx, 30*time.Second)
|
||||
// One probe per gateway, not per TV: the answer is the same for the whole house.
|
||||
go server.WatchEmbyReachability(ctx, cfg.EmbyHealthInterval)
|
||||
|
||||
if err := server.LoadUpdatePolicy(ctx); err != nil {
|
||||
return err
|
||||
@@ -194,17 +190,22 @@ func run(log *slog.Logger, events *logging.Buffer) error {
|
||||
ctx,
|
||||
cfg.TracearrSyncInterval,
|
||||
cfg.TracearrFullInterval,
|
||||
cfg.ForYouRefreshInterval,
|
||||
cfg.ForYouRebuildHour,
|
||||
)
|
||||
go func() {
|
||||
importCtx, cancel := context.WithTimeout(ctx, cfg.SyncTimeout)
|
||||
defer cancel()
|
||||
if _, err := forYouService.Import(importCtx, false); err != nil {
|
||||
cancel()
|
||||
log.Warn("startup Tracearr import failed", "error", err)
|
||||
return
|
||||
}
|
||||
if err := forYouService.RebuildAll(importCtx, false); err != nil {
|
||||
log.Warn("startup For You rebuild failed", "error", err)
|
||||
cancel()
|
||||
// Only an algorithm-version change warrants startup work. Normal dirty
|
||||
// profiles wait for the daily off-peak rebuild.
|
||||
rebuildCtx, rebuildCancel := context.WithTimeout(ctx, cfg.SyncTimeout)
|
||||
defer rebuildCancel()
|
||||
if err := forYouService.RebuildOutdated(rebuildCtx); err != nil {
|
||||
log.Warn("startup outdated For You rebuild failed", "error", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user