From 2903e7b493d88ce0209e2a7541b72c22ffa09b3b Mon Sep 17 00:00:00 2001 From: Ludvig Lundgren Date: Tue, 17 May 2022 09:35:08 +0200 Subject: [PATCH] fix(indexers-irc): load new values on update (#274) * fix(indexers-irc): reload config on restart * fix(indexers-irc): reload config * fix: indexer add form --- internal/announce/announce.go | 6 +- internal/domain/release.go | 2 +- internal/http/indexer.go | 2 +- internal/indexer/service.go | 78 +++++++++++-------------- internal/irc/handler.go | 6 +- web/src/forms/settings/IndexerForms.tsx | 7 ++- 6 files changed, 46 insertions(+), 55 deletions(-) diff --git a/internal/announce/announce.go b/internal/announce/announce.go index 4f58840..daa0b14 100644 --- a/internal/announce/announce.go +++ b/internal/announce/announce.go @@ -20,14 +20,14 @@ type Processor interface { } type announceProcessor struct { - indexer domain.IndexerDefinition + indexer *domain.IndexerDefinition releaseSvc release.Service queues map[string]chan string } -func NewAnnounceProcessor(releaseSvc release.Service, indexer domain.IndexerDefinition) Processor { +func NewAnnounceProcessor(releaseSvc release.Service, indexer *domain.IndexerDefinition) Processor { ap := &announceProcessor{ releaseSvc: releaseSvc, indexer: indexer, @@ -166,7 +166,7 @@ func (a *announceProcessor) parseExtract(pattern string, vars []string, tmpVars } // onLinesMatched process vars into release -func (a *announceProcessor) onLinesMatched(def domain.IndexerDefinition, vars map[string]string, rls *domain.Release) error { +func (a *announceProcessor) onLinesMatched(def *domain.IndexerDefinition, vars map[string]string, rls *domain.Release) error { var err error err = rls.MapVars(def, vars) diff --git a/internal/domain/release.go b/internal/domain/release.go index 86f7d78..021ebd3 100644 --- a/internal/domain/release.go +++ b/internal/domain/release.go @@ -358,7 +358,7 @@ func (r *Release) RejectionsString() string { } // MapVars better name -func (r *Release) MapVars(def IndexerDefinition, varMap map[string]string) error { +func (r *Release) MapVars(def *IndexerDefinition, varMap map[string]string) error { if torrentName, err := getStringMapValue(varMap, "torrentName"); err != nil { return errors.Wrap(err, "failed parsing required field") diff --git a/internal/http/indexer.go b/internal/http/indexer.go index 7ac5be9..40e81c4 100644 --- a/internal/http/indexer.go +++ b/internal/http/indexer.go @@ -16,7 +16,7 @@ type indexerService interface { Update(ctx context.Context, indexer domain.Indexer) (*domain.Indexer, error) List(ctx context.Context) ([]domain.Indexer, error) GetAll() ([]*domain.IndexerDefinition, error) - GetTemplates() ([]domain.IndexerDefinition, error) + GetTemplates() ([]*domain.IndexerDefinition, error) Delete(ctx context.Context, id int) error } diff --git a/internal/indexer/service.go b/internal/indexer/service.go index 822ed69..4c9e2dd 100644 --- a/internal/indexer/service.go +++ b/internal/indexer/service.go @@ -24,9 +24,9 @@ type Service interface { FindByFilterID(ctx context.Context, id int) ([]domain.Indexer, error) List(ctx context.Context) ([]domain.Indexer, error) GetAll() ([]*domain.IndexerDefinition, error) - GetTemplates() ([]domain.IndexerDefinition, error) + GetTemplates() ([]*domain.IndexerDefinition, error) LoadIndexerDefinitions() error - GetIndexersByIRCNetwork(server string) []domain.IndexerDefinition + GetIndexersByIRCNetwork(server string) []*domain.IndexerDefinition GetTorznabIndexers() []domain.IndexerDefinition Start() error } @@ -38,12 +38,12 @@ type service struct { scheduler scheduler.Service // contains all raw indexer definitions - indexerDefinitions map[string]domain.IndexerDefinition + indexerDefinitions map[string]*domain.IndexerDefinition // map server:channel:announce to indexer.Identifier mapIndexerIRCToName map[string]string - lookupIRCServerDefinition map[string]map[string]domain.IndexerDefinition + lookupIRCServerDefinition map[string]map[string]*domain.IndexerDefinition torznabIndexers map[string]*domain.IndexerDefinition } @@ -54,9 +54,9 @@ func NewService(config domain.Config, repo domain.IndexerRepo, apiService APISer repo: repo, apiService: apiService, scheduler: scheduler, - indexerDefinitions: make(map[string]domain.IndexerDefinition), + indexerDefinitions: make(map[string]*domain.IndexerDefinition), mapIndexerIRCToName: make(map[string]string), - lookupIRCServerDefinition: make(map[string]map[string]domain.IndexerDefinition), + lookupIRCServerDefinition: make(map[string]map[string]*domain.IndexerDefinition), torznabIndexers: make(map[string]*domain.IndexerDefinition), } } @@ -169,49 +169,37 @@ func (s *service) mapIndexer(indexer domain.Indexer) (*domain.IndexerDefinition, } } - indexerDefinition := domain.IndexerDefinition{ - ID: int(indexer.ID), - Name: indexer.Name, - Identifier: indexer.Identifier, - Implementation: indexer.Implementation, - Enabled: indexer.Enabled, - Description: in.Description, - Language: in.Language, - Privacy: in.Privacy, - Protocol: in.Protocol, - URLS: in.URLS, - Supports: in.Supports, - Settings: nil, - SettingsMap: make(map[string]string), - IRC: in.IRC, - Torznab: in.Torznab, - Parse: in.Parse, - } + in.ID = int(indexer.ID) + in.Name = indexer.Name + in.Identifier = indexer.Identifier + in.Implementation = indexer.Implementation + in.Enabled = indexer.Enabled + in.SettingsMap = make(map[string]string) - if indexerDefinition.Implementation == "" { - indexerDefinition.Implementation = "irc" + if in.Implementation == "" { + in.Implementation = "irc" } // map settings // add value to settings objects - for _, setting := range in.Settings { + for i, setting := range in.Settings { if v, ok := indexer.Settings[setting.Name]; ok { setting.Value = v - indexerDefinition.SettingsMap[setting.Name] = v + in.SettingsMap[setting.Name] = v } - indexerDefinition.Settings = append(indexerDefinition.Settings, setting) + in.Settings[i] = setting } - return &indexerDefinition, nil + return in, nil } -func (s *service) GetTemplates() ([]domain.IndexerDefinition, error) { +func (s *service) GetTemplates() ([]*domain.IndexerDefinition, error) { definitions := s.indexerDefinitions - var ret []domain.IndexerDefinition + ret := make([]*domain.IndexerDefinition, 0) for _, definition := range definitions { ret = append(ret, definition) } @@ -242,10 +230,10 @@ func (s *service) Start() error { for _, indexer := range indexerDefinitions { if indexer.IRC != nil { - s.mapIRCIndexerLookup(indexer.Identifier, *indexer) + s.mapIRCIndexerLookup(indexer.Identifier, indexer) // add to irc server lookup table - s.mapIRCServerDefinitionLookup(indexer.IRC.Server, *indexer) + s.mapIRCServerDefinitionLookup(indexer.IRC.Server, indexer) // check if it has api and add to api service if indexer.Enabled && indexer.HasApi() { @@ -294,10 +282,10 @@ func (s *service) addIndexer(indexer domain.Indexer) error { //} if indexerDefinition.IRC != nil { - s.mapIRCIndexerLookup(indexer.Identifier, *indexerDefinition) + s.mapIRCIndexerLookup(indexer.Identifier, indexerDefinition) // add to irc server lookup table - s.mapIRCServerDefinitionLookup(indexerDefinition.IRC.Server, *indexerDefinition) + s.mapIRCServerDefinitionLookup(indexerDefinition.IRC.Server, indexerDefinition) // check if it has api and add to api service if indexerDefinition.Enabled && indexerDefinition.HasApi() { @@ -315,7 +303,7 @@ func (s *service) addIndexer(indexer domain.Indexer) error { return nil } -func (s *service) mapIRCIndexerLookup(indexerIdentifier string, indexerDefinition domain.IndexerDefinition) { +func (s *service) mapIRCIndexerLookup(indexerIdentifier string, indexerDefinition *domain.IndexerDefinition) { // map irc stuff to indexer.name // map[irc.network.test:channel:announcer1] = indexer1 // map[irc.network.test:channel:announcer2] = indexer2 @@ -339,12 +327,12 @@ func (s *service) mapIRCIndexerLookup(indexerIdentifier string, indexerDefinitio // mapIRCServerDefinitionLookup map irc stuff to indexer.name // map[irc.network.test][indexer1] = indexer1 // map[irc.network.test][indexer2] = indexer2 -func (s *service) mapIRCServerDefinitionLookup(ircServer string, indexerDefinition domain.IndexerDefinition) { +func (s *service) mapIRCServerDefinitionLookup(ircServer string, indexerDefinition *domain.IndexerDefinition) { if indexerDefinition.IRC != nil { // check if already exists, if ok add it to existing, otherwise create new _, exists := s.lookupIRCServerDefinition[ircServer] if !exists { - s.lookupIRCServerDefinition[ircServer] = map[string]domain.IndexerDefinition{} + s.lookupIRCServerDefinition[ircServer] = map[string]*domain.IndexerDefinition{} } s.lookupIRCServerDefinition[ircServer][indexerDefinition.Identifier] = indexerDefinition @@ -374,7 +362,7 @@ func (s *service) LoadIndexerDefinitions() error { log.Trace().Msgf("parsing: %v", file) - var d domain.IndexerDefinition + var d *domain.IndexerDefinition data, err := fs.ReadFile(Definitions, file) if err != nil { @@ -427,7 +415,7 @@ func (s *service) LoadCustomIndexerDefinitions() error { log.Trace().Msgf("parsing custom: %v", file) - var d domain.IndexerDefinition + var d *domain.IndexerDefinition //data, err := fs.ReadFile(Definitions, filePath) data, err := os.ReadFile(file) @@ -452,10 +440,10 @@ func (s *service) LoadCustomIndexerDefinitions() error { return nil } -func (s *service) GetIndexersByIRCNetwork(server string) []domain.IndexerDefinition { +func (s *service) GetIndexersByIRCNetwork(server string) []*domain.IndexerDefinition { server = strings.ToLower(server) - indexerDefinitions := make([]domain.IndexerDefinition, 0) + var indexerDefinitions []*domain.IndexerDefinition // get indexer definitions matching irc network from lookup table if srv, idOk := s.lookupIRCServerDefinition[server]; idOk { @@ -483,7 +471,7 @@ func (s *service) GetTorznabIndexers() []domain.IndexerDefinition { func (s *service) getDefinitionByName(name string) *domain.IndexerDefinition { if v, ok := s.indexerDefinitions[name]; ok { - return &v + return v } return nil @@ -494,7 +482,7 @@ func (s *service) getDefinitionForAnnounce(name string) *domain.IndexerDefinitio // map[network:channel:announcer] = indexer01 if v, ok := s.indexerDefinitions[name]; ok { - return &v + return v } return nil diff --git a/internal/irc/handler.go b/internal/irc/handler.go index 08c257e..8ffa598 100644 --- a/internal/irc/handler.go +++ b/internal/irc/handler.go @@ -73,7 +73,7 @@ type Handler struct { channelHealth map[string]*channelHealth } -func NewHandler(network domain.IrcNetwork, definitions []domain.IndexerDefinition, releaseSvc release.Service) *Handler { +func NewHandler(network domain.IrcNetwork, definitions []*domain.IndexerDefinition, releaseSvc release.Service) *Handler { h := &Handler{ client: nil, network: &network, @@ -91,7 +91,7 @@ func NewHandler(network domain.IrcNetwork, definitions []domain.IndexerDefinitio return h } -func (h *Handler) InitIndexers(definitions []domain.IndexerDefinition) { +func (h *Handler) InitIndexers(definitions []*domain.IndexerDefinition) { // Networks can be shared by multiple indexers but channels are unique // so let's add a new AnnounceProcessor per channel for _, definition := range definitions { @@ -99,7 +99,7 @@ func (h *Handler) InitIndexers(definitions []domain.IndexerDefinition) { continue } - h.definitions[definition.Identifier] = &definition + h.definitions[definition.Identifier] = definition // indexers can use multiple channels, but it's not common, but let's handle that anyway. for _, channel := range definition.IRC.Channels { diff --git a/web/src/forms/settings/IndexerForms.tsx b/web/src/forms/settings/IndexerForms.tsx index a1a46a0..9fe7bab 100644 --- a/web/src/forms/settings/IndexerForms.tsx +++ b/web/src/forms/settings/IndexerForms.tsx @@ -370,15 +370,18 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) { })} value={field?.value && field.value.value} onChange={(option: unknown) => { - const opt = option as SelectValue; resetForm(); + + const opt = option as SelectValue; setFieldValue("name", opt.label ?? ""); setFieldValue(field.name, opt.value ?? ""); const ind = data && data.find(i => i.identifier === opt.value); if (ind) { setIndexer(ind); - if (ind.irc.settings) { + setFieldValue("implementation", ind.implementation); + + if (ind.irc && ind.irc.settings) { ind.irc.settings.forEach((s) => { setFieldValue(`irc.${s.name}`, s.default ?? ""); });