mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00
fix: store filter actions (#54)
This commit is contained in:
parent
e496027798
commit
e1ef47e09a
10 changed files with 213 additions and 73 deletions
|
@ -1,15 +1,19 @@
|
||||||
package action
|
package action
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/asaskevich/EventBus"
|
"github.com/asaskevich/EventBus"
|
||||||
|
|
||||||
"github.com/autobrr/autobrr/internal/domain"
|
"github.com/autobrr/autobrr/internal/domain"
|
||||||
"github.com/autobrr/autobrr/internal/download_client"
|
"github.com/autobrr/autobrr/internal/download_client"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
Store(action domain.Action) (*domain.Action, error)
|
Store(ctx context.Context, action domain.Action) (*domain.Action, error)
|
||||||
Fetch() ([]domain.Action, error)
|
Fetch() ([]domain.Action, error)
|
||||||
Delete(actionID int) error
|
Delete(actionID int) error
|
||||||
|
DeleteByFilterID(ctx context.Context, filterID int) error
|
||||||
ToggleEnabled(actionID int) error
|
ToggleEnabled(actionID int) error
|
||||||
|
|
||||||
RunActions(actions []domain.Action, release domain.Release) error
|
RunActions(actions []domain.Action, release domain.Release) error
|
||||||
|
@ -25,10 +29,10 @@ func NewService(repo domain.ActionRepo, clientSvc download_client.Service, bus E
|
||||||
return &service{repo: repo, clientSvc: clientSvc, bus: bus}
|
return &service{repo: repo, clientSvc: clientSvc, bus: bus}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) Store(action domain.Action) (*domain.Action, error) {
|
func (s *service) Store(ctx context.Context, action domain.Action) (*domain.Action, error) {
|
||||||
// validate data
|
// validate data
|
||||||
|
|
||||||
a, err := s.repo.Store(action)
|
a, err := s.repo.Store(ctx, action)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -44,6 +48,14 @@ func (s *service) Delete(actionID int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *service) DeleteByFilterID(ctx context.Context, filterID int) error {
|
||||||
|
if err := s.repo.DeleteByFilterID(ctx, filterID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *service) Fetch() ([]domain.Action, error) {
|
func (s *service) Fetch() ([]domain.Action, error) {
|
||||||
actions, err := s.repo.List()
|
actions, err := s.repo.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"github.com/autobrr/autobrr/internal/domain"
|
"github.com/autobrr/autobrr/internal/domain"
|
||||||
|
@ -121,7 +122,19 @@ func (r *ActionRepo) Delete(actionID int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ActionRepo) Store(action domain.Action) (*domain.Action, error) {
|
func (r *ActionRepo) DeleteByFilterID(ctx context.Context, filterID int) error {
|
||||||
|
_, err := r.db.ExecContext(ctx, `DELETE FROM action WHERE filter_id = ?`, filterID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msg("actions: error deleting by filterid")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Msgf("actions: delete by filterid %v", filterID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.Action, error) {
|
||||||
|
|
||||||
execCmd := toNullString(action.ExecCmd)
|
execCmd := toNullString(action.ExecCmd)
|
||||||
execArgs := toNullString(action.ExecArgs)
|
execArgs := toNullString(action.ExecArgs)
|
||||||
|
@ -138,13 +151,13 @@ func (r *ActionRepo) Store(action domain.Action) (*domain.Action, error) {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if action.ID != 0 {
|
if action.ID != 0 {
|
||||||
log.Info().Msg("UPDATE existing record")
|
log.Debug().Msg("actions: update existing record")
|
||||||
_, err = r.db.Exec(`UPDATE action SET name = ?, type = ?, enabled = ?, exec_cmd = ?, exec_args = ?, watch_folder = ? , category =? , tags = ?, label = ?, save_path = ?, paused = ?, ignore_rules = ?, limit_upload_speed = ?, limit_download_speed = ?, client_id = ?
|
_, err = r.db.ExecContext(ctx, `UPDATE action SET name = ?, type = ?, enabled = ?, exec_cmd = ?, exec_args = ?, watch_folder = ? , category =? , tags = ?, label = ?, save_path = ?, paused = ?, ignore_rules = ?, limit_upload_speed = ?, limit_download_speed = ?, client_id = ?
|
||||||
WHERE id = ?`, action.Name, action.Type, action.Enabled, execCmd, execArgs, watchFolder, category, tags, label, savePath, action.Paused, action.IgnoreRules, limitUL, limitDL, clientID, action.ID)
|
WHERE id = ?`, action.Name, action.Type, action.Enabled, execCmd, execArgs, watchFolder, category, tags, label, savePath, action.Paused, action.IgnoreRules, limitUL, limitDL, clientID, action.ID)
|
||||||
} else {
|
} else {
|
||||||
var res sql.Result
|
var res sql.Result
|
||||||
|
|
||||||
res, err = r.db.Exec(`INSERT INTO action(name, type, enabled, exec_cmd, exec_args, watch_folder, category, tags, label, save_path, paused, ignore_rules, limit_upload_speed, limit_download_speed, client_id, filter_id)
|
res, err = r.db.ExecContext(ctx, `INSERT INTO action(name, type, enabled, exec_cmd, exec_args, watch_folder, category, tags, label, save_path, paused, ignore_rules, limit_upload_speed, limit_download_speed, client_id, filter_id)
|
||||||
VALUES (?, ?, ?, ?, ?,? ,?, ?,?,?,?,?,?,?,?,?) ON CONFLICT DO NOTHING`, action.Name, action.Type, action.Enabled, execCmd, execArgs, watchFolder, category, tags, label, savePath, action.Paused, action.IgnoreRules, limitUL, limitDL, clientID, filterID)
|
VALUES (?, ?, ?, ?, ?,? ,?, ?,?,?,?,?,?,?,?,?) ON CONFLICT DO NOTHING`, action.Name, action.Type, action.Enabled, execCmd, execArgs, watchFolder, category, tags, label, savePath, action.Paused, action.IgnoreRules, limitUL, limitDL, clientID, filterID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
|
@ -152,13 +165,67 @@ func (r *ActionRepo) Store(action domain.Action) (*domain.Action, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resId, _ := res.LastInsertId()
|
resId, _ := res.LastInsertId()
|
||||||
log.Info().Msgf("LAST INSERT ID %v", resId)
|
log.Debug().Msgf("actions: added new %v", resId)
|
||||||
action.ID = int(resId)
|
action.ID = int(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &action, nil
|
return &action, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []domain.Action, filterID int64) ([]domain.Action, error) {
|
||||||
|
|
||||||
|
tx, err := r.db.BeginTx(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
_, err = tx.ExecContext(ctx, `DELETE FROM action WHERE filter_id = ?`, filterID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msgf("error deleting actions for filter: %v", filterID)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, action := range actions {
|
||||||
|
execCmd := toNullString(action.ExecCmd)
|
||||||
|
execArgs := toNullString(action.ExecArgs)
|
||||||
|
watchFolder := toNullString(action.WatchFolder)
|
||||||
|
category := toNullString(action.Category)
|
||||||
|
tags := toNullString(action.Tags)
|
||||||
|
label := toNullString(action.Label)
|
||||||
|
savePath := toNullString(action.SavePath)
|
||||||
|
|
||||||
|
limitDL := toNullInt64(action.LimitDownloadSpeed)
|
||||||
|
limitUL := toNullInt64(action.LimitUploadSpeed)
|
||||||
|
clientID := toNullInt32(action.ClientID)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var res sql.Result
|
||||||
|
|
||||||
|
res, err = tx.ExecContext(ctx, `INSERT INTO action(name, type, enabled, exec_cmd, exec_args, watch_folder, category, tags, label, save_path, paused, ignore_rules, limit_upload_speed, limit_download_speed, client_id, filter_id)
|
||||||
|
VALUES (?, ?, ?, ?, ?,? ,?, ?,?,?,?,?,?,?,?,?) ON CONFLICT DO NOTHING`, action.Name, action.Type, action.Enabled, execCmd, execArgs, watchFolder, category, tags, label, savePath, action.Paused, action.IgnoreRules, limitUL, limitDL, clientID, filterID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msg("actions: error executing query")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resId, _ := res.LastInsertId()
|
||||||
|
action.ID = int(resId)
|
||||||
|
|
||||||
|
log.Debug().Msgf("actions: store '%v' type: '%v' on filter: %v", action.Name, action.Type, filterID)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msg("error updating actions")
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ActionRepo) ToggleEnabled(actionID int) error {
|
func (r *ActionRepo) ToggleEnabled(actionID int) error {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -316,12 +317,12 @@ func (r *FilterRepo) Store(filter domain.Filter) (*domain.Filter, error) {
|
||||||
return &filter, nil
|
return &filter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FilterRepo) Update(filter domain.Filter) (*domain.Filter, error) {
|
func (r *FilterRepo) Update(ctx context.Context, filter domain.Filter) (*domain.Filter, error) {
|
||||||
|
|
||||||
//var res sql.Result
|
//var res sql.Result
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
_, err = r.db.Exec(`
|
_, err = r.db.ExecContext(ctx, `
|
||||||
UPDATE filter SET
|
UPDATE filter SET
|
||||||
name = ?,
|
name = ?,
|
||||||
enabled = ?,
|
enabled = ?,
|
||||||
|
@ -389,9 +390,45 @@ func (r *FilterRepo) Update(filter domain.Filter) (*domain.Filter, error) {
|
||||||
return &filter, nil
|
return &filter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FilterRepo) StoreIndexerConnection(filterID int, indexerID int) error {
|
func (r *FilterRepo) StoreIndexerConnections(ctx context.Context, filterID int, indexers []domain.Indexer) error {
|
||||||
|
|
||||||
|
tx, err := r.db.BeginTx(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
deleteQuery := `DELETE FROM filter_indexer WHERE filter_id = ?`
|
||||||
|
_, err = tx.ExecContext(ctx, deleteQuery, filterID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msgf("error deleting indexers for filter: %v", filterID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, indexer := range indexers {
|
||||||
|
query := `INSERT INTO filter_indexer (filter_id, indexer_id) VALUES ($1, $2)`
|
||||||
|
_, err := tx.ExecContext(ctx, query, filterID, indexer.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msg("error executing query")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Msgf("filter.indexers: store '%v' on filter: %v", indexer.Name, filterID)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Stack().Err(err).Msgf("error deleting indexers for filter: %v", filterID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FilterRepo) StoreIndexerConnection(ctx context.Context, filterID int, indexerID int) error {
|
||||||
query := `INSERT INTO filter_indexer (filter_id, indexer_id) VALUES ($1, $2)`
|
query := `INSERT INTO filter_indexer (filter_id, indexer_id) VALUES ($1, $2)`
|
||||||
_, err := r.db.Exec(query, filterID, indexerID)
|
_, err := r.db.ExecContext(ctx, query, filterID, indexerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msg("error executing query")
|
log.Error().Stack().Err(err).Msg("error executing query")
|
||||||
return err
|
return err
|
||||||
|
@ -400,10 +437,10 @@ func (r *FilterRepo) StoreIndexerConnection(filterID int, indexerID int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FilterRepo) DeleteIndexerConnections(filterID int) error {
|
func (r *FilterRepo) DeleteIndexerConnections(ctx context.Context, filterID int) error {
|
||||||
|
|
||||||
query := `DELETE FROM filter_indexer WHERE filter_id = ?`
|
query := `DELETE FROM filter_indexer WHERE filter_id = ?`
|
||||||
_, err := r.db.Exec(query, filterID)
|
_, err := r.db.ExecContext(ctx, query, filterID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msg("error executing query")
|
log.Error().Stack().Err(err).Msg("error executing query")
|
||||||
return err
|
return err
|
||||||
|
@ -412,17 +449,15 @@ func (r *FilterRepo) DeleteIndexerConnections(filterID int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FilterRepo) Delete(filterID int) error {
|
func (r *FilterRepo) Delete(ctx context.Context, filterID int) error {
|
||||||
|
|
||||||
res, err := r.db.Exec(`DELETE FROM filter WHERE id = ?`, filterID)
|
_, err := r.db.ExecContext(ctx, `DELETE FROM filter WHERE id = ?`, filterID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msg("error executing query")
|
log.Error().Stack().Err(err).Msg("error executing query")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, _ := res.RowsAffected()
|
log.Info().Msgf("filter.delete: successfully deleted: %v", filterID)
|
||||||
|
|
||||||
log.Info().Msgf("rows affected %v", rows)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,7 +368,6 @@ func (ir *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, ch
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Stack().Err(err).Msgf("error deleting network: %v", networkID)
|
log.Error().Stack().Err(err).Msgf("error deleting network: %v", networkID)
|
||||||
return err
|
return err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
type ActionRepo interface {
|
type ActionRepo interface {
|
||||||
Store(action Action) (*Action, error)
|
Store(ctx context.Context, action Action) (*Action, error)
|
||||||
|
StoreFilterActions(ctx context.Context, actions []Action, filterID int64) ([]Action, error)
|
||||||
|
DeleteByFilterID(ctx context.Context, filterID int) error
|
||||||
FindByFilterID(filterID int) ([]Action, error)
|
FindByFilterID(filterID int) ([]Action, error)
|
||||||
List() ([]Action, error)
|
List() ([]Action, error)
|
||||||
Delete(actionID int) error
|
Delete(actionID int) error
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Works the same way as for autodl-irssi
|
Works the same way as for autodl-irssi
|
||||||
|
@ -13,10 +16,11 @@ type FilterRepo interface {
|
||||||
FindByIndexerIdentifier(indexer string) ([]Filter, error)
|
FindByIndexerIdentifier(indexer string) ([]Filter, error)
|
||||||
ListFilters() ([]Filter, error)
|
ListFilters() ([]Filter, error)
|
||||||
Store(filter Filter) (*Filter, error)
|
Store(filter Filter) (*Filter, error)
|
||||||
Update(filter Filter) (*Filter, error)
|
Update(ctx context.Context, filter Filter) (*Filter, error)
|
||||||
Delete(filterID int) error
|
Delete(ctx context.Context, filterID int) error
|
||||||
StoreIndexerConnection(filterID int, indexerID int) error
|
StoreIndexerConnection(ctx context.Context, filterID int, indexerID int) error
|
||||||
DeleteIndexerConnections(filterID int) error
|
StoreIndexerConnections(ctx context.Context, filterID int, indexers []Indexer) error
|
||||||
|
DeleteIndexerConnections(ctx context.Context, filterID int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package filter
|
package filter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"github.com/autobrr/autobrr/internal/domain"
|
"github.com/autobrr/autobrr/internal/domain"
|
||||||
|
@ -13,8 +16,8 @@ type Service interface {
|
||||||
FindAndCheckFilters(release *domain.Release) (bool, *domain.Filter, error)
|
FindAndCheckFilters(release *domain.Release) (bool, *domain.Filter, error)
|
||||||
ListFilters() ([]domain.Filter, error)
|
ListFilters() ([]domain.Filter, error)
|
||||||
Store(filter domain.Filter) (*domain.Filter, error)
|
Store(filter domain.Filter) (*domain.Filter, error)
|
||||||
Update(filter domain.Filter) (*domain.Filter, error)
|
Update(ctx context.Context, filter domain.Filter) (*domain.Filter, error)
|
||||||
Delete(filterID int) error
|
Delete(ctx context.Context, filterID int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type service struct {
|
type service struct {
|
||||||
|
@ -102,49 +105,56 @@ func (s *service) Store(filter domain.Filter) (*domain.Filter, error) {
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) Update(filter domain.Filter) (*domain.Filter, error) {
|
func (s *service) Update(ctx context.Context, filter domain.Filter) (*domain.Filter, error) {
|
||||||
// validate data
|
// validate data
|
||||||
|
if filter.Name == "" {
|
||||||
|
return nil, errors.New("validation: name can't be empty")
|
||||||
|
}
|
||||||
|
|
||||||
// store
|
// update
|
||||||
f, err := s.repo.Update(filter)
|
f, err := s.repo.Update(ctx, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msgf("could not update filter: %v", filter.Name)
|
log.Error().Err(err).Msgf("could not update filter: %v", filter.Name)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// take care of connected indexers
|
// take care of connected indexers
|
||||||
if err = s.repo.DeleteIndexerConnections(f.ID); err != nil {
|
if err = s.repo.StoreIndexerConnections(ctx, f.ID, filter.Indexers); err != nil {
|
||||||
log.Error().Err(err).Msgf("could not delete filter indexer connections: %v", filter.Name)
|
log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range filter.Indexers {
|
// take care of filter actions
|
||||||
if err = s.repo.StoreIndexerConnection(f.ID, int(i.ID)); err != nil {
|
actions, err := s.actionRepo.StoreFilterActions(ctx, filter.Actions, int64(filter.ID))
|
||||||
log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name)
|
if err != nil {
|
||||||
return nil, err
|
log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name)
|
||||||
}
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// store actions
|
f.Actions = actions
|
||||||
if filter.Actions != nil {
|
|
||||||
for _, action := range filter.Actions {
|
|
||||||
if _, err := s.actionRepo.Store(action); err != nil {
|
|
||||||
log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) Delete(filterID int) error {
|
func (s *service) Delete(ctx context.Context, filterID int) error {
|
||||||
if filterID == 0 {
|
if filterID == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete
|
// take care of filter actions
|
||||||
if err := s.repo.Delete(filterID); err != nil {
|
if err := s.actionRepo.DeleteByFilterID(ctx, filterID); err != nil {
|
||||||
|
log.Error().Err(err).Msg("could not delete filter actions")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// take care of filter indexers
|
||||||
|
if err := s.repo.DeleteIndexerConnections(ctx, filterID); err != nil {
|
||||||
|
log.Error().Err(err).Msg("could not delete filter indexers")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete filter
|
||||||
|
if err := s.repo.Delete(ctx, filterID); err != nil {
|
||||||
log.Error().Err(err).Msgf("could not delete filter: %v", filterID)
|
log.Error().Err(err).Msgf("could not delete filter: %v", filterID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
|
|
||||||
type actionService interface {
|
type actionService interface {
|
||||||
Fetch() ([]domain.Action, error)
|
Fetch() ([]domain.Action, error)
|
||||||
Store(action domain.Action) (*domain.Action, error)
|
Store(ctx context.Context, action domain.Action) (*domain.Action, error)
|
||||||
Delete(actionID int) error
|
Delete(actionID int) error
|
||||||
ToggleEnabled(actionID int) error
|
ToggleEnabled(actionID int) error
|
||||||
}
|
}
|
||||||
|
@ -47,61 +48,71 @@ func (h actionHandler) getActions(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h actionHandler) storeAction(w http.ResponseWriter, r *http.Request) {
|
func (h actionHandler) storeAction(w http.ResponseWriter, r *http.Request) {
|
||||||
var data domain.Action
|
var (
|
||||||
|
data domain.Action
|
||||||
|
ctx = r.Context()
|
||||||
|
)
|
||||||
|
|
||||||
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
|
||||||
// encode error
|
// encode error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
action, err := h.service.Store(data)
|
action, err := h.service.Store(ctx, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// encode error
|
// encode error
|
||||||
}
|
}
|
||||||
|
|
||||||
h.encoder.StatusResponse(r.Context(), w, action, http.StatusCreated)
|
h.encoder.StatusResponse(ctx, w, action, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h actionHandler) updateAction(w http.ResponseWriter, r *http.Request) {
|
func (h actionHandler) updateAction(w http.ResponseWriter, r *http.Request) {
|
||||||
var data domain.Action
|
var (
|
||||||
|
data domain.Action
|
||||||
|
ctx = r.Context()
|
||||||
|
)
|
||||||
|
|
||||||
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
|
||||||
// encode error
|
// encode error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
action, err := h.service.Store(data)
|
action, err := h.service.Store(ctx, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// encode error
|
// encode error
|
||||||
}
|
}
|
||||||
|
|
||||||
h.encoder.StatusResponse(r.Context(), w, action, http.StatusCreated)
|
h.encoder.StatusResponse(ctx, w, action, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h actionHandler) deleteAction(w http.ResponseWriter, r *http.Request) {
|
func (h actionHandler) deleteAction(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var ctx = r.Context()
|
||||||
|
|
||||||
actionID, err := parseInt(chi.URLParam(r, "id"))
|
actionID, err := parseInt(chi.URLParam(r, "id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.encoder.StatusResponse(r.Context(), w, errors.New("bad param id"), http.StatusBadRequest)
|
h.encoder.StatusResponse(ctx, w, errors.New("bad param id"), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.Delete(actionID); err != nil {
|
if err := h.service.Delete(actionID); err != nil {
|
||||||
// encode error
|
// encode error
|
||||||
}
|
}
|
||||||
|
|
||||||
h.encoder.StatusResponse(r.Context(), w, nil, http.StatusNoContent)
|
h.encoder.StatusResponse(ctx, w, nil, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h actionHandler) toggleActionEnabled(w http.ResponseWriter, r *http.Request) {
|
func (h actionHandler) toggleActionEnabled(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var ctx = r.Context()
|
||||||
|
|
||||||
actionID, err := parseInt(chi.URLParam(r, "id"))
|
actionID, err := parseInt(chi.URLParam(r, "id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.encoder.StatusResponse(r.Context(), w, errors.New("bad param id"), http.StatusBadRequest)
|
h.encoder.StatusResponse(ctx, w, errors.New("bad param id"), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.ToggleEnabled(actionID); err != nil {
|
if err := h.service.ToggleEnabled(actionID); err != nil {
|
||||||
// encode error
|
// encode error
|
||||||
}
|
}
|
||||||
|
|
||||||
h.encoder.StatusResponse(r.Context(), w, nil, http.StatusCreated)
|
h.encoder.StatusResponse(ctx, w, nil, http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseInt(s string) (int, error) {
|
func parseInt(s string) (int, error) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -14,9 +15,8 @@ type filterService interface {
|
||||||
ListFilters() ([]domain.Filter, error)
|
ListFilters() ([]domain.Filter, error)
|
||||||
FindByID(filterID int) (*domain.Filter, error)
|
FindByID(filterID int) (*domain.Filter, error)
|
||||||
Store(filter domain.Filter) (*domain.Filter, error)
|
Store(filter domain.Filter) (*domain.Filter, error)
|
||||||
Delete(filterID int) error
|
Delete(ctx context.Context, filterID int) error
|
||||||
Update(filter domain.Filter) (*domain.Filter, error)
|
Update(ctx context.Context, filter domain.Filter) (*domain.Filter, error)
|
||||||
//StoreFilterAction(action domain.Action) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type filterHandler struct {
|
type filterHandler struct {
|
||||||
|
@ -114,7 +114,7 @@ func (h filterHandler) update(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
filter, err := h.service.Update(data)
|
filter, err := h.service.Update(ctx, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// encode error
|
// encode error
|
||||||
return
|
return
|
||||||
|
@ -131,7 +131,7 @@ func (h filterHandler) delete(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
id, _ := strconv.Atoi(filterID)
|
id, _ := strconv.Atoi(filterID)
|
||||||
|
|
||||||
if err := h.service.Delete(id); err != nil {
|
if err := h.service.Delete(ctx, id); err != nil {
|
||||||
// return err
|
// return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Fragment, useRef } from "react";
|
import { Fragment, useRef } from "react";
|
||||||
import { Dialog, Transition, Switch as SwitchBasic } from "@headlessui/react";
|
import { Dialog, Transition, Switch as SwitchBasic } from "@headlessui/react";
|
||||||
import { ChevronDownIcon, ChevronRightIcon, ExclamationIcon, } from '@heroicons/react/solid'
|
import { ChevronDownIcon, ChevronRightIcon, } from '@heroicons/react/solid'
|
||||||
import { EmptyListState } from "../../components/emptystates";
|
import { EmptyListState } from "../../components/emptystates";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -126,7 +126,7 @@ export default function FilterDetails() {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const { data: indexers } = useQuery<Indexer[], Error>('indexerList', APIClient.indexers.getOptions,
|
const { data: indexers } = useQuery<Indexer[], Error>(["filter", "indexer_list"], APIClient.indexers.getOptions,
|
||||||
{
|
{
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
}
|
}
|
||||||
|
@ -142,10 +142,8 @@ export default function FilterDetails() {
|
||||||
})
|
})
|
||||||
|
|
||||||
const deleteMutation = useMutation((id: number) => APIClient.filters.delete(id), {
|
const deleteMutation = useMutation((id: number) => APIClient.filters.delete(id), {
|
||||||
onSuccess: (filter) => {
|
onSuccess: () => {
|
||||||
// invalidate filters
|
toast.custom((t) => <Toast type="success" body={`${data?.name} was deleted`} t={t} />)
|
||||||
queryClient.invalidateQueries("filter");
|
|
||||||
toast.custom((t) => <Toast type="success" body={`${filter.name} was deleted`} t={t} />)
|
|
||||||
|
|
||||||
// redirect
|
// redirect
|
||||||
history.push("/filters")
|
history.push("/filters")
|
||||||
|
@ -539,7 +537,7 @@ interface FilterActionsProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function FilterActions({ filter, values }: FilterActionsProps) {
|
function FilterActions({ filter, values }: FilterActionsProps) {
|
||||||
const { data } = useQuery<DownloadClient[], Error>('downloadClients', APIClient.download_clients.getAll,
|
const { data } = useQuery<DownloadClient[], Error>(['filter', 'download_clients'], APIClient.download_clients.getAll,
|
||||||
{
|
{
|
||||||
refetchOnWindowFocus: false
|
refetchOnWindowFocus: false
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue