From 3202c6043db11e76055c2ae1d8ca98d4fcebc3a7 Mon Sep 17 00:00:00 2001 From: ze0s <43699394+zze0s@users.noreply.github.com> Date: Fri, 3 May 2024 11:32:56 +0200 Subject: [PATCH] feat(indexers): update release baseurl on update (#1532) --- cmd/autobrr/main.go | 2 +- internal/database/indexer.go | 12 ++++++++- internal/database/release.go | 50 ++++++++++++++++++++++++++++++++++++ internal/domain/release.go | 1 + internal/indexer/service.go | 38 ++++++++++++++++++++++----- 5 files changed, 94 insertions(+), 9 deletions(-) diff --git a/cmd/autobrr/main.go b/cmd/autobrr/main.go index 646df81..8958f9b 100644 --- a/cmd/autobrr/main.go +++ b/cmd/autobrr/main.go @@ -113,7 +113,7 @@ func main() { authService = auth.NewService(log, userService) downloadClientService = download_client.NewService(log, downloadClientRepo) actionService = action.NewService(log, actionRepo, downloadClientService, bus) - indexerService = indexer.NewService(log, cfg.Config, indexerRepo, indexerAPIService, schedulingService) + indexerService = indexer.NewService(log, cfg.Config, indexerRepo, releaseRepo, indexerAPIService, schedulingService) filterService = filter.NewService(log, filterRepo, actionRepo, releaseRepo, indexerAPIService, indexerService) releaseService = release.NewService(log, releaseRepo, actionService, filterService, indexerService) ircService = irc.NewService(log, serverEvents, ircRepo, releaseService, indexerService, notificationService) diff --git a/internal/database/indexer.go b/internal/database/indexer.go index ff03450..c02e4bd 100644 --- a/internal/database/indexer.go +++ b/internal/database/indexer.go @@ -80,7 +80,17 @@ func (r *IndexerRepo) Update(ctx context.Context, indexer domain.Indexer) (*doma } func (r *IndexerRepo) List(ctx context.Context) ([]domain.Indexer, error) { - rows, err := r.db.handler.QueryContext(ctx, "SELECT id, enabled, name, identifier, implementation, base_url, settings FROM indexer ORDER BY name ASC") + queryBuilder := r.db.squirrel. + Select("id", "enabled", "name", "identifier", "implementation", "base_url", "settings"). + From("indexer"). + OrderBy("name ASC") + + query, _, err := queryBuilder.ToSql() + if err != nil { + return nil, errors.Wrap(err, "error building query") + } + + rows, err := r.db.handler.QueryContext(ctx, query) if err != nil { return nil, errors.Wrap(err, "error executing query") } diff --git a/internal/database/release.go b/internal/database/release.go index 8e60f8b..d007826 100644 --- a/internal/database/release.go +++ b/internal/database/release.go @@ -734,3 +734,53 @@ func (repo *ReleaseRepo) CanDownloadShow(ctx context.Context, title string, seas return true, nil } + +func (repo *ReleaseRepo) UpdateBaseURL(ctx context.Context, indexer string, oldBaseURL, newBaseURL string) error { + tx, err := repo.db.BeginTx(ctx, &sql.TxOptions{}) + if err != nil { + return err + } + + defer func() { + var txErr error + if p := recover(); p != nil { + txErr = tx.Rollback() + if txErr != nil { + repo.log.Error().Err(txErr).Msg("error rolling back transaction") + } + repo.log.Error().Msgf("something went terribly wrong panic: %v", p) + } else if err != nil { + txErr = tx.Rollback() + if txErr != nil { + repo.log.Error().Err(txErr).Msg("error rolling back transaction") + } + } else { + // All good, commit + txErr = tx.Commit() + if txErr != nil { + repo.log.Error().Err(txErr).Msg("error committing transaction") + } + } + }() + + queryBuilder := repo.db.squirrel. + RunWith(tx). + Update("release"). + Set("download_url", sq.Expr("REPLACE(download_url, ?, ?)", oldBaseURL, newBaseURL)). + Set("info_url", sq.Expr("REPLACE(info_url, ?, ?)", oldBaseURL, newBaseURL)). + Where(sq.Eq{"indexer": indexer}) + + result, err := queryBuilder.ExecContext(ctx) + if err != nil { + return errors.Wrap(err, "error executing query") + } + + rowsAffected, err := result.RowsAffected() + if err != nil { + return errors.Wrap(err, "error getting rows affected") + } + + repo.log.Trace().Msgf("release updated (%d) base urls from %q to %q", rowsAffected, oldBaseURL, newBaseURL) + + return nil +} diff --git a/internal/domain/release.go b/internal/domain/release.go index 39fb0c0..489299f 100644 --- a/internal/domain/release.go +++ b/internal/domain/release.go @@ -36,6 +36,7 @@ type ReleaseRepo interface { Stats(ctx context.Context) (*ReleaseStats, error) Delete(ctx context.Context, req *DeleteReleaseRequest) error CanDownloadShow(ctx context.Context, title string, season int, episode int) (bool, error) + UpdateBaseURL(ctx context.Context, indexer string, oldBaseURL, newBaseURL string) error GetActionStatus(ctx context.Context, req *GetReleaseActionStatusRequest) (*ReleaseActionStatus, error) StoreReleaseActionStatus(ctx context.Context, status *ReleaseActionStatus) error diff --git a/internal/indexer/service.go b/internal/indexer/service.go index cb4b1fa..4c72dd0 100644 --- a/internal/indexer/service.go +++ b/internal/indexer/service.go @@ -43,11 +43,12 @@ type Service interface { } type service struct { - log zerolog.Logger - config *domain.Config - repo domain.IndexerRepo - ApiService APIService - scheduler scheduler.Service + log zerolog.Logger + config *domain.Config + repo domain.IndexerRepo + releaseRepo domain.ReleaseRepo + ApiService APIService + scheduler scheduler.Service // contains all raw indexer definitions definitions map[string]domain.IndexerDefinition @@ -63,11 +64,12 @@ type service struct { rssIndexers map[string]*domain.IndexerDefinition } -func NewService(log logger.Logger, config *domain.Config, repo domain.IndexerRepo, apiService APIService, scheduler scheduler.Service) Service { +func NewService(log logger.Logger, config *domain.Config, repo domain.IndexerRepo, releaseRepo domain.ReleaseRepo, apiService APIService, scheduler scheduler.Service) Service { return &service{ log: log.With().Str("module", "indexer").Logger(), config: config, repo: repo, + releaseRepo: releaseRepo, ApiService: apiService, scheduler: scheduler, lookupIRCServerDefinition: make(map[string]map[string]*domain.IndexerDefinition), @@ -119,6 +121,28 @@ func (s *service) Update(ctx context.Context, indexer domain.Indexer) (*domain.I indexer.Settings[key] = sanitize.String(val) } + currentIndexer, err := s.repo.FindByID(ctx, int(indexer.ID)) + if err != nil { + return nil, errors.Wrap(err, "could not find indexer by id: %v", indexer.ID) + } + + // only IRC indexers have baseURL set + if indexer.Implementation == string(domain.IndexerImplementationIRC) { + if indexer.BaseURL == "" { + return nil, errors.New("indexer baseURL must not be empty") + } + + // check if baseURL has been updated and update releases if it was + if currentIndexer.BaseURL != indexer.BaseURL { + + // update urls of releases + err = s.releaseRepo.UpdateBaseURL(ctx, indexer.Identifier, currentIndexer.BaseURL, indexer.BaseURL) + if err != nil { + return nil, errors.Wrap(err, "could not update release urls with new baseURL: %s", indexer.BaseURL) + } + } + } + i, err := s.repo.Update(ctx, indexer) if err != nil { s.log.Error().Err(err).Msgf("could not update indexer: %+v", indexer) @@ -132,7 +156,7 @@ func (s *service) Update(ctx context.Context, indexer domain.Indexer) (*domain.I } if isImplFeed(indexer.Implementation) { - if !indexer.Enabled { + if currentIndexer.Enabled && !indexer.Enabled { s.stopFeed(indexer.Identifier) } }