diff --git a/internal/torznab/config.go b/internal/torznab/config.go index 1ffaebb5..f8539cf2 100644 --- a/internal/torznab/config.go +++ b/internal/torznab/config.go @@ -1,10 +1,87 @@ package torznab +import ( + "encoding/json" + "strings" + + "github.com/bitmagnet-io/bitmagnet/internal/boilerplate/lazy" + "github.com/bitmagnet-io/bitmagnet/internal/database/search" + "go.uber.org/fx" + "go.uber.org/zap" +) + +type Profile struct { + OrderBy search.TorrentContentOrderBy + OrderDirection search.OrderDirection + Tags []string +} + type Config struct { + Hostname *string + Profiles map[string]Profile +} + +type UntypedConfig struct { Hostname *string Profiles map[string]map[string]string } -func NewDefaultConfig() Config { - return Config{} +func NewDefaultUntypedConfig() UntypedConfig { + return UntypedConfig{} +} + +type Params struct { + fx.In + UntypedConfig UntypedConfig + Log *zap.SugaredLogger +} + +type Result struct { + fx.Out + Profiles lazy.Lazy[*Config] +} + +// lazy validation of strongly typed config +func New(p Params) Result { + return Result{ + Profiles: lazy.New[*Config](func() (*Config, error) { + // make sure default profile has been defined. + _, ok := p.UntypedConfig.Profiles[ProfileDefault] + if !ok { + p.UntypedConfig.Profiles[ProfileDefault] = make(map[string]string, 0) + } + config := Config{ + Hostname: p.UntypedConfig.Hostname, + Profiles: make(map[string]Profile, len(p.UntypedConfig.Profiles)), + } + for name, profile := range p.UntypedConfig.Profiles { + orderbyRaw, ok := profile[ProfileItemOrderBy] + if !ok { + orderbyRaw = string(search.TorrentContentOrderByRelevance) + } + orderby, err := search.ParseTorrentContentOrderBy(orderbyRaw) + if err != nil { + return nil, err + } + dirRaw, ok := profile[ProfileItemOrderDirection] + if !ok { + dirRaw = string(search.OrderDirectionDescending) + } + dir, err := search.ParseOrderDirection(dirRaw) + if err != nil { + return nil, err + } + tags := make([]string, 0) + csvTags, ok := profile[ProfileItemTags] + if ok && len(csvTags) > 0 { + tags = strings.Split(csvTags, ",") + } + config.Profiles[name] = Profile{OrderBy: orderby, OrderDirection: dir, Tags: tags} + + } + log, _ := json.MarshalIndent(config, "", " ") + p.Log.Infof("torznab profiles:\n%s\n", log) + return &config, nil + }), + } } diff --git a/internal/torznab/httpserver/httpserver.go b/internal/torznab/httpserver/httpserver.go index 3af1f89f..3285d215 100644 --- a/internal/torznab/httpserver/httpserver.go +++ b/internal/torznab/httpserver/httpserver.go @@ -10,15 +10,14 @@ import ( "github.com/bitmagnet-io/bitmagnet/internal/boilerplate/lazy" "github.com/bitmagnet-io/bitmagnet/internal/model" "github.com/bitmagnet-io/bitmagnet/internal/torznab" - "github.com/bitmagnet-io/bitmagnet/internal/torznab/settings" "github.com/gin-gonic/gin" "go.uber.org/fx" ) type Params struct { fx.In - Client lazy.Lazy[torznab.Client] - Settings lazy.Lazy[*settings.Settings] + Client lazy.Lazy[torznab.Client] + Config lazy.Lazy[*torznab.Config] } type Result struct { @@ -29,15 +28,15 @@ type Result struct { func New(p Params) Result { return Result{ Option: builder{ - client: p.Client, - settings: p.Settings, + client: p.Client, + config: p.Config, }, } } type builder struct { - client lazy.Lazy[torznab.Client] - settings lazy.Lazy[*settings.Settings] + client lazy.Lazy[torznab.Client] + config lazy.Lazy[*torznab.Config] } func (builder) Key() string { @@ -45,9 +44,8 @@ func (builder) Key() string { } type torznabworker struct { - client torznab.Client - // settings *settings.Settings - profile settings.Profile + client torznab.Client + profile torznab.Profile hostname *string } @@ -170,12 +168,12 @@ func (w torznabworker) get(c *gin.Context) { } -func (w torznabworker) getDefault(profile settings.Profile) gin.HandlerFunc { +func (w torznabworker) getDefault(profile torznab.Profile) gin.HandlerFunc { w.profile = profile return gin.HandlerFunc(w.get) } -func (w torznabworker) getWithProfile(profiles map[string]settings.Profile) gin.HandlerFunc { +func (w torznabworker) getWithProfile(profiles map[string]torznab.Profile) gin.HandlerFunc { handler := func(c *gin.Context) { profileName := c.Param("profile") profile, ok := profiles[profileName] @@ -198,16 +196,16 @@ func (b builder) Apply(e *gin.Engine) error { if err != nil { return err } - settings, err := b.settings.Get() + config, err := b.config.Get() if err != nil { return err } worker := torznabworker{ client: client, - hostname: settings.Hostname, + hostname: config.Hostname, } - e.GET("/torznab/api/*any", worker.getDefault(settings.Profiles[torznab.ProfileDefault])) - e.GET("/torznab/:profile/*any", worker.getWithProfile(settings.Profiles)) + e.GET("/torznab/api/*any", worker.getDefault(config.Profiles[torznab.ProfileDefault])) + e.GET("/torznab/:profile/*any", worker.getWithProfile(config.Profiles)) return nil } diff --git a/internal/torznab/settings/settings.go b/internal/torznab/settings/settings.go deleted file mode 100644 index 47398566..00000000 --- a/internal/torznab/settings/settings.go +++ /dev/null @@ -1,79 +0,0 @@ -package settings - -import ( - "encoding/json" - "strings" - - "github.com/bitmagnet-io/bitmagnet/internal/boilerplate/lazy" - "github.com/bitmagnet-io/bitmagnet/internal/database/search" - "github.com/bitmagnet-io/bitmagnet/internal/torznab" - "go.uber.org/fx" - "go.uber.org/zap" -) - -type Profile struct { - OrderBy search.TorrentContentOrderBy - OrderDirection search.OrderDirection - Tags []string -} - -type Settings struct { - Hostname *string - Profiles map[string]Profile -} - -type Params struct { - fx.In - Config torznab.Config - Log *zap.SugaredLogger -} - -type Result struct { - fx.Out - Profiles lazy.Lazy[*Settings] -} - -// lazy validation of settings -func New(p Params) Result { - return Result{ - Profiles: lazy.New[*Settings](func() (*Settings, error) { - // make sure default profile has been defined. - _, ok := p.Config.Profiles[torznab.ProfileDefault] - if !ok { - p.Config.Profiles[torznab.ProfileDefault] = make(map[string]string, 0) - } - settings := Settings{ - Hostname: p.Config.Hostname, - Profiles: make(map[string]Profile, len(p.Config.Profiles)), - } - for name, profile := range p.Config.Profiles { - orderbyRaw, ok := profile[torznab.ProfileItemOrderBy] - if !ok { - orderbyRaw = string(search.TorrentContentOrderByRelevance) - } - orderby, err := search.ParseTorrentContentOrderBy(orderbyRaw) - if err != nil { - return nil, err - } - dirRaw, ok := profile[torznab.ProfileItemOrderDirection] - if !ok { - dirRaw = string(search.OrderDirectionDescending) - } - dir, err := search.ParseOrderDirection(dirRaw) - if err != nil { - return nil, err - } - tags := make([]string, 0) - csvTags, ok := profile[torznab.ProfileItemTags] - if ok && len(csvTags) > 0 { - tags = strings.Split(csvTags, ",") - } - settings.Profiles[name] = Profile{OrderBy: orderby, OrderDirection: dir, Tags: tags} - - } - log, _ := json.MarshalIndent(settings, "", " ") - p.Log.Infof("torznab profiles:\n%s\n", log) - return &settings, nil - }), - } -} diff --git a/internal/torznab/torznabfx/module.go b/internal/torznab/torznabfx/module.go index 402d3408..47bf39fb 100644 --- a/internal/torznab/torznabfx/module.go +++ b/internal/torznab/torznabfx/module.go @@ -5,17 +5,16 @@ import ( "github.com/bitmagnet-io/bitmagnet/internal/torznab" "github.com/bitmagnet-io/bitmagnet/internal/torznab/adapter" "github.com/bitmagnet-io/bitmagnet/internal/torznab/httpserver" - "github.com/bitmagnet-io/bitmagnet/internal/torznab/settings" "go.uber.org/fx" ) func New() fx.Option { return fx.Module( "torznab", - configfx.NewConfigModule[torznab.Config]("torznab", torznab.NewDefaultConfig()), + configfx.NewConfigModule[torznab.UntypedConfig]("torznab", torznab.NewDefaultUntypedConfig()), fx.Provide( adapter.New, - settings.New, + torznab.New, httpserver.New, ), )