feat(confg): reload on save and refactor logging (#275)

* feat(confg): reload on save

* refactor(logging): rework
This commit is contained in:
Ludvig Lundgren 2022-05-20 09:27:01 +02:00 committed by GitHub
parent 198528a474
commit 91b094f4f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 995 additions and 873 deletions

View file

@ -10,18 +10,17 @@ import (
"github.com/autobrr/autobrr/internal/domain"
delugeClient "github.com/gdm85/go-libdeluge"
"github.com/rs/zerolog/log"
)
func (s *service) deluge(action domain.Action, release domain.Release) error {
log.Debug().Msgf("action Deluge: %v", action.Name)
s.log.Debug().Msgf("action Deluge: %v", action.Name)
var err error
// get client for action
client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID)
if err != nil {
log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID)
s.log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID)
return err
}
@ -40,12 +39,12 @@ func (s *service) deluge(action domain.Action, release domain.Release) error {
switch client.Type {
case "DELUGE_V1":
if err = delugeV1(client, settings, action, release); err != nil {
if err = s.delugeV1(client, settings, action, release); err != nil {
return err
}
case "DELUGE_V2":
if err = delugeV2(client, settings, action, release); err != nil {
if err = s.delugeV2(client, settings, action, release); err != nil {
return err
}
}
@ -54,12 +53,12 @@ func (s *service) deluge(action domain.Action, release domain.Release) error {
}
func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error) {
log.Trace().Msgf("action Deluge: %v check rules", action.Name)
s.log.Trace().Msgf("action Deluge: %v check rules", action.Name)
// get client for action
client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID)
if err != nil {
log.Error().Stack().Err(err).Msgf("error finding client: %v ID %v", action.Name, action.ClientID)
s.log.Error().Stack().Err(err).Msgf("error finding client: %v ID %v", action.Name, action.ClientID)
return false, err
}
@ -88,7 +87,7 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error
// perform connection to Deluge server
err = deluge.Connect()
if err != nil {
log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host)
s.log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host)
return false, err
}
@ -98,7 +97,7 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error
if client.Settings.Rules.Enabled && !action.IgnoreRules {
activeDownloads, err := deluge.TorrentsStatus(delugeClient.StateDownloading, nil)
if err != nil {
log.Error().Stack().Err(err).Msg("Deluge - could not fetch downloading torrents")
s.log.Error().Stack().Err(err).Msg("Deluge - could not fetch downloading torrents")
return false, err
}
@ -107,7 +106,7 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error
// if max active downloads reached, check speed and if lower than threshold add anyways
if len(activeDownloads) >= client.Settings.Rules.MaxActiveDownloads {
log.Debug().Msg("max active downloads reached, skipping")
s.log.Debug().Msg("max active downloads reached, skipping")
return false, nil
// // TODO handle ignore slow torrents
@ -117,16 +116,16 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error
// // gives type conversion errors
// state, err := deluge.GetSessionStatus()
// if err != nil {
// log.Error().Err(err).Msg("could not get session state")
// s.log.Error().Err(err).Msg("could not get session state")
// return err
// }
//
// if int64(state.DownloadRate)*1024 >= client.Settings.Rules.DownloadSpeedThreshold {
// log.Trace().Msg("max active downloads reached, skip adding")
// s.log.Trace().Msg("max active downloads reached, skip adding")
// return nil
// }
//
// log.Trace().Msg("active downloads are slower than set limit, lets add it")
// s.log.Trace().Msg("active downloads are slower than set limit, lets add it")
//}
}
}
@ -135,14 +134,14 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error
return true, nil
}
func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error {
func (s *service) delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error {
deluge := delugeClient.NewV1(settings)
// perform connection to Deluge server
err := deluge.Connect()
if err != nil {
log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host)
s.log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host)
return err
}
@ -150,14 +149,14 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act
t, err := ioutil.ReadFile(release.TorrentTmpFile)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile)
s.log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile)
return err
}
// encode file to base64 before sending to deluge
encodedFile := base64.StdEncoding.EncodeToString(t)
if encodedFile == "" {
log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile)
s.log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile)
return err
}
@ -174,7 +173,7 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act
// parse and replace values in argument string before continuing
savePathArgs, err := m.Parse(action.SavePath)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath)
return err
}
@ -189,25 +188,25 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act
options.MaxUploadSpeed = &maxUL
}
log.Trace().Msgf("action Deluge options: %+v", options)
s.log.Trace().Msgf("action Deluge options: %+v", options)
torrentHash, err := deluge.AddTorrentFile(release.TorrentTmpFile, encodedFile, &options)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name)
s.log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name)
return err
}
if action.Label != "" {
p, err := deluge.LabelPlugin()
if err != nil {
log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name)
s.log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name)
return err
}
// parse and replace values in argument string before continuing
labelArgs, err := m.Parse(action.Label)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label)
return err
}
@ -215,25 +214,25 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act
// TODO first check if label exists, if not, add it, otherwise set
err = p.SetTorrentLabel(torrentHash, labelArgs)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name)
s.log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name)
return err
}
}
}
log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name)
s.log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name)
return nil
}
func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error {
func (s *service) delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error {
deluge := delugeClient.NewV2(settings)
// perform connection to Deluge server
err := deluge.Connect()
if err != nil {
log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host)
s.log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host)
return err
}
@ -241,14 +240,14 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act
t, err := ioutil.ReadFile(release.TorrentTmpFile)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile)
s.log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile)
return err
}
// encode file to base64 before sending to deluge
encodedFile := base64.StdEncoding.EncodeToString(t)
if encodedFile == "" {
log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile)
s.log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile)
return err
}
@ -265,7 +264,7 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act
// parse and replace values in argument string before continuing
savePathArgs, err := m.Parse(action.SavePath)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath)
return err
}
@ -280,25 +279,25 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act
options.MaxUploadSpeed = &maxUL
}
log.Trace().Msgf("action Deluge options: %+v", options)
s.log.Trace().Msgf("action Deluge options: %+v", options)
torrentHash, err := deluge.AddTorrentFile(release.TorrentTmpFile, encodedFile, &options)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name)
s.log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name)
return err
}
if action.Label != "" {
p, err := deluge.LabelPlugin()
if err != nil {
log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name)
s.log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name)
return err
}
// parse and replace values in argument string before continuing
labelArgs, err := m.Parse(action.Label)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label)
return err
}
@ -306,13 +305,13 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act
// TODO first check if label exists, if not, add it, otherwise set
err = p.SetTorrentLabel(torrentHash, labelArgs)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name)
s.log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name)
return err
}
}
}
log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name)
s.log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name)
return nil
}

View file

@ -6,17 +6,15 @@ import (
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/rs/zerolog/log"
)
func (s *service) execCmd(release domain.Release, action domain.Action) {
log.Debug().Msgf("action exec: %v release: %v", action.Name, release.TorrentName)
s.log.Debug().Msgf("action exec: %v release: %v", action.Name, release.TorrentName)
// check if program exists
cmd, err := exec.LookPath(action.ExecCmd)
if err != nil {
log.Error().Stack().Err(err).Msgf("exec failed, could not find program: %v", action.ExecCmd)
s.log.Error().Stack().Err(err).Msgf("exec failed, could not find program: %v", action.ExecCmd)
return
}
@ -26,7 +24,7 @@ func (s *service) execCmd(release domain.Release, action domain.Action) {
// parse and replace values in argument string before continuing
parsedArgs, err := m.Parse(action.ExecArgs)
if err != nil {
log.Error().Stack().Err(err).Msgf("exec failed, could not parse arguments: %v", action.ExecCmd)
s.log.Error().Stack().Err(err).Msgf("exec failed, could not parse arguments: %v", action.ExecCmd)
return
}
@ -42,12 +40,12 @@ func (s *service) execCmd(release domain.Release, action domain.Action) {
output, err := command.CombinedOutput()
if err != nil {
// everything other than exit 0 is considered an error
log.Error().Stack().Err(err).Msgf("command: %v args: %v failed, torrent: %v", cmd, parsedArgs, release.TorrentTmpFile)
s.log.Error().Stack().Err(err).Msgf("command: %v args: %v failed, torrent: %v", cmd, parsedArgs, release.TorrentTmpFile)
}
log.Trace().Msgf("executed command: '%v'", string(output))
s.log.Trace().Msgf("executed command: '%v'", string(output))
duration := time.Since(start)
log.Info().Msgf("executed command: '%v', args: '%v' %v,%v, total time %v", cmd, parsedArgs, release.TorrentName, release.Indexer, duration)
s.log.Info().Msgf("executed command: '%v', args: '%v' %v,%v, total time %v", cmd, parsedArgs, release.TorrentName, release.Indexer, duration)
}

View file

@ -7,19 +7,17 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/lidarr"
"github.com/rs/zerolog/log"
)
func (s *service) lidarr(release domain.Release, action domain.Action) ([]string, error) {
log.Trace().Msg("action LIDARR")
s.log.Trace().Msg("action LIDARR")
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID)
if err != nil {
log.Error().Err(err).Msgf("lidarr: error finding client: %v", action.ClientID)
s.log.Error().Err(err).Msgf("lidarr: error finding client: %v", action.ClientID)
return nil, err
}
@ -61,17 +59,17 @@ func (s *service) lidarr(release domain.Release, action domain.Action) ([]string
rejections, err := arr.Push(r)
if err != nil {
log.Error().Stack().Err(err).Msgf("lidarr: failed to push release: %v", r)
s.log.Error().Stack().Err(err).Msgf("lidarr: failed to push release: %v", r)
return nil, err
}
if rejections != nil {
log.Debug().Msgf("lidarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
s.log.Debug().Msgf("lidarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
return rejections, nil
}
log.Debug().Msgf("lidarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
s.log.Debug().Msgf("lidarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
return nil, nil
}

View file

@ -5,8 +5,6 @@ import (
"strconv"
"time"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/qbittorrent"
)
@ -15,7 +13,7 @@ const ReannounceMaxAttempts = 50
const ReannounceInterval = 7000
func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, release domain.Release) error {
log.Debug().Msgf("action qBittorrent: %v", action.Name)
s.log.Debug().Msgf("action qBittorrent: %v", action.Name)
// macros handle args and replace vars
m := NewMacro(release)
@ -29,7 +27,7 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel
// parse and replace values in argument string before continuing
actionArgs, err := m.Parse(action.SavePath)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath)
return err
}
@ -40,7 +38,7 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel
// parse and replace values in argument string before continuing
categoryArgs, err := m.Parse(action.Category)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Category)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Category)
return err
}
@ -50,7 +48,7 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel
// parse and replace values in argument string before continuing
tagsArgs, err := m.Parse(action.Tags)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Tags)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Tags)
return err
}
@ -69,34 +67,34 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel
options["seedingTimeLimit"] = strconv.FormatInt(action.LimitSeedTime, 10)
}
log.Trace().Msgf("action qBittorrent options: %+v", options)
s.log.Trace().Msgf("action qBittorrent options: %+v", options)
err := qbt.AddTorrentFromFile(release.TorrentTmpFile, options)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, qbt.Name)
s.log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, qbt.Name)
return err
}
if !action.Paused && !action.ReAnnounceSkip && release.TorrentHash != "" {
err = s.checkTrackerStatus(qbt, action, release.TorrentHash)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not reannounce torrent: %v", release.TorrentHash)
s.log.Error().Stack().Err(err).Msgf("could not reannounce torrent: %v", release.TorrentHash)
return err
}
}
log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", release.TorrentHash, qbt.Name)
s.log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", release.TorrentHash, qbt.Name)
return nil
}
func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool, *qbittorrent.Client, error) {
log.Trace().Msgf("action qBittorrent: %v check rules", action.Name)
s.log.Trace().Msgf("action qBittorrent: %v check rules", action.Name)
// get client for action
client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID)
if err != nil {
log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID)
s.log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID)
return false, nil, err
}
@ -118,7 +116,7 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool,
// save cookies?
err = qbt.Login()
if err != nil {
log.Error().Stack().Err(err).Msgf("error logging into client: %v", client.Host)
s.log.Error().Stack().Err(err).Msgf("error logging into client: %v", client.Host)
return false, nil, err
}
@ -126,7 +124,7 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool,
if client.Settings.Rules.Enabled && !action.IgnoreRules {
activeDownloads, err := qbt.GetTorrentsActiveDownloads()
if err != nil {
log.Error().Stack().Err(err).Msg("could not fetch downloading torrents")
s.log.Error().Stack().Err(err).Msg("could not fetch downloading torrents")
return false, nil, err
}
@ -139,20 +137,20 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool,
// check speeds of downloads
info, err := qbt.GetTransferInfo()
if err != nil {
log.Error().Err(err).Msg("could not get transfer info")
s.log.Error().Err(err).Msg("could not get transfer info")
return false, nil, err
}
// if current transfer speed is more than threshold return out and skip
// DlInfoSpeed is in bytes so lets convert to KB to match DownloadSpeedThreshold
if info.DlInfoSpeed/1024 >= client.Settings.Rules.DownloadSpeedThreshold {
log.Debug().Msg("max active downloads reached, skipping")
s.log.Debug().Msg("max active downloads reached, skipping")
return false, nil, nil
}
log.Debug().Msg("active downloads are slower than set limit, lets add it")
s.log.Debug().Msg("active downloads are slower than set limit, lets add it")
} else {
log.Debug().Msg("max active downloads reached, skipping")
s.log.Debug().Msg("max active downloads reached, skipping")
return false, nil, nil
}
}
@ -181,20 +179,20 @@ func (s *service) checkTrackerStatus(qb *qbittorrent.Client, action domain.Actio
}
for attempts < maxAttempts {
log.Debug().Msgf("qBittorrent - run re-announce %v attempt: %v", hash, attempts)
s.log.Debug().Msgf("qBittorrent - run re-announce %v attempt: %v", hash, attempts)
trackers, err := qb.GetTorrentTrackers(hash)
if err != nil {
log.Error().Err(err).Msgf("qBittorrent - could not get trackers for torrent: %v", hash)
s.log.Error().Err(err).Msgf("qBittorrent - could not get trackers for torrent: %v", hash)
return err
}
log.Trace().Msgf("qBittorrent - run re-announce %v attempt: %v trackers (%+v)", hash, attempts, trackers)
s.log.Trace().Msgf("qBittorrent - run re-announce %v attempt: %v trackers (%+v)", hash, attempts, trackers)
// check if status not working or something else
working := findTrackerStatus(trackers)
if working {
log.Debug().Msgf("qBittorrent - re-announce for %v OK", hash)
s.log.Debug().Msgf("qBittorrent - re-announce for %v OK", hash)
announceOK = true
@ -202,10 +200,10 @@ func (s *service) checkTrackerStatus(qb *qbittorrent.Client, action domain.Actio
return nil
}
log.Trace().Msgf("qBittorrent - not working yet, lets re-announce %v attempt: %v", hash, attempts)
s.log.Trace().Msgf("qBittorrent - not working yet, lets re-announce %v attempt: %v", hash, attempts)
err = qb.ReAnnounceTorrents([]string{hash})
if err != nil {
log.Error().Err(err).Msgf("qBittorrent - could not get re-announce torrent: %v", hash)
s.log.Error().Err(err).Msgf("qBittorrent - could not get re-announce torrent: %v", hash)
return err
}
@ -220,11 +218,11 @@ func (s *service) checkTrackerStatus(qb *qbittorrent.Client, action domain.Actio
// delete on failure to reannounce
if !announceOK && action.ReAnnounceDelete {
log.Debug().Msgf("qBittorrent - re-announce for %v took too long, deleting torrent", hash)
s.log.Debug().Msgf("qBittorrent - re-announce for %v took too long, deleting torrent", hash)
err := qb.DeleteTorrents([]string{hash}, false)
if err != nil {
log.Error().Stack().Err(err).Msgf("qBittorrent - could not delete torrent: %v", hash)
s.log.Error().Stack().Err(err).Msgf("qBittorrent - could not delete torrent: %v", hash)
return err
}
}

View file

@ -6,19 +6,17 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/radarr"
"github.com/rs/zerolog/log"
)
func (s *service) radarr(release domain.Release, action domain.Action) ([]string, error) {
log.Trace().Msg("action RADARR")
s.log.Trace().Msg("action RADARR")
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID)
if err != nil {
log.Error().Err(err).Msgf("radarr: error finding client: %v", action.ClientID)
s.log.Error().Err(err).Msgf("radarr: error finding client: %v", action.ClientID)
return nil, err
}
@ -54,17 +52,17 @@ func (s *service) radarr(release domain.Release, action domain.Action) ([]string
rejections, err := arr.Push(r)
if err != nil {
log.Error().Stack().Err(err).Msgf("radarr: failed to push release: %v", r)
s.log.Error().Stack().Err(err).Msgf("radarr: failed to push release: %v", r)
return nil, err
}
if rejections != nil {
log.Debug().Msgf("radarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
s.log.Debug().Msgf("radarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
return rejections, nil
}
log.Debug().Msgf("radarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
s.log.Debug().Msgf("radarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
return nil, nil
}

View file

@ -9,8 +9,6 @@ import (
"path"
"time"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
)
@ -22,11 +20,11 @@ func (s *service) RunActions(actions []domain.Action, release domain.Release) er
continue
}
log.Debug().Msgf("process action: %v for '%v'", action.Name, release.TorrentName)
s.log.Debug().Msgf("process action: %v for '%v'", action.Name, release.TorrentName)
err := s.runAction(action, release)
if err != nil {
log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName)
s.log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName)
s.bus.Publish("release:store-action-status", &domain.ReleaseActionStatus{
ReleaseID: release.ID,
@ -71,7 +69,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st
case domain.ActionTypeExec:
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
break
}
}
@ -81,7 +79,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st
case domain.ActionTypeWatchFolder:
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
break
}
}
@ -91,7 +89,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st
case domain.ActionTypeWebhook:
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
break
}
}
@ -101,7 +99,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st
case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2:
canDownload, err := s.delugeCheckRulesCanDownload(*action)
if err != nil {
log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
break
}
if !canDownload {
@ -111,21 +109,21 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
break
}
}
err = s.deluge(*action, release)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to Deluge")
s.log.Error().Stack().Err(err).Msg("error sending torrent to Deluge")
break
}
case domain.ActionTypeQbittorrent:
canDownload, client, err := s.qbittorrentCheckRulesCanDownload(*action)
if err != nil {
log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
break
}
if !canDownload {
@ -135,47 +133,47 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
break
}
}
err = s.qbittorrent(client, *action, release)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent")
s.log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent")
break
}
case domain.ActionTypeRadarr:
rejections, err = s.radarr(release, *action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to radarr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to radarr")
break
}
case domain.ActionTypeSonarr:
rejections, err = s.sonarr(release, *action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to sonarr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to sonarr")
break
}
case domain.ActionTypeLidarr:
rejections, err = s.lidarr(release, *action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to lidarr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to lidarr")
break
}
case domain.ActionTypeWhisparr:
rejections, err = s.whisparr(release, *action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to whisparr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to whisparr")
break
}
default:
log.Warn().Msgf("unsupported action type: %v", action.Type)
s.log.Warn().Msgf("unsupported action type: %v", action.Type)
return rejections, err
}
@ -205,7 +203,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st
}
if err != nil {
log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName)
s.log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName)
rlsActionStatus.Status = domain.ReleasePushStatusErr
rlsActionStatus.Rejections = []string{err.Error()}
@ -243,7 +241,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error
case domain.ActionTypeExec:
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
return err
}
}
@ -253,7 +251,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error
case domain.ActionTypeWatchFolder:
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
return err
}
}
@ -263,7 +261,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error
case domain.ActionTypeWebhook:
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
return err
}
}
@ -273,7 +271,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error
case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2:
canDownload, err := s.delugeCheckRulesCanDownload(action)
if err != nil {
log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
return err
}
if !canDownload {
@ -283,21 +281,21 @@ func (s *service) runAction(action domain.Action, release domain.Release) error
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
return err
}
}
err = s.deluge(action, release)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to Deluge")
s.log.Error().Stack().Err(err).Msg("error sending torrent to Deluge")
return err
}
case domain.ActionTypeQbittorrent:
canDownload, client, err := s.qbittorrentCheckRulesCanDownload(action)
if err != nil {
log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
return err
}
if !canDownload {
@ -307,47 +305,47 @@ func (s *service) runAction(action domain.Action, release domain.Release) error
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFile(); err != nil {
log.Error().Stack().Err(err)
s.log.Error().Stack().Err(err)
return err
}
}
err = s.qbittorrent(client, action, release)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent")
s.log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent")
return err
}
case domain.ActionTypeRadarr:
rejections, err = s.radarr(release, action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to radarr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to radarr")
return err
}
case domain.ActionTypeSonarr:
rejections, err = s.sonarr(release, action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to sonarr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to sonarr")
return err
}
case domain.ActionTypeLidarr:
rejections, err = s.lidarr(release, action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to lidarr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to lidarr")
return err
}
case domain.ActionTypeWhisparr:
rejections, err = s.whisparr(release, action)
if err != nil {
log.Error().Stack().Err(err).Msg("error sending torrent to whisparr")
s.log.Error().Stack().Err(err).Msg("error sending torrent to whisparr")
return err
}
default:
log.Warn().Msgf("unsupported action: %v type: %v", action.Name, action.Type)
s.log.Warn().Msgf("unsupported action: %v type: %v", action.Name, action.Type)
return nil
}
@ -399,13 +397,13 @@ func (s *service) CheckCanDownload(actions []domain.Action) bool {
continue
}
log.Debug().Msgf("action-service: check can download action: %v", action.Name)
s.log.Debug().Msgf("action-service: check can download action: %v", action.Name)
switch action.Type {
case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2:
canDownload, err := s.delugeCheckRulesCanDownload(action)
if err != nil {
log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
continue
}
if !canDownload {
@ -417,7 +415,7 @@ func (s *service) CheckCanDownload(actions []domain.Action) bool {
case domain.ActionTypeQbittorrent:
canDownload, _, err := s.qbittorrentCheckRulesCanDownload(action)
if err != nil {
log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name)
continue
}
if !canDownload {
@ -432,7 +430,7 @@ func (s *service) CheckCanDownload(actions []domain.Action) bool {
}
func (s *service) test(name string) {
log.Info().Msgf("action TEST: %v", name)
s.log.Info().Msgf("action TEST: %v", name)
}
func (s *service) watchFolder(action domain.Action, release domain.Release) {
@ -441,15 +439,15 @@ func (s *service) watchFolder(action domain.Action, release domain.Release) {
// parse and replace values in argument string before continuing
watchFolderArgs, err := m.Parse(action.WatchFolder)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WatchFolder)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WatchFolder)
}
log.Trace().Msgf("action WATCH_FOLDER: %v file: %v", watchFolderArgs, release.TorrentTmpFile)
s.log.Trace().Msgf("action WATCH_FOLDER: %v file: %v", watchFolderArgs, release.TorrentTmpFile)
// Open original file
original, err := os.Open(release.TorrentTmpFile)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not open temp file '%v'", release.TorrentTmpFile)
s.log.Error().Stack().Err(err).Msgf("could not open temp file '%v'", release.TorrentTmpFile)
return
}
defer original.Close()
@ -460,7 +458,7 @@ func (s *service) watchFolder(action domain.Action, release domain.Release) {
// Create new file
newFile, err := os.Create(fullFileName)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not create new temp file '%v'", fullFileName)
s.log.Error().Stack().Err(err).Msgf("could not create new temp file '%v'", fullFileName)
return
}
defer newFile.Close()
@ -468,11 +466,11 @@ func (s *service) watchFolder(action domain.Action, release domain.Release) {
// Copy file
_, err = io.Copy(newFile, original)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not copy file %v to watch folder", fullFileName)
s.log.Error().Stack().Err(err).Msgf("could not copy file %v to watch folder", fullFileName)
return
}
log.Info().Msgf("saved file to watch folder: %v", fullFileName)
s.log.Info().Msgf("saved file to watch folder: %v", fullFileName)
}
func (s *service) webhook(action domain.Action, release domain.Release) {
@ -481,12 +479,12 @@ func (s *service) webhook(action domain.Action, release domain.Release) {
// parse and replace values in argument string before continuing
dataArgs, err := m.Parse(action.WebhookData)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WebhookData)
s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WebhookData)
return
}
log.Trace().Msgf("action WEBHOOK: '%v' file: %v", action.Name, release.TorrentName)
log.Trace().Msgf("webhook action '%v' - host: %v data: %v", action.Name, action.WebhookHost, action.WebhookData)
s.log.Trace().Msgf("action WEBHOOK: '%v' file: %v", action.Name, release.TorrentName)
s.log.Trace().Msgf("webhook action '%v' - host: %v data: %v", action.Name, action.WebhookHost, action.WebhookData)
t := &http.Transport{
TLSClientConfig: &tls.Config{
@ -498,7 +496,7 @@ func (s *service) webhook(action domain.Action, release domain.Release) {
req, err := http.NewRequest(http.MethodPost, action.WebhookHost, bytes.NewBufferString(dataArgs))
if err != nil {
log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost)
s.log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost)
return
}
@ -507,13 +505,13 @@ func (s *service) webhook(action domain.Action, release domain.Release) {
res, err := client.Do(req)
if err != nil {
log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost)
s.log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost)
return
}
defer res.Body.Close()
log.Info().Msgf("successfully ran webhook action: '%v' to: %v payload: %v", action.Name, action.WebhookHost, dataArgs)
s.log.Info().Msgf("successfully ran webhook action: '%v' to: %v payload: %v", action.Name, action.WebhookHost, dataArgs)
return
}

View file

@ -7,6 +7,7 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/download_client"
"github.com/autobrr/autobrr/internal/logger"
)
type Service interface {
@ -22,13 +23,19 @@ type Service interface {
}
type service struct {
log logger.Logger
repo domain.ActionRepo
clientSvc download_client.Service
bus EventBus.Bus
}
func NewService(repo domain.ActionRepo, clientSvc download_client.Service, bus EventBus.Bus) Service {
return &service{repo: repo, clientSvc: clientSvc, bus: bus}
func NewService(log logger.Logger, repo domain.ActionRepo, clientSvc download_client.Service, bus EventBus.Bus) Service {
return &service{
log: log,
repo: repo,
clientSvc: clientSvc,
bus: bus,
}
}
func (s *service) Store(ctx context.Context, action domain.Action) (*domain.Action, error) {

View file

@ -6,19 +6,17 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/sonarr"
"github.com/rs/zerolog/log"
)
func (s *service) sonarr(release domain.Release, action domain.Action) ([]string, error) {
log.Trace().Msg("action SONARR")
s.log.Trace().Msg("action SONARR")
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID)
if err != nil {
log.Error().Err(err).Msgf("sonarr: error finding client: %v", action.ClientID)
s.log.Error().Err(err).Msgf("sonarr: error finding client: %v", action.ClientID)
return nil, err
}
@ -54,17 +52,17 @@ func (s *service) sonarr(release domain.Release, action domain.Action) ([]string
rejections, err := arr.Push(r)
if err != nil {
log.Error().Stack().Err(err).Msgf("sonarr: failed to push release: %v", r)
s.log.Error().Stack().Err(err).Msgf("sonarr: failed to push release: %v", r)
return nil, err
}
if rejections != nil {
log.Debug().Msgf("sonarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
s.log.Debug().Msgf("sonarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
return rejections, nil
}
log.Debug().Msgf("sonarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
s.log.Debug().Msgf("sonarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
return nil, nil
}

View file

@ -6,19 +6,17 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/whisparr"
"github.com/rs/zerolog/log"
)
func (s *service) whisparr(release domain.Release, action domain.Action) ([]string, error) {
log.Trace().Msg("action WHISPARR")
s.log.Trace().Msg("action WHISPARR")
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID)
if err != nil {
log.Error().Err(err).Msgf("whisparr: error finding client: %v", action.ClientID)
s.log.Error().Err(err).Msgf("whisparr: error finding client: %v", action.ClientID)
return nil, err
}
@ -54,17 +52,17 @@ func (s *service) whisparr(release domain.Release, action domain.Action) ([]stri
rejections, err := arr.Push(r)
if err != nil {
log.Error().Stack().Err(err).Msgf("whisparr: failed to push release: %v", r)
s.log.Error().Stack().Err(err).Msgf("whisparr: failed to push release: %v", r)
return nil, err
}
if rejections != nil {
log.Debug().Msgf("whisparr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
s.log.Debug().Msgf("whisparr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections)
return rejections, nil
}
log.Debug().Msgf("whisparr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
s.log.Debug().Msgf("whisparr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host)
return nil, nil
}

View file

@ -9,10 +9,10 @@ import (
"strings"
"text/template"
"github.com/rs/zerolog"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/release"
"github.com/rs/zerolog/log"
)
type Processor interface {
@ -20,6 +20,7 @@ type Processor interface {
}
type announceProcessor struct {
log zerolog.Logger
indexer *domain.IndexerDefinition
releaseSvc release.Service
@ -27,8 +28,9 @@ type announceProcessor struct {
queues map[string]chan string
}
func NewAnnounceProcessor(releaseSvc release.Service, indexer *domain.IndexerDefinition) Processor {
func NewAnnounceProcessor(log zerolog.Logger, releaseSvc release.Service, indexer *domain.IndexerDefinition) Processor {
ap := &announceProcessor{
log: log,
releaseSvc: releaseSvc,
indexer: indexer,
}
@ -46,7 +48,7 @@ func (a *announceProcessor) setupQueues() {
channel = strings.ToLower(channel)
queues[channel] = make(chan string, 128)
log.Trace().Msgf("announce: setup queue: %v", channel)
a.log.Trace().Msgf("announce: setup queue: %v", channel)
}
a.queues = queues
@ -55,9 +57,9 @@ func (a *announceProcessor) setupQueues() {
func (a *announceProcessor) setupQueueConsumers() {
for queueName, queue := range a.queues {
go func(name string, q chan string) {
log.Trace().Msgf("announce: setup queue consumer: %v", name)
a.log.Trace().Msgf("announce: setup queue consumer: %v", name)
a.processQueue(q)
log.Trace().Msgf("announce: queue consumer stopped: %v", name)
a.log.Trace().Msgf("announce: queue consumer stopped: %v", name)
}(queueName, queue)
}
}
@ -71,43 +73,43 @@ func (a *announceProcessor) processQueue(queue chan string) {
for _, pattern := range a.indexer.Parse.Lines {
line, err := a.getNextLine(queue)
if err != nil {
log.Error().Stack().Err(err).Msg("could not get line from queue")
a.log.Error().Stack().Err(err).Msg("could not get line from queue")
return
}
log.Trace().Msgf("announce: process line: %v", line)
a.log.Trace().Msgf("announce: process line: %v", line)
// check should ignore
match, err := a.parseExtract(pattern.Pattern, pattern.Vars, tmpVars, line)
if err != nil {
log.Debug().Msgf("error parsing extract: %v", line)
a.log.Debug().Msgf("error parsing extract: %v", line)
parseFailed = true
break
}
if !match {
log.Debug().Msgf("line not matching expected regex pattern: %v", line)
a.log.Debug().Msgf("line not matching expected regex pattern: %v", line)
parseFailed = true
break
}
}
if parseFailed {
log.Trace().Msg("announce: parse failed")
a.log.Trace().Msg("announce: parse failed")
continue
}
rls, err := domain.NewRelease(a.indexer.Identifier)
if err != nil {
log.Error().Err(err).Msg("could not create new release")
a.log.Error().Err(err).Msg("could not create new release")
continue
}
// on lines matched
err = a.onLinesMatched(a.indexer, tmpVars, rls)
if err != nil {
log.Debug().Msgf("error match line: %v", "")
a.log.Debug().Msgf("error match line: %v", "")
continue
}
@ -135,7 +137,7 @@ func (a *announceProcessor) AddLineToQueue(channel string, line string) error {
}
queue <- line
log.Trace().Msgf("announce: queued line: %v", line)
a.log.Trace().Msgf("announce: queued line: %v", line)
return nil
}
@ -144,7 +146,7 @@ func (a *announceProcessor) parseExtract(pattern string, vars []string, tmpVars
rxp, err := regExMatch(pattern, line)
if err != nil {
log.Debug().Msgf("did not match expected line: %v", line)
a.log.Debug().Msgf("did not match expected line: %v", line)
}
if rxp == nil {
@ -171,21 +173,21 @@ func (a *announceProcessor) onLinesMatched(def *domain.IndexerDefinition, vars m
err = rls.MapVars(def, vars)
if err != nil {
log.Error().Stack().Err(err).Msg("announce: could not map vars for release")
a.log.Error().Stack().Err(err).Msg("announce: could not map vars for release")
return err
}
// parse fields
err = rls.ParseString(rls.TorrentName)
if err != nil {
log.Error().Stack().Err(err).Msg("announce: could not parse release")
a.log.Error().Stack().Err(err).Msg("announce: could not parse release")
return err
}
// parse torrentUrl
err = def.Parse.ParseTorrentUrl(vars, def.SettingsMap, rls)
if err != nil {
log.Error().Stack().Err(err).Msg("announce: could not parse torrent url")
a.log.Error().Stack().Err(err).Msg("announce: could not parse torrent url")
return err
}
@ -221,14 +223,14 @@ func (a *announceProcessor) processTorrentUrl(match string, vars map[string]stri
// setup text template to inject variables into
tmpl, err := template.New("torrenturl").Parse(match)
if err != nil {
log.Error().Err(err).Msg("could not create torrent url template")
a.log.Error().Err(err).Msg("could not create torrent url template")
return "", err
}
var b bytes.Buffer
err = tmpl.Execute(&b, &tmpVars)
if err != nil {
log.Error().Err(err).Msg("could not write torrent url template output")
a.log.Error().Err(err).Msg("could not write torrent url template output")
return "", err
}

View file

@ -6,32 +6,15 @@ import (
"os"
"path"
"path/filepath"
"sync"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
var Config domain.Config
func Defaults() domain.Config {
return domain.Config{
Host: "localhost",
Port: 7474,
LogLevel: "TRACE",
LogPath: "",
BaseURL: "/",
SessionSecret: "secret-session-key",
CustomDefinitions: "",
DatabaseType: "sqlite",
PostgresHost: "",
PostgresPort: 0,
PostgresDatabase: "",
PostgresUser: "",
PostgresPass: "",
}
}
func writeConfig(configPath string, configFile string) error {
path := filepath.Join(configPath, configFile)
@ -108,9 +91,45 @@ sessionSecret = "secret-session-key"`)
return nil
}
func Read(configPath string) domain.Config {
config := Defaults()
type Config interface {
DynamicReload(log logger.Logger)
}
type AppConfig struct {
Config *domain.Config
m sync.Mutex
}
func New(configPath string, version string) *AppConfig {
c := &AppConfig{}
c.defaults()
c.Config.Version = version
c.load(configPath)
return c
}
func (c *AppConfig) defaults() {
c.Config = &domain.Config{
Version: "dev",
Host: "localhost",
Port: 7474,
LogLevel: "TRACE",
LogPath: "",
BaseURL: "/",
SessionSecret: "secret-session-key",
CustomDefinitions: "",
DatabaseType: "sqlite",
PostgresHost: "",
PostgresPort: 0,
PostgresDatabase: "",
PostgresUser: "",
PostgresPass: "",
}
}
func (c *AppConfig) load(configPath string) {
// or use viper.SetDefault(val, def)
//viper.SetDefault("host", config.Host)
//viper.SetDefault("port", config.Port)
@ -133,7 +152,6 @@ func Read(configPath string) domain.Config {
}
viper.SetConfigFile(path.Join(configPath, "config.toml"))
config.ConfigPath = configPath
} else {
viper.SetConfigName("config")
@ -148,11 +166,27 @@ func Read(configPath string) domain.Config {
log.Printf("config read error: %q", err)
}
if err := viper.Unmarshal(&config); err != nil {
if err := viper.Unmarshal(&c.Config); err != nil {
log.Fatalf("Could not unmarshal config file: %v", viper.ConfigFileUsed())
}
Config = config
return config
}
func (c *AppConfig) DynamicReload(log logger.Logger) {
viper.OnConfigChange(func(e fsnotify.Event) {
c.m.Lock()
logLevel := viper.GetString("logLevel")
c.Config.LogLevel = logLevel
log.SetLogLevel(c.Config.LogLevel)
logPath := viper.GetString("logPath")
c.Config.LogPath = logPath
log.Debug().Msg("config file reloaded!")
c.m.Unlock()
})
viper.WatchConfig()
return
}

View file

@ -6,18 +6,20 @@ import (
"encoding/json"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
sq "github.com/Masterminds/squirrel"
"github.com/rs/zerolog/log"
)
type ActionRepo struct {
log logger.Logger
db *DB
clientRepo domain.DownloadClientRepo
}
func NewActionRepo(db *DB, clientRepo domain.DownloadClientRepo) domain.ActionRepo {
func NewActionRepo(log logger.Logger, db *DB, clientRepo domain.DownloadClientRepo) domain.ActionRepo {
return &ActionRepo{
log: log,
db: db,
clientRepo: clientRepo,
}
@ -85,13 +87,13 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) (
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.findByFilterID: error building query")
r.log.Error().Stack().Err(err).Msg("action.findByFilterID: error building query")
return nil, err
}
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("action.findByFilterID: query error")
r.log.Error().Stack().Err(err).Msg("action.findByFilterID: query error")
return nil, err
}
@ -110,7 +112,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) (
var paused, ignoreRules sql.NullBool
if err := rows.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &clientID); err != nil {
log.Error().Stack().Err(err).Msg("action.findByFilterID: error scanning row")
r.log.Error().Stack().Err(err).Msg("action.findByFilterID: error scanning row")
return nil, err
}
@ -139,7 +141,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) (
actions = append(actions, &a)
}
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err).Msg("action.findByFilterID: row error")
r.log.Error().Stack().Err(err).Msg("action.findByFilterID: row error")
return nil, err
}
@ -166,13 +168,13 @@ func (r *ActionRepo) attachDownloadClient(ctx context.Context, tx *Tx, clientID
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error building query")
r.log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error building query")
return nil, err
}
row := tx.QueryRowContext(ctx, query, args...)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error query row")
r.log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error query row")
return nil, err
}
@ -180,13 +182,13 @@ func (r *ActionRepo) attachDownloadClient(ctx context.Context, tx *Tx, clientID
var settingsJsonStr string
if err := row.Scan(&client.ID, &client.Name, &client.Type, &client.Enabled, &client.Host, &client.Port, &client.TLS, &client.TLSSkipVerify, &client.Username, &client.Password, &settingsJsonStr); err != nil {
log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error scanning row")
r.log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error scanning row")
return nil, err
}
if settingsJsonStr != "" {
if err := json.Unmarshal([]byte(settingsJsonStr), &client.Settings); err != nil {
log.Error().Stack().Err(err).Msgf("action.attachDownloadClient: could not marshal download client settings %v", settingsJsonStr)
r.log.Error().Stack().Err(err).Msgf("action.attachDownloadClient: could not marshal download client settings %v", settingsJsonStr)
return nil, err
}
}
@ -228,13 +230,13 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.list: error building query")
r.log.Error().Stack().Err(err).Msg("action.list: error building query")
return nil, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("action.list: error executing query")
r.log.Error().Stack().Err(err).Msg("action.list: error executing query")
return nil, err
}
@ -251,7 +253,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
var paused, ignoreRules sql.NullBool
if err := rows.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &clientID); err != nil {
log.Error().Stack().Err(err).Msg("action.list: error scanning row")
r.log.Error().Stack().Err(err).Msg("action.list: error scanning row")
return nil, err
}
@ -277,7 +279,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
actions = append(actions, a)
}
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err).Msg("action.list: row error")
r.log.Error().Stack().Err(err).Msg("action.list: row error")
return nil, err
}
@ -291,17 +293,17 @@ func (r *ActionRepo) Delete(actionID int) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.delete: error building query")
r.log.Error().Stack().Err(err).Msg("action.delete: error building query")
return err
}
_, err = r.db.handler.Exec(query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("action.delete: error executing query")
r.log.Error().Stack().Err(err).Msg("action.delete: error executing query")
return err
}
log.Debug().Msgf("action.delete: %v", actionID)
r.log.Debug().Msgf("action.delete: %v", actionID)
return nil
}
@ -313,17 +315,17 @@ func (r *ActionRepo) DeleteByFilterID(ctx context.Context, filterID int) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error building query")
r.log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error executing query")
r.log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error executing query")
return err
}
log.Debug().Msgf("action.deleteByFilterID: %v", filterID)
r.log.Debug().Msgf("action.deleteByFilterID: %v", filterID)
return nil
}
@ -413,11 +415,11 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
err := queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("action.store: error executing query")
r.log.Error().Stack().Err(err).Msg("action.store: error executing query")
return nil, err
}
log.Debug().Msgf("action.store: added new %v", retID)
r.log.Debug().Msgf("action.store: added new %v", retID)
action.ID = int(retID)
return &action, nil
@ -478,17 +480,17 @@ func (r *ActionRepo) Update(ctx context.Context, action domain.Action) (*domain.
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.update: error building query")
r.log.Error().Stack().Err(err).Msg("action.update: error building query")
return nil, err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("action.update: error executing query")
r.log.Error().Stack().Err(err).Msg("action.update: error executing query")
return nil, err
}
log.Debug().Msgf("action.update: %v", action.ID)
r.log.Debug().Msgf("action.update: %v", action.ID)
return &action, nil
}
@ -507,12 +509,12 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []*domain.A
deleteQuery, deleteArgs, err := deleteQueryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error building query")
r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error building query")
return nil, err
}
_, err = tx.ExecContext(ctx, deleteQuery, deleteArgs...)
if err != nil {
log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query")
r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query")
return nil, err
}
@ -600,18 +602,18 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []*domain.A
err = queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query")
r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query")
return nil, err
}
action.ID = retID
log.Debug().Msgf("action.StoreFilterActions: store '%v' type: '%v' on filter: %v", action.Name, action.Type, filterID)
r.log.Debug().Msgf("action.StoreFilterActions: store '%v' type: '%v' on filter: %v", action.Name, action.Type, filterID)
}
err = tx.Commit()
if err != nil {
log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error updating actions")
r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error updating actions")
return nil, err
}
@ -629,17 +631,17 @@ func (r *ActionRepo) ToggleEnabled(actionID int) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.toggleEnabled: error building query")
r.log.Error().Stack().Err(err).Msg("action.toggleEnabled: error building query")
return err
}
_, err = r.db.handler.Exec(query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("action.toggleEnabled: error executing query")
r.log.Error().Stack().Err(err).Msg("action.toggleEnabled: error executing query")
return err
}
log.Debug().Msgf("action.toggleEnabled: %v", actionID)
r.log.Debug().Msgf("action.toggleEnabled: %v", actionID)
return nil
}

View file

@ -6,13 +6,14 @@ import (
"fmt"
"sync"
sq "github.com/Masterminds/squirrel"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
sq "github.com/Masterminds/squirrel"
)
type DB struct {
log logger.Logger
handler *sql.DB
lock sync.RWMutex
ctx context.Context
@ -24,10 +25,11 @@ type DB struct {
squirrel sq.StatementBuilderType
}
func NewDB(cfg domain.Config) (*DB, error) {
func NewDB(cfg *domain.Config, log logger.Logger) (*DB, error) {
db := &DB{
// set default placeholder for squirrel to support both sqlite and postgres
squirrel: sq.StatementBuilder.PlaceholderFormat(sq.Dollar),
log: log,
}
db.ctx, db.cancel = context.WithCancel(context.Background())
@ -58,12 +60,12 @@ func (db *DB) Open() error {
switch db.Driver {
case "sqlite":
if err = db.openSQLite(); err != nil {
log.Fatal().Err(err).Msg("could not open sqlite db connection")
db.log.Fatal().Err(err).Msg("could not open sqlite db connection")
return err
}
case "postgres":
if err = db.openPostgres(); err != nil {
log.Fatal().Err(err).Msg("could not open postgres db connection")
db.log.Fatal().Err(err).Msg("could not open postgres db connection")
return err
}
}

View file

@ -6,11 +6,11 @@ import (
"sync"
"github.com/autobrr/autobrr/internal/domain"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/logger"
)
type DownloadClientRepo struct {
log logger.Logger
db *DB
cache *clientCache
}
@ -48,8 +48,9 @@ func (c *clientCache) Pop(id int) {
c.mu.Unlock()
}
func NewDownloadClientRepo(db *DB) domain.DownloadClientRepo {
func NewDownloadClientRepo(log logger.Logger, db *DB) domain.DownloadClientRepo {
return &DownloadClientRepo{
log: log,
db: db,
cache: NewClientCache(),
}
@ -76,13 +77,13 @@ func (r *DownloadClientRepo) List(ctx context.Context) ([]domain.DownloadClient,
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.list: error building query")
r.log.Error().Stack().Err(err).Msg("download_client.list: error building query")
return nil, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.list: error executing query")
r.log.Error().Stack().Err(err).Msg("download_client.list: error executing query")
return nil, err
}
@ -93,13 +94,13 @@ func (r *DownloadClientRepo) List(ctx context.Context) ([]domain.DownloadClient,
var settingsJsonStr string
if err := rows.Scan(&f.ID, &f.Name, &f.Type, &f.Enabled, &f.Host, &f.Port, &f.TLS, &f.TLSSkipVerify, &f.Username, &f.Password, &settingsJsonStr); err != nil {
log.Error().Stack().Err(err).Msg("download_client.list: error scanning row")
r.log.Error().Stack().Err(err).Msg("download_client.list: error scanning row")
return clients, err
}
if settingsJsonStr != "" {
if err := json.Unmarshal([]byte(settingsJsonStr), &f.Settings); err != nil {
log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr)
r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr)
return clients, err
}
}
@ -107,7 +108,7 @@ func (r *DownloadClientRepo) List(ctx context.Context) ([]domain.DownloadClient,
clients = append(clients, f)
}
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err).Msg("download_client.list: row error")
r.log.Error().Stack().Err(err).Msg("download_client.list: row error")
return clients, err
}
@ -140,13 +141,13 @@ func (r *DownloadClientRepo) FindByID(ctx context.Context, id int32) (*domain.Do
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.findByID: error building query")
r.log.Error().Stack().Err(err).Msg("download_client.findByID: error building query")
return nil, err
}
row := r.db.handler.QueryRowContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.findByID: error executing query")
r.log.Error().Stack().Err(err).Msg("download_client.findByID: error executing query")
return nil, err
}
@ -154,13 +155,13 @@ func (r *DownloadClientRepo) FindByID(ctx context.Context, id int32) (*domain.Do
var settingsJsonStr string
if err := row.Scan(&client.ID, &client.Name, &client.Type, &client.Enabled, &client.Host, &client.Port, &client.TLS, &client.TLSSkipVerify, &client.Username, &client.Password, &settingsJsonStr); err != nil {
log.Error().Stack().Err(err).Msg("download_client.findByID: error scanning row")
r.log.Error().Stack().Err(err).Msg("download_client.findByID: error scanning row")
return nil, err
}
if settingsJsonStr != "" {
if err := json.Unmarshal([]byte(settingsJsonStr), &client.Settings); err != nil {
log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr)
r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr)
return nil, err
}
}
@ -179,7 +180,7 @@ func (r *DownloadClientRepo) Store(ctx context.Context, client domain.DownloadCl
settingsJson, err := json.Marshal(&settings)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings)
r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings)
return nil, err
}
@ -194,13 +195,13 @@ func (r *DownloadClientRepo) Store(ctx context.Context, client domain.DownloadCl
err = queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.store: error executing query")
r.log.Error().Stack().Err(err).Msg("download_client.store: error executing query")
return nil, err
}
client.ID = retID
log.Debug().Msgf("download_client.store: %d", client.ID)
r.log.Debug().Msgf("download_client.store: %d", client.ID)
// save to cache
r.cache.Set(client.ID, &client)
@ -219,7 +220,7 @@ func (r *DownloadClientRepo) Update(ctx context.Context, client domain.DownloadC
settingsJson, err := json.Marshal(&settings)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings)
r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings)
return nil, err
}
@ -239,17 +240,17 @@ func (r *DownloadClientRepo) Update(ctx context.Context, client domain.DownloadC
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.update: error building query")
r.log.Error().Stack().Err(err).Msg("download_client.update: error building query")
return nil, err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.update: error querying data")
r.log.Error().Stack().Err(err).Msg("download_client.update: error querying data")
return nil, err
}
log.Debug().Msgf("download_client.update: %d", client.ID)
r.log.Debug().Msgf("download_client.update: %d", client.ID)
// save to cache
r.cache.Set(client.ID, &client)
@ -264,13 +265,13 @@ func (r *DownloadClientRepo) Delete(ctx context.Context, clientID int) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.delete: error building query")
r.log.Error().Stack().Err(err).Msg("download_client.delete: error building query")
return err
}
res, err := r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("download_client.delete: error query data")
r.log.Error().Stack().Err(err).Msg("download_client.delete: error query data")
return err
}
@ -282,7 +283,7 @@ func (r *DownloadClientRepo) Delete(ctx context.Context, clientID int) error {
return err
}
log.Info().Msgf("delete download client: %d", clientID)
r.log.Info().Msgf("delete download client: %d", clientID)
return nil
}

View file

@ -5,19 +5,21 @@ import (
"database/sql"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
sq "github.com/Masterminds/squirrel"
"github.com/rs/zerolog/log"
)
func NewFeedRepo(db *DB) domain.FeedRepo {
func NewFeedRepo(log logger.Logger, db *DB) domain.FeedRepo {
return &FeedRepo{
db: db,
log: log,
db: db,
}
}
type FeedRepo struct {
db *DB
log logger.Logger
db *DB
}
func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) {
@ -39,13 +41,13 @@ func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feed.FindById: error building query")
r.log.Error().Stack().Err(err).Msg("feed.FindById: error building query")
return nil, err
}
row := r.db.handler.QueryRowContext(ctx, query, args...)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("feed.FindById: error executing query")
r.log.Error().Stack().Err(err).Msg("feed.FindById: error executing query")
return nil, err
}
@ -54,7 +56,7 @@ func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) {
var apiKey sql.NullString
if err := row.Scan(&f.ID, &f.Indexer, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &apiKey, &f.CreatedAt, &f.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msg("feed.FindById: error scanning row")
r.log.Error().Stack().Err(err).Msg("feed.FindById: error scanning row")
return nil, err
}
@ -83,13 +85,13 @@ func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string)
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error building query")
r.log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error building query")
return nil, err
}
row := r.db.handler.QueryRowContext(ctx, query, args...)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error executing query")
r.log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error executing query")
return nil, err
}
@ -98,7 +100,7 @@ func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string)
var apiKey sql.NullString
if err := row.Scan(&f.ID, &f.Indexer, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &apiKey, &f.CreatedAt, &f.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error scanning row")
r.log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error scanning row")
return nil, err
}
@ -127,13 +129,13 @@ func (r *FeedRepo) Find(ctx context.Context) ([]domain.Feed, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feed.Find: error building query")
r.log.Error().Stack().Err(err).Msg("feed.Find: error building query")
return nil, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("feed.Find: error executing query")
r.log.Error().Stack().Err(err).Msg("feed.Find: error executing query")
return nil, err
}
@ -146,7 +148,7 @@ func (r *FeedRepo) Find(ctx context.Context) ([]domain.Feed, error) {
var apiKey sql.NullString
if err := rows.Scan(&f.ID, &f.Indexer, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &apiKey, &f.CreatedAt, &f.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msg("feed.Find: error scanning row")
r.log.Error().Stack().Err(err).Msg("feed.Find: error scanning row")
return nil, err
}
@ -187,7 +189,7 @@ func (r *FeedRepo) Store(ctx context.Context, feed *domain.Feed) error {
var retID int
if err := queryBuilder.QueryRowContext(ctx).Scan(&retID); err != nil {
log.Error().Stack().Err(err).Msg("feed.Store: error executing query")
r.log.Error().Stack().Err(err).Msg("feed.Store: error executing query")
return err
}
@ -210,13 +212,13 @@ func (r *FeedRepo) Update(ctx context.Context, feed *domain.Feed) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feed.Update: error building query")
r.log.Error().Stack().Err(err).Msg("feed.Update: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("feed.Update: error executing query")
r.log.Error().Stack().Err(err).Msg("feed.Update: error executing query")
return err
}
@ -234,12 +236,12 @@ func (r *FeedRepo) ToggleEnabled(ctx context.Context, id int, enabled bool) erro
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error building query")
r.log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error executing query")
r.log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error executing query")
return err
}
@ -253,17 +255,17 @@ func (r *FeedRepo) Delete(ctx context.Context, id int) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feed.delete: error building query")
r.log.Error().Stack().Err(err).Msg("feed.delete: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("feed.delete: error executing query")
r.log.Error().Stack().Err(err).Msg("feed.delete: error executing query")
return err
}
log.Info().Msgf("feed.delete: successfully deleted: %v", id)
r.log.Info().Msgf("feed.delete: successfully deleted: %v", id)
return nil
}

View file

@ -4,18 +4,19 @@ import (
"database/sql"
"time"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
)
type FeedCacheRepo struct {
db *DB
log logger.Logger
db *DB
}
func NewFeedCacheRepo(db *DB) domain.FeedCacheRepo {
func NewFeedCacheRepo(log logger.Logger, db *DB) domain.FeedCacheRepo {
return &FeedCacheRepo{
db: db,
log: log,
db: db,
}
}
@ -32,13 +33,13 @@ func (r *FeedCacheRepo) Get(bucket string, key string) ([]byte, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feedCache.Get: error building query")
r.log.Error().Stack().Err(err).Msg("feedCache.Get: error building query")
return nil, err
}
row := r.db.handler.QueryRow(query, args...)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("feedCache.Get: query error")
r.log.Error().Stack().Err(err).Msg("feedCache.Get: query error")
return nil, err
}
@ -46,7 +47,7 @@ func (r *FeedCacheRepo) Get(bucket string, key string) ([]byte, error) {
var ttl time.Duration
if err := row.Scan(&value, &ttl); err != nil && err != sql.ErrNoRows {
log.Error().Stack().Err(err).Msg("feedCache.Get: error scanning row")
r.log.Error().Stack().Err(err).Msg("feedCache.Get: error scanning row")
return nil, err
}
@ -64,14 +65,14 @@ func (r *FeedCacheRepo) Exists(bucket string, key string) (bool, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feedCache.Exists: error building query")
r.log.Error().Stack().Err(err).Msg("feedCache.Exists: error building query")
return false, err
}
var exists bool
err = r.db.handler.QueryRow(query, args...).Scan(&exists)
if err != nil && err != sql.ErrNoRows {
log.Error().Stack().Err(err).Msg("feedCache.Exists: query error")
r.log.Error().Stack().Err(err).Msg("feedCache.Exists: query error")
}
return exists, nil
@ -85,12 +86,12 @@ func (r *FeedCacheRepo) Put(bucket string, key string, val []byte, ttl time.Time
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("feedCache.Put: error building query")
r.log.Error().Stack().Err(err).Msg("feedCache.Put: error building query")
return err
}
if _, err = r.db.handler.Exec(query, args...); err != nil {
log.Error().Stack().Err(err).Msg("feedCache.Put: error executing query")
r.log.Error().Stack().Err(err).Msg("feedCache.Put: error executing query")
return err
}

View file

@ -5,19 +5,23 @@ import (
"database/sql"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
)
type FilterRepo struct {
db *DB
log logger.Logger
db *DB
}
func NewFilterRepo(db *DB) domain.FilterRepo {
return &FilterRepo{db: db}
func NewFilterRepo(log logger.Logger, db *DB) domain.FilterRepo {
return &FilterRepo{
log: log,
db: db,
}
}
func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) {
@ -36,13 +40,13 @@ func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.list: error building query")
r.log.Error().Stack().Err(err).Msg("filter.list: error building query")
return nil, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.list: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.list: error executing query")
return nil, err
}
@ -55,7 +59,7 @@ func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) {
var matchReleases, exceptReleases sql.NullString
if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &matchReleases, &exceptReleases, &f.CreatedAt, &f.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msg("filter.list: error scanning row")
r.log.Error().Stack().Err(err).Msg("filter.list: error scanning row")
return nil, err
}
@ -65,7 +69,7 @@ func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) {
filters = append(filters, f)
}
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err).Msg("filter.list: row error")
r.log.Error().Stack().Err(err).Msg("filter.list: row error")
return nil, err
}
@ -129,13 +133,13 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.findByID: error building query")
r.log.Error().Stack().Err(err).Msg("filter.findByID: error building query")
return nil, err
}
row := r.db.handler.QueryRowContext(ctx, query, args...)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("filter.findByID: error query row")
r.log.Error().Stack().Err(err).Msg("filter.findByID: error query row")
return nil, err
}
@ -145,7 +149,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
var delay, maxDownloads, logScore sql.NullInt32
if err := row.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &f.CreatedAt, &f.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msgf("filter.findByID: %v : error scanning row", filterID)
r.log.Error().Stack().Err(err).Msgf("filter.findByID: %v : error scanning row", filterID)
return nil, err
}
@ -269,13 +273,13 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error building query")
r.log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error building query")
return nil, err
}
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error executing query")
return nil, err
}
@ -290,7 +294,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
var delay, maxDownloads, logScore sql.NullInt32
if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &f.CreatedAt, &f.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error scanning row")
r.log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error scanning row")
return nil, err
}
@ -434,7 +438,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F
err := queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.store: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.store: error executing query")
return nil, err
}
@ -498,13 +502,13 @@ func (r *FilterRepo) Update(ctx context.Context, filter domain.Filter) (*domain.
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.update: error building query")
r.log.Error().Stack().Err(err).Msg("filter.update: error building query")
return nil, err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.update: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.update: error executing query")
return nil, err
}
@ -522,12 +526,12 @@ func (r *FilterRepo) ToggleEnabled(ctx context.Context, filterID int, enabled bo
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error building query")
r.log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error executing query")
return err
}
@ -548,12 +552,12 @@ func (r *FilterRepo) StoreIndexerConnections(ctx context.Context, filterID int,
deleteQuery, deleteArgs, err := deleteQueryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query")
r.log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query")
return err
}
_, err = tx.ExecContext(ctx, deleteQuery, deleteArgs...)
if err != nil {
log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error deleting indexers for filter: %v", filterID)
r.log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error deleting indexers for filter: %v", filterID)
return err
}
@ -564,21 +568,21 @@ func (r *FilterRepo) StoreIndexerConnections(ctx context.Context, filterID int,
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query")
r.log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query")
return err
}
_, err = tx.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error executing query")
return err
}
log.Debug().Msgf("filter.StoreIndexerConnections: store '%v' on filter: %v", indexer.Name, filterID)
r.log.Debug().Msgf("filter.StoreIndexerConnections: store '%v' on filter: %v", indexer.Name, filterID)
}
err = tx.Commit()
if err != nil {
log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error storing indexers for filter: %v", filterID)
r.log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error storing indexers for filter: %v", filterID)
return err
}
@ -592,13 +596,13 @@ func (r *FilterRepo) StoreIndexerConnection(ctx context.Context, filterID int, i
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error building query")
r.log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error executing query")
return err
}
@ -612,13 +616,13 @@ func (r *FilterRepo) DeleteIndexerConnections(ctx context.Context, filterID int)
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error building query")
r.log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error executing query")
return err
}
@ -632,17 +636,17 @@ func (r *FilterRepo) Delete(ctx context.Context, filterID int) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("filter.delete: error building query")
r.log.Error().Stack().Err(err).Msg("filter.delete: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("filter.delete: error executing query")
r.log.Error().Stack().Err(err).Msg("filter.delete: error executing query")
return err
}
log.Info().Msgf("filter.delete: successfully deleted: %v", filterID)
r.log.Info().Msgf("filter.delete: successfully deleted: %v", filterID)
return nil
}
@ -667,14 +671,14 @@ WHERE "release".filter_id = ?;`
row := tx.QueryRowContext(ctx, query, filterID)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error querying stats")
r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error querying stats")
return nil, err
}
var f domain.FilterDownloads
if err := row.Scan(&f.HourCount, &f.DayCount, &f.WeekCount, &f.MonthCount, &f.TotalCount); err != nil {
log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error scanning stats data to struct")
r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error scanning stats data to struct")
return nil, err
}
@ -693,14 +697,14 @@ WHERE "release".filter_id = ?;`
row := tx.QueryRowContext(ctx, query, filterID)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error querying stats")
r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error querying stats")
return nil, err
}
var f domain.FilterDownloads
if err := row.Scan(&f.HourCount, &f.DayCount, &f.WeekCount, &f.MonthCount, &f.TotalCount); err != nil {
log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error scanning stats data to struct")
r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error scanning stats data to struct")
return nil, err
}

View file

@ -6,25 +6,26 @@ import (
"encoding/json"
"time"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
)
type IndexerRepo struct {
db *DB
log logger.Logger
db *DB
}
func NewIndexerRepo(db *DB) domain.IndexerRepo {
func NewIndexerRepo(log logger.Logger, db *DB) domain.IndexerRepo {
return &IndexerRepo{
db: db,
log: log,
db: db,
}
}
func (r *IndexerRepo) Store(ctx context.Context, indexer domain.Indexer) (*domain.Indexer, error) {
settings, err := json.Marshal(indexer.Settings)
if err != nil {
log.Error().Stack().Err(err).Msg("error marshaling json data")
r.log.Error().Stack().Err(err).Msg("error marshaling json data")
return nil, err
}
@ -38,7 +39,7 @@ func (r *IndexerRepo) Store(ctx context.Context, indexer domain.Indexer) (*domai
err = queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.store: error executing query")
r.log.Error().Stack().Err(err).Msg("indexer.store: error executing query")
return nil, err
}
@ -50,7 +51,7 @@ func (r *IndexerRepo) Store(ctx context.Context, indexer domain.Indexer) (*domai
func (r *IndexerRepo) Update(ctx context.Context, indexer domain.Indexer) (*domain.Indexer, error) {
settings, err := json.Marshal(indexer.Settings)
if err != nil {
log.Error().Stack().Err(err).Msg("error marshaling json data")
r.log.Error().Stack().Err(err).Msg("error marshaling json data")
return nil, err
}
@ -64,13 +65,13 @@ func (r *IndexerRepo) Update(ctx context.Context, indexer domain.Indexer) (*doma
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.update: error building query")
r.log.Error().Stack().Err(err).Msg("indexer.update: error building query")
return nil, err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.update: error executing query")
r.log.Error().Stack().Err(err).Msg("indexer.update: error executing query")
return nil, err
}
@ -80,7 +81,7 @@ 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, settings FROM indexer ORDER BY name ASC")
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.list: error query indexer")
r.log.Error().Stack().Err(err).Msg("indexer.list: error query indexer")
return nil, err
}
@ -95,7 +96,7 @@ func (r *IndexerRepo) List(ctx context.Context) ([]domain.Indexer, error) {
var settingsMap map[string]string
if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &f.Identifier, &implementation, &settings); err != nil {
log.Error().Stack().Err(err).Msg("indexer.list: error scanning data to struct")
r.log.Error().Stack().Err(err).Msg("indexer.list: error scanning data to struct")
return nil, err
}
@ -103,7 +104,7 @@ func (r *IndexerRepo) List(ctx context.Context) ([]domain.Indexer, error) {
err = json.Unmarshal([]byte(settings), &settingsMap)
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.list: error unmarshal settings")
r.log.Error().Stack().Err(err).Msg("indexer.list: error unmarshal settings")
return nil, err
}
@ -127,13 +128,13 @@ func (r *IndexerRepo) FindByFilterID(ctx context.Context, id int) ([]domain.Inde
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.check_existing_network: error fetching data")
r.log.Error().Stack().Err(err).Msg("irc.check_existing_network: error fetching data")
return nil, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error query indexer")
r.log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error query indexer")
return nil, err
}
@ -147,13 +148,13 @@ func (r *IndexerRepo) FindByFilterID(ctx context.Context, id int) ([]domain.Inde
var settingsMap map[string]string
if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &f.Identifier, &settings); err != nil {
log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error scanning data to struct")
r.log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error scanning data to struct")
return nil, err
}
err = json.Unmarshal([]byte(settings), &settingsMap)
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error unmarshal settings")
r.log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error unmarshal settings")
return nil, err
}
@ -176,17 +177,17 @@ func (r *IndexerRepo) Delete(ctx context.Context, id int) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("indexer.delete: error building query")
r.log.Error().Stack().Err(err).Msg("indexer.delete: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msgf("indexer.delete: error executing query: '%v'", query)
r.log.Error().Stack().Err(err).Msgf("indexer.delete: error executing query: '%v'", query)
return err
}
log.Debug().Msgf("indexer.delete: id %v", id)
r.log.Debug().Msgf("indexer.delete: id %v", id)
return nil
}

View file

@ -3,20 +3,24 @@ package database
import (
"context"
"database/sql"
"github.com/pkg/errors"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/rs/zerolog/log"
"github.com/pkg/errors"
)
type IrcRepo struct {
db *DB
log logger.Logger
db *DB
}
func NewIrcRepo(db *DB) domain.IrcRepo {
return &IrcRepo{db: db}
func NewIrcRepo(log logger.Logger, db *DB) domain.IrcRepo {
return &IrcRepo{
log: log,
db: db,
}
}
func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetwork, error) {
@ -27,10 +31,10 @@ func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error building query")
r.log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error building query")
return nil, err
}
log.Trace().Str("database", "irc.check_existing_network").Msgf("query: '%v', args: '%v'", query, args)
r.log.Trace().Str("database", "irc.check_existing_network").Msgf("query: '%v', args: '%v'", query, args)
var n domain.IrcNetwork
@ -40,7 +44,7 @@ func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw
row := r.db.handler.QueryRowContext(ctx, query, args...)
if err := row.Scan(&n.ID, &n.Enabled, &n.Name, &n.Server, &n.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil {
log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error executing query")
return nil, err
}
@ -67,13 +71,13 @@ func (r *IrcRepo) DeleteNetwork(ctx context.Context, id int64) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query")
r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query")
return err
}
_, err = tx.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query")
return err
}
@ -83,19 +87,19 @@ func (r *IrcRepo) DeleteNetwork(ctx context.Context, id int64) error {
netQuery, netArgs, err := netQueryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query")
r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query")
return err
}
_, err = tx.ExecContext(ctx, netQuery, netArgs...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query")
return err
}
err = tx.Commit()
if err != nil {
log.Error().Stack().Err(err).Msgf("irc.deleteNetwork: error deleting network %v", id)
r.log.Error().Stack().Err(err).Msgf("irc.deleteNetwork: error deleting network %v", id)
return err
}
@ -111,13 +115,13 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork,
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error building query")
r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error building query")
return nil, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error executing query")
return nil, err
}
@ -132,7 +136,7 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork,
var tls sql.NullBool
if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil {
log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error scanning row")
r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error scanning row")
return nil, err
}
@ -146,7 +150,7 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork,
networks = append(networks, net)
}
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: row error")
r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: row error")
return nil, err
}
@ -161,13 +165,13 @@ func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.listNetworks: error building query")
r.log.Error().Stack().Err(err).Msg("irc.listNetworks: error building query")
return nil, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.listNetworks: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.listNetworks: error executing query")
return nil, err
}
@ -182,7 +186,7 @@ func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
var tls sql.NullBool
if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil {
log.Error().Stack().Err(err).Msg("irc.listNetworks: error scanning row")
r.log.Error().Stack().Err(err).Msg("irc.listNetworks: error scanning row")
return nil, err
}
@ -196,7 +200,7 @@ func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
networks = append(networks, net)
}
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err).Msg("irc.listNetworks: row error")
r.log.Error().Stack().Err(err).Msg("irc.listNetworks: row error")
return nil, err
}
@ -211,13 +215,13 @@ func (r *IrcRepo) ListChannels(networkID int64) ([]domain.IrcChannel, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.listChannels: error building query")
r.log.Error().Stack().Err(err).Msg("irc.listChannels: error building query")
return nil, err
}
rows, err := r.db.handler.Query(query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.listChannels: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.listChannels: error executing query")
return nil, err
}
defer rows.Close()
@ -228,7 +232,7 @@ func (r *IrcRepo) ListChannels(networkID int64) ([]domain.IrcChannel, error) {
var pass sql.NullString
if err := rows.Scan(&ch.ID, &ch.Name, &ch.Enabled, &pass); err != nil {
log.Error().Stack().Err(err).Msg("irc.listChannels: error scanning row")
r.log.Error().Stack().Err(err).Msg("irc.listChannels: error scanning row")
return nil, err
}
@ -237,7 +241,7 @@ func (r *IrcRepo) ListChannels(networkID int64) ([]domain.IrcChannel, error) {
channels = append(channels, ch)
}
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err).Msg("irc.listChannels: error row")
r.log.Error().Stack().Err(err).Msg("irc.listChannels: error row")
return nil, err
}
@ -253,10 +257,10 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error building query")
r.log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error building query")
return nil, err
}
log.Trace().Str("database", "irc.checkExistingNetwork").Msgf("query: '%v', args: '%v'", query, args)
r.log.Trace().Str("database", "irc.checkExistingNetwork").Msgf("query: '%v', args: '%v'", query, args)
row := r.db.handler.QueryRowContext(ctx, query, args...)
@ -270,7 +274,7 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN
// no result is not an error in our case
return nil, nil
} else if err != nil {
log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error scanning data to struct")
r.log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error scanning data to struct")
return nil, err
}
@ -322,7 +326,7 @@ func (r *IrcRepo) StoreNetwork(network *domain.IrcNetwork) error {
err = queryBuilder.QueryRow().Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.storeNetwork: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.storeNetwork: error executing query")
return errors.Wrap(err, "error executing query")
}
@ -357,14 +361,14 @@ func (r *IrcRepo) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.updateNetwork: error building query")
r.log.Error().Stack().Err(err).Msg("irc.updateNetwork: error building query")
return err
}
// update record
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.updateNetwork: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.updateNetwork: error executing query")
return err
}
@ -387,13 +391,13 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query")
r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query")
return err
}
_, err = tx.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query")
return err
}
@ -425,7 +429,7 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha
err = channelQueryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query")
return errors.Wrap(err, "error executing query")
}
@ -433,13 +437,13 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha
//channelQuery, channelArgs, err := channelQueryBuilder.ToSql()
//if err != nil {
// log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query")
// r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query")
// return err
//}
//
//res, err = r.db.handler.ExecContext(ctx, channelQuery, channelArgs...)
//if err != nil {
// log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query")
// r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query")
// return err
//}
//
@ -448,7 +452,7 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha
err = tx.Commit()
if err != nil {
log.Error().Stack().Err(err).Msgf("irc.storeNetworkChannels: error deleting network: %v", networkID)
r.log.Error().Stack().Err(err).Msgf("irc.storeNetworkChannels: error deleting network: %v", networkID)
return err
}
@ -471,13 +475,13 @@ func (r *IrcRepo) StoreChannel(networkID int64, channel *domain.IrcChannel) erro
query, args, err := channelQueryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query")
r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query")
return err
}
_, err = r.db.handler.Exec(query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query")
return err
}
} else {
@ -505,7 +509,7 @@ func (r *IrcRepo) StoreChannel(networkID int64, channel *domain.IrcChannel) erro
err = queryBuilder.QueryRow().Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.storeChannels: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.storeChannels: error executing query")
return errors.Wrap(err, "error executing query")
}
@ -513,13 +517,13 @@ func (r *IrcRepo) StoreChannel(networkID int64, channel *domain.IrcChannel) erro
//channelQuery, channelArgs, err := channelQueryBuilder.ToSql()
//if err != nil {
// log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query")
// r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query")
// return err
//}
//
//res, err := r.db.handler.Exec(channelQuery, channelArgs...)
//if err != nil {
// log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query")
// r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query")
// return errors.Wrap(err, "error executing query")
// //return err
//}
@ -544,13 +548,13 @@ func (r *IrcRepo) UpdateChannel(channel *domain.IrcChannel) error {
query, args, err := channelQueryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("irc.updateChannel: error building query")
r.log.Error().Stack().Err(err).Msg("irc.updateChannel: error building query")
return err
}
_, err = r.db.handler.Exec(query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("irc.updateChannel: error executing query")
r.log.Error().Stack().Err(err).Msg("irc.updateChannel: error executing query")
return err
}

View file

@ -3,20 +3,23 @@ package database
import (
"context"
"database/sql"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/rs/zerolog/log"
)
type NotificationRepo struct {
db *DB
log logger.Logger
db *DB
}
func NewNotificationRepo(db *DB) domain.NotificationRepo {
func NewNotificationRepo(log logger.Logger, db *DB) domain.NotificationRepo {
return &NotificationRepo{
db: db,
log: log,
db: db,
}
}
@ -29,13 +32,13 @@ func (r *NotificationRepo) Find(ctx context.Context, params domain.NotificationQ
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("notification.find: error building query")
r.log.Error().Stack().Err(err).Msg("notification.find: error building query")
return nil, 0, err
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("notification.find: error executing query")
r.log.Error().Stack().Err(err).Msg("notification.find: error executing query")
return nil, 0, err
}
@ -51,7 +54,7 @@ func (r *NotificationRepo) Find(ctx context.Context, params domain.NotificationQ
//if err := rows.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &token, &apiKey, &webhook, &title, &icon, &host, &username, &password, &channel, &targets, &devices, &n.CreatedAt, &n.UpdatedAt); err != nil {
//var token, apiKey, webhook, title, icon, host, username, password, channel, targets, devices sql.NullString
if err := rows.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &webhook, &n.CreatedAt, &n.UpdatedAt, &totalCount); err != nil {
log.Error().Stack().Err(err).Msg("notification.find: error scanning row")
r.log.Error().Stack().Err(err).Msg("notification.find: error scanning row")
return nil, 0, err
}
@ -87,7 +90,7 @@ func (r *NotificationRepo) List(ctx context.Context) ([]domain.Notification, err
rows, err := r.db.handler.QueryContext(ctx, "SELECT id, name, type, enabled, events, token, api_key, webhook, title, icon, host, username, password, channel, targets, devices, created_at, updated_at FROM notification ORDER BY name ASC")
if err != nil {
log.Error().Stack().Err(err).Msg("filters_list: error query data")
r.log.Error().Stack().Err(err).Msg("filters_list: error query data")
return nil, err
}
@ -100,7 +103,7 @@ func (r *NotificationRepo) List(ctx context.Context) ([]domain.Notification, err
var token, apiKey, webhook, title, icon, host, username, password, channel, targets, devices sql.NullString
if err := rows.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &token, &apiKey, &webhook, &title, &icon, &host, &username, &password, &channel, &targets, &devices, &n.CreatedAt, &n.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msg("notification_list: error scanning data to struct")
r.log.Error().Stack().Err(err).Msg("notification_list: error scanning data to struct")
return nil, err
}
@ -144,7 +147,7 @@ func (r *NotificationRepo) FindByID(ctx context.Context, id int) (*domain.Notifi
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("notification.findByID: error building query")
r.log.Error().Stack().Err(err).Msg("notification.findByID: error building query")
return nil, err
}
@ -158,7 +161,7 @@ func (r *NotificationRepo) FindByID(ctx context.Context, id int) (*domain.Notifi
var token, apiKey, webhook, title, icon, host, username, password, channel, targets, devices sql.NullString
if err := row.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &token, &apiKey, &webhook, &title, &icon, &host, &username, &password, &channel, &targets, &devices, &n.CreatedAt, &n.UpdatedAt); err != nil {
log.Error().Stack().Err(err).Msg("notification.findByID: error scanning row")
r.log.Error().Stack().Err(err).Msg("notification.findByID: error scanning row")
return nil, err
}
@ -203,11 +206,11 @@ func (r *NotificationRepo) Store(ctx context.Context, notification domain.Notifi
err := queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("notification.store: error executing query")
r.log.Error().Stack().Err(err).Msg("notification.store: error executing query")
return nil, err
}
log.Debug().Msgf("notification.store: added new %v", retID)
r.log.Debug().Msgf("notification.store: added new %v", retID)
notification.ID = int(retID)
return &notification, nil
@ -228,17 +231,17 @@ func (r *NotificationRepo) Update(ctx context.Context, notification domain.Notif
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("action.update: error building query")
r.log.Error().Stack().Err(err).Msg("action.update: error building query")
return nil, err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("notification.update: error executing query")
r.log.Error().Stack().Err(err).Msg("notification.update: error executing query")
return nil, err
}
log.Debug().Msgf("notification.update: %v", notification.Name)
r.log.Debug().Msgf("notification.update: %v", notification.Name)
return &notification, nil
}
@ -250,17 +253,17 @@ func (r *NotificationRepo) Delete(ctx context.Context, notificationID int) error
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("notification.delete: error building query")
r.log.Error().Stack().Err(err).Msg("notification.delete: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("notification.delete: error executing query")
r.log.Error().Stack().Err(err).Msg("notification.delete: error executing query")
return err
}
log.Info().Msgf("notification.delete: successfully deleted: %v", notificationID)
r.log.Info().Msgf("notification.delete: successfully deleted: %v", notificationID)
return nil
}

View file

@ -6,7 +6,6 @@ import (
"fmt"
_ "github.com/lib/pq"
"github.com/rs/zerolog/log"
)
func (db *DB) openPostgres() error {
@ -14,19 +13,19 @@ func (db *DB) openPostgres() error {
// open database connection
if db.handler, err = sql.Open("postgres", db.DSN); err != nil {
log.Fatal().Err(err).Msg("could not open postgres connection")
db.log.Fatal().Err(err).Msg("could not open postgres connection")
return err
}
err = db.handler.Ping()
if err != nil {
log.Fatal().Err(err).Msg("could not ping postgres database")
db.log.Fatal().Err(err).Msg("could not ping postgres database")
return err
}
// migrate db
if err = db.migratePostgres(); err != nil {
log.Fatal().Err(err).Msg("could not migrate postgres database")
db.log.Fatal().Err(err).Msg("could not migrate postgres database")
return err
}

View file

@ -5,18 +5,23 @@ import (
"database/sql"
"strings"
sq "github.com/Masterminds/squirrel"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
sq "github.com/Masterminds/squirrel"
"github.com/lib/pq"
"github.com/rs/zerolog/log"
)
type ReleaseRepo struct {
db *DB
log logger.Logger
db *DB
}
func NewReleaseRepo(db *DB) domain.ReleaseRepo {
return &ReleaseRepo{db: db}
func NewReleaseRepo(log logger.Logger, db *DB) domain.ReleaseRepo {
return &ReleaseRepo{
log: log,
db: db,
}
}
func (repo *ReleaseRepo) Store(ctx context.Context, r *domain.Release) (*domain.Release, error) {
@ -34,13 +39,13 @@ func (repo *ReleaseRepo) Store(ctx context.Context, r *domain.Release) (*domain.
err := queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("release.store: error executing query")
repo.log.Error().Stack().Err(err).Msg("release.store: error executing query")
return nil, err
}
r.ID = retID
log.Debug().Msgf("release.store: %+v", r)
repo.log.Debug().Msgf("release.store: %+v", r)
return r, nil
}
@ -57,13 +62,13 @@ func (repo *ReleaseRepo) StoreReleaseActionStatus(ctx context.Context, a *domain
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("release.store: error building query")
repo.log.Error().Stack().Err(err).Msg("release.store: error building query")
return err
}
_, err = repo.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error updating status of release")
repo.log.Error().Stack().Err(err).Msg("error updating status of release")
return err
}
@ -79,14 +84,14 @@ func (repo *ReleaseRepo) StoreReleaseActionStatus(ctx context.Context, a *domain
err := queryBuilder.QueryRowContext(ctx).Scan(&retID)
if err != nil {
log.Error().Stack().Err(err).Msg("release.storeReleaseActionStatus: error executing query")
repo.log.Error().Stack().Err(err).Msg("release.storeReleaseActionStatus: error executing query")
return err
}
a.ID = retID
}
log.Trace().Msgf("release.store_release_action_status: %+v", a)
repo.log.Trace().Msgf("release.store_release_action_status: %+v", a)
return nil
}
@ -148,20 +153,20 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain
}
query, args, err := queryBuilder.ToSql()
log.Trace().Str("database", "release.find").Msgf("query: '%v', args: '%v'", query, args)
repo.log.Trace().Str("database", "release.find").Msgf("query: '%v', args: '%v'", query, args)
res := make([]*domain.Release, 0)
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error fetching releases")
repo.log.Error().Stack().Err(err).Msg("error fetching releases")
return res, 0, 0, nil
}
defer rows.Close()
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err)
repo.log.Error().Stack().Err(err)
return res, 0, 0, err
}
@ -173,7 +178,7 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain
var indexer, filter sql.NullString
if err := rows.Scan(&rls.ID, &rls.FilterStatus, pq.Array(&rls.Rejections), &indexer, &filter, &rls.Protocol, &rls.Title, &rls.TorrentName, &rls.Size, &rls.Timestamp, &countItems); err != nil {
log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
return res, 0, 0, err
}
@ -196,20 +201,20 @@ func (repo *ReleaseRepo) GetIndexerOptions(ctx context.Context) ([]string, error
query := `SELECT DISTINCT indexer FROM "release" UNION SELECT DISTINCT identifier indexer FROM indexer;`
log.Trace().Str("database", "release.get_indexers").Msgf("query: '%v'", query)
repo.log.Trace().Str("database", "release.get_indexers").Msgf("query: '%v'", query)
res := make([]string, 0)
rows, err := repo.db.handler.QueryContext(ctx, query)
if err != nil {
log.Error().Stack().Err(err).Msg("error fetching indexer list")
repo.log.Error().Stack().Err(err).Msg("error fetching indexer list")
return res, err
}
defer rows.Close()
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err)
repo.log.Error().Stack().Err(err)
return res, err
}
@ -217,7 +222,7 @@ func (repo *ReleaseRepo) GetIndexerOptions(ctx context.Context) ([]string, error
var indexer string
if err := rows.Scan(&indexer); err != nil {
log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
return res, err
}
@ -240,14 +245,14 @@ func (repo *ReleaseRepo) GetActionStatusByReleaseID(ctx context.Context, release
rows, err := repo.db.handler.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error fetching releases")
repo.log.Error().Stack().Err(err).Msg("error fetching releases")
return res, nil
}
defer rows.Close()
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err)
repo.log.Error().Stack().Err(err)
return res, err
}
@ -255,7 +260,7 @@ func (repo *ReleaseRepo) GetActionStatusByReleaseID(ctx context.Context, release
var rls domain.ReleaseActionStatus
if err := rows.Scan(&rls.ID, &rls.Status, &rls.Action, &rls.Type, pq.Array(&rls.Rejections), &rls.Timestamp); err != nil {
log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
return res, err
}
@ -278,14 +283,14 @@ func (repo *ReleaseRepo) attachActionStatus(ctx context.Context, tx *Tx, release
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("error fetching releases")
repo.log.Error().Stack().Err(err).Msg("error fetching releases")
return res, nil
}
defer rows.Close()
if err := rows.Err(); err != nil {
log.Error().Stack().Err(err)
repo.log.Error().Stack().Err(err)
return res, err
}
@ -293,7 +298,7 @@ func (repo *ReleaseRepo) attachActionStatus(ctx context.Context, tx *Tx, release
var rls domain.ReleaseActionStatus
if err := rows.Scan(&rls.ID, &rls.Status, &rls.Action, &rls.Type, pq.Array(&rls.Rejections), &rls.Timestamp); err != nil {
log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct")
return res, err
}
@ -316,14 +321,14 @@ FROM "release";`
row := repo.db.handler.QueryRowContext(ctx, query)
if err := row.Err(); err != nil {
log.Error().Stack().Err(err).Msg("release.stats: error querying stats")
repo.log.Error().Stack().Err(err).Msg("release.stats: error querying stats")
return nil, err
}
var rls domain.ReleaseStats
if err := row.Scan(&rls.TotalCount, &rls.FilteredCount, &rls.FilterRejectedCount, &rls.PushApprovedCount, &rls.PushRejectedCount); err != nil {
log.Error().Stack().Err(err).Msg("release.stats: error scanning stats data to struct")
repo.log.Error().Stack().Err(err).Msg("release.stats: error scanning stats data to struct")
return nil, err
}
@ -340,19 +345,19 @@ func (repo *ReleaseRepo) Delete(ctx context.Context) error {
_, err = tx.ExecContext(ctx, `DELETE FROM "release"`)
if err != nil {
log.Error().Stack().Err(err).Msg("error deleting all releases")
repo.log.Error().Stack().Err(err).Msg("error deleting all releases")
return err
}
_, err = tx.ExecContext(ctx, `DELETE FROM release_action_status`)
if err != nil {
log.Error().Stack().Err(err).Msg("error deleting all release_action_status")
repo.log.Error().Stack().Err(err).Msg("error deleting all release_action_status")
return err
}
err = tx.Commit()
if err != nil {
log.Error().Stack().Err(err).Msg("error deleting all releases")
repo.log.Error().Stack().Err(err).Msg("error deleting all releases")
return err
}

View file

@ -5,7 +5,6 @@ import (
"fmt"
"github.com/lib/pq"
"github.com/rs/zerolog/log"
_ "modernc.org/sqlite"
)
@ -18,7 +17,7 @@ func (db *DB) openSQLite() error {
// open database connection
if db.handler, err = sql.Open("sqlite", db.DSN+"?_pragma=busy_timeout%3d1000"); err != nil {
log.Fatal().Err(err).Msg("could not open db connection")
db.log.Fatal().Err(err).Msg("could not open db connection")
return err
}
@ -42,7 +41,7 @@ func (db *DB) openSQLite() error {
// migrate db
if err = db.migrateSQLite(); err != nil {
log.Fatal().Err(err).Msg("could not migrate db")
db.log.Fatal().Err(err).Msg("could not migrate db")
return err
}

View file

@ -2,17 +2,20 @@ package database
import (
"context"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
)
type UserRepo struct {
db *DB
log logger.Logger
db *DB
}
func NewUserRepo(db *DB) domain.UserRepo {
return &UserRepo{db: db}
func NewUserRepo(log logger.Logger, db *DB) domain.UserRepo {
return &UserRepo{
log: log,
db: db,
}
}
func (r *UserRepo) GetUserCount(ctx context.Context) (int, error) {
@ -20,7 +23,7 @@ func (r *UserRepo) GetUserCount(ctx context.Context) (int, error) {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("user.store: error building query")
r.log.Error().Stack().Err(err).Msg("user.store: error building query")
return 0, err
}
@ -31,7 +34,7 @@ func (r *UserRepo) GetUserCount(ctx context.Context) (int, error) {
result := 0
if err := row.Scan(&result); err != nil {
log.Error().Err(err).Msg("could not query number of users")
r.log.Error().Err(err).Msg("could not query number of users")
return 0, err
}
@ -47,7 +50,7 @@ func (r *UserRepo) FindByUsername(ctx context.Context, username string) (*domain
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("user.store: error building query")
r.log.Error().Stack().Err(err).Msg("user.store: error building query")
return nil, err
}
@ -59,7 +62,7 @@ func (r *UserRepo) FindByUsername(ctx context.Context, username string) (*domain
var user domain.User
if err := row.Scan(&user.ID, &user.Username, &user.Password); err != nil {
log.Error().Err(err).Msg("could not scan user to struct")
r.log.Error().Err(err).Msg("could not scan user to struct")
return nil, err
}
@ -77,13 +80,13 @@ func (r *UserRepo) Store(ctx context.Context, user domain.User) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("user.store: error building query")
r.log.Error().Stack().Err(err).Msg("user.store: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("user.store: error executing query")
r.log.Error().Stack().Err(err).Msg("user.store: error executing query")
return err
}
@ -102,13 +105,13 @@ func (r *UserRepo) Update(ctx context.Context, user domain.User) error {
query, args, err := queryBuilder.ToSql()
if err != nil {
log.Error().Stack().Err(err).Msg("user.store: error building query")
r.log.Error().Stack().Err(err).Msg("user.store: error building query")
return err
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
log.Error().Stack().Err(err).Msg("user.store: error executing query")
r.log.Error().Stack().Err(err).Msg("user.store: error executing query")
return err
}

View file

@ -1,6 +1,7 @@
package domain
type Config struct {
Version string
ConfigPath string
Host string `toml:"host"`
Port int `toml:"port"`

View file

@ -3,11 +3,11 @@ package domain
import (
"bytes"
"context"
"errors"
"net/url"
"text/template"
"github.com/dustin/go-humanize"
"github.com/rs/zerolog/log"
)
type IndexerRepo interface {
@ -148,15 +148,13 @@ func (p *IndexerParse) ParseTorrentUrl(vars map[string]string, extraVars map[str
// setup text template to inject variables into
tmpl, err := template.New("torrenturl").Parse(p.Match.TorrentURL)
if err != nil {
log.Error().Err(err).Msg("could not create torrent url template")
return err
return errors.New("could not create torrent url template")
}
var urlBytes bytes.Buffer
err = tmpl.Execute(&urlBytes, &tmpVars)
if err != nil {
log.Error().Err(err).Msg("could not write torrent url template output")
return err
return errors.New("could not write torrent url template output")
}
release.TorrentURL = urlBytes.String()

View file

@ -20,7 +20,6 @@ import (
"github.com/dustin/go-humanize"
"github.com/moistari/rls"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
type ReleaseRepo interface {
@ -274,8 +273,7 @@ func (r *Release) DownloadTorrentFile() error {
req, err := http.NewRequest("GET", r.TorrentURL, nil)
if err != nil {
log.Error().Stack().Err(err).Msg("error downloading file")
return err
return errors.Wrap(err, "error downloading file")
}
if r.RawCookie != "" {
@ -287,43 +285,37 @@ func (r *Release) DownloadTorrentFile() error {
// Get the data
resp, err := client.Do(req)
if err != nil {
log.Error().Stack().Err(err).Msg("error downloading file")
return err
return errors.Wrap(err, "error downloading file")
}
defer resp.Body.Close()
// retry logic
if resp.StatusCode != http.StatusOK {
log.Error().Stack().Err(err).Msgf("error downloading file from: %v - bad status: %d", r.TorrentURL, resp.StatusCode)
return fmt.Errorf("error downloading torrent (%v) file (%v) from '%v' - status code: %d", r.TorrentName, r.TorrentURL, r.Indexer, resp.StatusCode)
}
// Create tmp file
tmpFile, err := os.CreateTemp("", "autobrr-")
if err != nil {
log.Error().Stack().Err(err).Msg("error creating temp file")
return err
return errors.Wrap(err, "error creating tmp file")
}
defer tmpFile.Close()
// Write the body to file
_, err = io.Copy(tmpFile, resp.Body)
if err != nil {
log.Error().Stack().Err(err).Msgf("error writing downloaded file: %v", tmpFile.Name())
return err
return errors.Wrap(err, fmt.Sprintf("error writing downloaded file: %v", tmpFile.Name()))
}
meta, err := metainfo.LoadFromFile(tmpFile.Name())
if err != nil {
log.Error().Stack().Err(err).Msgf("metainfo could not load file contents: %v", tmpFile.Name())
return err
return errors.Wrap(err, fmt.Sprintf("metainfo could not load file contents: %v", tmpFile.Name()))
}
torrentMetaInfo, err := meta.UnmarshalInfo()
if err != nil {
log.Error().Stack().Err(err).Msgf("metainfo could not unmarshal info from torrent: %v", tmpFile.Name())
return err
return errors.Wrap(err, fmt.Sprintf("metainfo could not unmarshal info from torrent: %v", tmpFile.Name()))
}
r.TorrentTmpFile = tmpFile.Name()
@ -332,7 +324,7 @@ func (r *Release) DownloadTorrentFile() error {
// remove file if fail
log.Debug().Msgf("successfully downloaded file: %v", tmpFile.Name())
//log.Debug().Msgf("successfully downloaded file: %v", tmpFile.Name())
return nil
}

View file

@ -438,7 +438,7 @@ func TestRelease_MapVars(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := tt.fields
_ = r.MapVars(tt.args.definition, tt.args.varMap)
_ = r.MapVars(&tt.args.definition, tt.args.varMap)
assert.Equal(t, tt.want, r)
})

View file

@ -1,18 +1,19 @@
package download_client
import (
"github.com/autobrr/autobrr/pkg/whisparr"
"github.com/pkg/errors"
"fmt"
"time"
"github.com/pkg/errors"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/lidarr"
"github.com/autobrr/autobrr/pkg/qbittorrent"
"github.com/autobrr/autobrr/pkg/radarr"
"github.com/autobrr/autobrr/pkg/sonarr"
"github.com/autobrr/autobrr/pkg/whisparr"
delugeClient "github.com/gdm85/go-libdeluge"
"github.com/rs/zerolog/log"
)
func (s *service) testConnection(client domain.DownloadClient) error {
@ -52,11 +53,10 @@ func (s *service) testQbittorrentConnection(client domain.DownloadClient) error
qbt := qbittorrent.NewClient(qbtSettings)
err := qbt.Login()
if err != nil {
log.Error().Err(err).Msgf("error logging into client: %v", client.Host)
return err
return errors.Wrap(err, fmt.Sprintf("error logging into client: %v", client.Host))
}
log.Debug().Msgf("test client connection for qBittorrent: success")
s.log.Debug().Msgf("test client connection for qBittorrent: success")
return nil
}
@ -87,8 +87,7 @@ func (s *service) testDelugeConnection(client domain.DownloadClient) error {
// perform connection to Deluge server
err := deluge.Connect()
if err != nil {
log.Error().Err(err).Msgf("error logging into client: %v", client.Host)
return err
return errors.Wrap(err, fmt.Sprintf("error logging into client: %v", client.Host))
}
defer deluge.Close()
@ -96,11 +95,10 @@ func (s *service) testDelugeConnection(client domain.DownloadClient) error {
// print daemon version
ver, err := deluge.DaemonVersion()
if err != nil {
log.Error().Err(err).Msgf("could not get daemon version: %v", client.Host)
return err
return errors.Wrap(err, fmt.Sprintf("could not get daemon version: %v", client.Host))
}
log.Debug().Msgf("test client connection for Deluge: success - daemon version: %v", ver)
s.log.Debug().Msgf("test client connection for Deluge: success - daemon version: %v", ver)
return nil
}
@ -116,11 +114,10 @@ func (s *service) testRadarrConnection(client domain.DownloadClient) error {
_, err := r.Test()
if err != nil {
log.Error().Err(err).Msgf("radarr: connection test failed: %v", client.Host)
return err
return errors.Wrap(err, fmt.Sprintf("radarr: connection test failed: %v", client.Host))
}
log.Debug().Msgf("test client connection for Radarr: success")
s.log.Debug().Msgf("test client connection for Radarr: success")
return nil
}
@ -136,11 +133,10 @@ func (s *service) testSonarrConnection(client domain.DownloadClient) error {
_, err := r.Test()
if err != nil {
log.Error().Err(err).Msgf("sonarr: connection test failed: %v", client.Host)
return err
return errors.Wrap(err, fmt.Sprintf("sonarr: connection test failed: %v", client.Host))
}
log.Debug().Msgf("test client connection for Sonarr: success")
s.log.Debug().Msgf("test client connection for Sonarr: success")
return nil
}
@ -156,11 +152,10 @@ func (s *service) testLidarrConnection(client domain.DownloadClient) error {
_, err := r.Test()
if err != nil {
log.Error().Err(err).Msgf("lidarr: connection test failed: %v", client.Host)
return err
return errors.Wrap(err, fmt.Sprintf("lidarr: connection test failed: %v", client.Host))
}
log.Debug().Msgf("test client connection for Lidarr: success")
s.log.Debug().Msgf("test client connection for Lidarr: success")
return nil
}
@ -176,11 +171,10 @@ func (s *service) testWhisparrConnection(client domain.DownloadClient) error {
_, err := r.Test()
if err != nil {
log.Error().Err(err).Msgf("whisparr: connection test failed: %v", client.Host)
return err
return errors.Wrap(err, fmt.Sprintf("whisparr: connection test failed: %v", client.Host))
}
log.Debug().Msgf("test client connection for whisparr: success")
s.log.Debug().Msgf("test client connection for whisparr: success")
return nil
}

View file

@ -5,6 +5,7 @@ import (
"errors"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
)
type Service interface {
@ -17,11 +18,15 @@ type Service interface {
}
type service struct {
log logger.Logger
repo domain.DownloadClientRepo
}
func NewService(repo domain.DownloadClientRepo) Service {
return &service{repo: repo}
func NewService(log logger.Logger, repo domain.DownloadClientRepo) Service {
return &service{
log: log,
repo: repo,
}
}
func (s *service) List(ctx context.Context) ([]domain.DownloadClient, error) {
@ -69,5 +74,10 @@ func (s *service) Test(client domain.DownloadClient) error {
}
// test
return s.testConnection(client)
if err := s.testConnection(client); err != nil {
s.log.Err(err).Msg("client connection test error")
return err
}
return nil
}

View file

@ -4,21 +4,23 @@ import (
"context"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/notification"
"github.com/autobrr/autobrr/internal/release"
"github.com/asaskevich/EventBus"
"github.com/rs/zerolog/log"
)
type Subscriber struct {
log logger.Logger
eventbus EventBus.Bus
notificationSvc notification.Service
releaseSvc release.Service
}
func NewSubscribers(eventbus EventBus.Bus, notificationSvc notification.Service, releaseSvc release.Service) Subscriber {
func NewSubscribers(log logger.Logger, eventbus EventBus.Bus, notificationSvc notification.Service, releaseSvc release.Service) Subscriber {
s := Subscriber{
log: log,
eventbus: eventbus,
notificationSvc: notificationSvc,
releaseSvc: releaseSvc,
@ -36,26 +38,26 @@ func (s Subscriber) Register() {
}
func (s Subscriber) releaseActionStatus(actionStatus *domain.ReleaseActionStatus) {
log.Trace().Msgf("events: 'release:store-action-status' '%+v'", actionStatus)
s.log.Trace().Msgf("events: 'release:store-action-status' '%+v'", actionStatus)
err := s.releaseSvc.StoreReleaseActionStatus(context.Background(), actionStatus)
if err != nil {
log.Error().Err(err).Msgf("events: 'release:store-action-status' error")
s.log.Error().Err(err).Msgf("events: 'release:store-action-status' error")
}
}
func (s Subscriber) releasePushStatus(actionStatus *domain.ReleaseActionStatus) {
log.Trace().Msgf("events: 'release:push' '%+v'", actionStatus)
s.log.Trace().Msgf("events: 'release:push' '%+v'", actionStatus)
if err := s.releaseSvc.StoreReleaseActionStatus(context.Background(), actionStatus); err != nil {
log.Error().Err(err).Msgf("events: 'release:push' error")
s.log.Error().Err(err).Msgf("events: 'release:push' error")
}
}
func (s Subscriber) releasePush(event *domain.EventsReleasePushed) {
log.Trace().Msgf("events: 'events:release:push' '%+v'", event)
s.log.Trace().Msgf("events: 'events:release:push' '%+v'", event)
if err := s.notificationSvc.SendEvent(*event); err != nil {
log.Error().Err(err).Msgf("events: 'events:release:push' error sending notification")
s.log.Error().Err(err).Msgf("events: 'events:release:push' error sending notification")
}
}

View file

@ -6,11 +6,10 @@ import (
"fmt"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/release"
"github.com/autobrr/autobrr/internal/scheduler"
"github.com/autobrr/autobrr/pkg/torznab"
"github.com/rs/zerolog/log"
)
type Service interface {
@ -35,6 +34,7 @@ type feedInstance struct {
}
type service struct {
log logger.Logger
jobs map[string]int
repo domain.FeedRepo
@ -43,8 +43,9 @@ type service struct {
scheduler scheduler.Service
}
func NewService(repo domain.FeedRepo, cacheRepo domain.FeedCacheRepo, releaseSvc release.Service, scheduler scheduler.Service) Service {
func NewService(log logger.Logger, repo domain.FeedRepo, cacheRepo domain.FeedCacheRepo, releaseSvc release.Service, scheduler scheduler.Service) Service {
return &service{
log: log,
jobs: map[string]int{},
repo: repo,
cacheRepo: cacheRepo,
@ -83,12 +84,12 @@ func (s *service) ToggleEnabled(ctx context.Context, id int, enabled bool) error
func (s *service) update(ctx context.Context, feed *domain.Feed) error {
if err := s.repo.Update(ctx, feed); err != nil {
log.Error().Err(err).Msg("feed.Update: error updating feed")
s.log.Error().Err(err).Msg("feed.Update: error updating feed")
return err
}
if err := s.restartJob(feed); err != nil {
log.Error().Err(err).Msg("feed.Update: error restarting feed")
s.log.Error().Err(err).Msg("feed.Update: error restarting feed")
return err
}
@ -98,54 +99,54 @@ func (s *service) update(ctx context.Context, feed *domain.Feed) error {
func (s *service) delete(ctx context.Context, id int) error {
f, err := s.repo.FindByID(ctx, id)
if err != nil {
log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed")
s.log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed")
return err
}
if err := s.stopTorznabJob(f.Indexer); err != nil {
log.Error().Err(err).Msg("feed.Delete: error stopping torznab job")
s.log.Error().Err(err).Msg("feed.Delete: error stopping torznab job")
return err
}
if err := s.repo.Delete(ctx, id); err != nil {
log.Error().Err(err).Msg("feed.Delete: error deleting feed")
s.log.Error().Err(err).Msg("feed.Delete: error deleting feed")
return err
}
log.Debug().Msgf("feed.Delete: stopping and removing feed: %v", f.Name)
s.log.Debug().Msgf("feed.Delete: stopping and removing feed: %v", f.Name)
return nil
}
func (s *service) toggleEnabled(ctx context.Context, id int, enabled bool) error {
if err := s.repo.ToggleEnabled(ctx, id, enabled); err != nil {
log.Error().Err(err).Msg("feed.ToggleEnabled: error toggle enabled")
s.log.Error().Err(err).Msg("feed.ToggleEnabled: error toggle enabled")
return err
}
f, err := s.repo.FindByID(ctx, id)
if err != nil {
log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed")
s.log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed")
return err
}
if !enabled {
if err := s.stopTorznabJob(f.Indexer); err != nil {
log.Error().Err(err).Msg("feed.ToggleEnabled: error stopping torznab job")
s.log.Error().Err(err).Msg("feed.ToggleEnabled: error stopping torznab job")
return err
}
log.Debug().Msgf("feed.ToggleEnabled: stopping feed: %v", f.Name)
s.log.Debug().Msgf("feed.ToggleEnabled: stopping feed: %v", f.Name)
return nil
}
if err := s.startJob(*f); err != nil {
log.Error().Err(err).Msg("feed.ToggleEnabled: error starting torznab job")
s.log.Error().Err(err).Msg("feed.ToggleEnabled: error starting torznab job")
return err
}
log.Debug().Msgf("feed.ToggleEnabled: started feed: %v", f.Name)
s.log.Debug().Msgf("feed.ToggleEnabled: started feed: %v", f.Name)
return nil
}
@ -154,13 +155,13 @@ func (s *service) Start() error {
// get all torznab indexer definitions
feeds, err := s.repo.Find(context.TODO())
if err != nil {
log.Error().Err(err).Msg("feed.Start: error getting feeds")
s.log.Error().Err(err).Msg("feed.Start: error getting feeds")
return err
}
for _, i := range feeds {
if err := s.startJob(i); err != nil {
log.Error().Err(err).Msg("feed.Start: failed to initialize torznab job")
s.log.Error().Err(err).Msg("feed.Start: failed to initialize torznab job")
continue
}
}
@ -171,19 +172,19 @@ func (s *service) Start() error {
func (s *service) restartJob(f *domain.Feed) error {
// stop feed
if err := s.stopTorznabJob(f.Indexer); err != nil {
log.Error().Err(err).Msg("feed.restartJob: error stopping torznab job")
s.log.Error().Err(err).Msg("feed.restartJob: error stopping torznab job")
return err
}
log.Debug().Msgf("feed.restartJob: stopping feed: %v", f.Name)
s.log.Debug().Msgf("feed.restartJob: stopping feed: %v", f.Name)
if f.Enabled {
if err := s.startJob(*f); err != nil {
log.Error().Err(err).Msg("feed.restartJob: error starting torznab job")
s.log.Error().Err(err).Msg("feed.restartJob: error starting torznab job")
return err
}
log.Debug().Msgf("feed.restartJob: restarted feed: %v", f.Name)
s.log.Debug().Msgf("feed.restartJob: restarted feed: %v", f.Name)
}
return nil
@ -215,7 +216,7 @@ func (s *service) startJob(f domain.Feed) error {
switch fi.Implementation {
case string(domain.FeedTypeTorznab):
if err := s.addTorznabJob(fi); err != nil {
log.Error().Err(err).Msg("feed.startJob: failed to initialize feed")
s.log.Error().Err(err).Msg("feed.startJob: failed to initialize feed")
return err
}
//case "rss":
@ -234,7 +235,7 @@ func (s *service) addTorznabJob(f feedInstance) error {
}
// setup logger
l := log.With().Str("feed_name", f.Name).Logger()
l := s.log.With().Str("feed_name", f.Name).Logger()
// setup torznab Client
c := torznab.NewClient(f.URL, f.ApiKey)
@ -260,7 +261,7 @@ func (s *service) addTorznabJob(f feedInstance) error {
// add to job map
s.jobs[f.IndexerIdentifier] = id
log.Debug().Msgf("feed.AddTorznabJob: %v", f.Name)
s.log.Debug().Msgf("feed.AddTorznabJob: %v", f.Name)
return nil
}
@ -271,7 +272,7 @@ func (s *service) stopTorznabJob(indexer string) error {
return fmt.Errorf("feed.stopTorznabJob: stop job failed: %w", err)
}
log.Debug().Msgf("feed.stopTorznabJob: %v", indexer)
s.log.Debug().Msgf("feed.stopTorznabJob: %v", indexer)
return nil
}

View file

@ -5,11 +5,11 @@ import (
"sort"
"time"
"github.com/rs/zerolog"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/release"
"github.com/autobrr/autobrr/pkg/torznab"
"github.com/rs/zerolog"
)
type TorznabJob struct {

View file

@ -5,11 +5,11 @@ import (
"errors"
"fmt"
"github.com/dustin/go-humanize"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/indexer"
"github.com/autobrr/autobrr/internal/logger"
"github.com/dustin/go-humanize"
)
type Service interface {
@ -25,14 +25,16 @@ type Service interface {
}
type service struct {
log logger.Logger
repo domain.FilterRepo
actionRepo domain.ActionRepo
indexerSvc indexer.Service
apiService indexer.APIService
}
func NewService(repo domain.FilterRepo, actionRepo domain.ActionRepo, apiService indexer.APIService, indexerSvc indexer.Service) Service {
func NewService(log logger.Logger, repo domain.FilterRepo, actionRepo domain.ActionRepo, apiService indexer.APIService, indexerSvc indexer.Service) Service {
return &service{
log: log,
repo: repo,
actionRepo: actionRepo,
apiService: apiService,
@ -72,14 +74,14 @@ func (s *service) FindByID(ctx context.Context, filterID int) (*domain.Filter, e
// find actions and attach
actions, err := s.actionRepo.FindByFilterID(ctx, filter.ID)
if err != nil {
log.Error().Msgf("could not find filter actions: %+v", &filter.ID)
s.log.Error().Msgf("could not find filter actions: %+v", &filter.ID)
}
filter.Actions = actions
// find indexers and attach
indexers, err := s.indexerSvc.FindByFilterID(ctx, filter.ID)
if err != nil {
log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &filter.Name)
s.log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &filter.Name)
return nil, err
}
filter.Indexers = indexers
@ -91,7 +93,7 @@ func (s *service) FindByIndexerIdentifier(indexer string) ([]domain.Filter, erro
// get filters for indexer
filters, err := s.repo.FindByIndexerIdentifier(indexer)
if err != nil {
log.Error().Err(err).Msgf("could not find filters for indexer: %v", indexer)
s.log.Error().Err(err).Msgf("could not find filters for indexer: %v", indexer)
return nil, err
}
@ -104,7 +106,7 @@ func (s *service) Store(ctx context.Context, filter domain.Filter) (*domain.Filt
// store
f, err := s.repo.Store(ctx, filter)
if err != nil {
log.Error().Err(err).Msgf("could not store filter: %v", filter)
s.log.Error().Err(err).Msgf("could not store filter: %v", filter)
return nil, err
}
@ -120,20 +122,20 @@ func (s *service) Update(ctx context.Context, filter domain.Filter) (*domain.Fil
// update
f, err := s.repo.Update(ctx, filter)
if err != nil {
log.Error().Err(err).Msgf("could not update filter: %v", filter.Name)
s.log.Error().Err(err).Msgf("could not update filter: %v", filter.Name)
return nil, err
}
// take care of connected indexers
if err = s.repo.StoreIndexerConnections(ctx, f.ID, filter.Indexers); err != nil {
log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name)
s.log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name)
return nil, err
}
// take care of filter actions
actions, err := s.actionRepo.StoreFilterActions(ctx, filter.Actions, int64(filter.ID))
if err != nil {
log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name)
s.log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name)
return nil, err
}
@ -155,27 +157,27 @@ func (s *service) Duplicate(ctx context.Context, filterID int) (*domain.Filter,
// find actions and attach
filterActions, err := s.actionRepo.FindByFilterID(ctx, filterID)
if err != nil {
log.Error().Msgf("could not find filter actions: %+v", &filterID)
s.log.Error().Msgf("could not find filter actions: %+v", &filterID)
return nil, err
}
// find indexers and attach
filterIndexers, err := s.indexerSvc.FindByFilterID(ctx, filterID)
if err != nil {
log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &baseFilter.Name)
s.log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &baseFilter.Name)
return nil, err
}
// update
filter, err := s.repo.Store(ctx, *baseFilter)
if err != nil {
log.Error().Err(err).Msgf("could not update filter: %v", baseFilter.Name)
s.log.Error().Err(err).Msgf("could not update filter: %v", baseFilter.Name)
return nil, err
}
// take care of connected indexers
if err = s.repo.StoreIndexerConnections(ctx, filter.ID, filterIndexers); err != nil {
log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name)
s.log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name)
return nil, err
}
filter.Indexers = filterIndexers
@ -183,7 +185,7 @@ func (s *service) Duplicate(ctx context.Context, filterID int) (*domain.Filter,
// take care of filter actions
actions, err := s.actionRepo.StoreFilterActions(ctx, filterActions, int64(filter.ID))
if err != nil {
log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name)
s.log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name)
return nil, err
}
@ -194,11 +196,11 @@ func (s *service) Duplicate(ctx context.Context, filterID int) (*domain.Filter,
func (s *service) ToggleEnabled(ctx context.Context, filterID int, enabled bool) error {
if err := s.repo.ToggleEnabled(ctx, filterID, enabled); err != nil {
log.Error().Err(err).Msg("could not update filter enabled")
s.log.Error().Err(err).Msg("could not update filter enabled")
return err
}
log.Debug().Msgf("filter.toggle_enabled: update filter '%v' to '%v'", filterID, enabled)
s.log.Debug().Msgf("filter.toggle_enabled: update filter '%v' to '%v'", filterID, enabled)
return nil
}
@ -210,19 +212,19 @@ func (s *service) Delete(ctx context.Context, filterID int) error {
// take care of filter actions
if err := s.actionRepo.DeleteByFilterID(ctx, filterID); err != nil {
log.Error().Err(err).Msg("could not delete filter actions")
s.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")
s.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)
s.log.Error().Err(err).Msgf("could not delete filter: %v", filterID)
return err
}
@ -231,19 +233,19 @@ func (s *service) Delete(ctx context.Context, filterID int) error {
func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, error) {
log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v %+v", f.Name, f)
log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v for release: %+v", f.Name, release)
s.log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v %+v", f.Name, f)
s.log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v for release: %+v", f.Name, release)
rejections, matchedFilter := f.CheckFilter(release)
if len(rejections) > 0 {
log.Trace().Msgf("filter.Service.CheckFilter: (%v) for release: %v rejections: (%v)", f.Name, release.TorrentName, release.RejectionsString())
s.log.Trace().Msgf("filter.Service.CheckFilter: (%v) for release: %v rejections: (%v)", f.Name, release.TorrentName, release.RejectionsString())
return false, nil
}
if matchedFilter {
// if matched, do additional size check if needed, attach actions and return the filter
log.Debug().Msgf("filter.Service.CheckFilter: found and matched filter: %+v", f.Name)
s.log.Debug().Msgf("filter.Service.CheckFilter: found and matched filter: %+v", f.Name)
// Some indexers do not announce the size and if size (min,max) is set in a filter then it will need
// additional size check. Some indexers have api implemented to fetch this data and for the others
@ -251,16 +253,16 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e
// do additional size check against indexer api or download torrent for size check
if release.AdditionalSizeCheckRequired {
log.Debug().Msgf("filter.Service.CheckFilter: (%v) additional size check required", f.Name)
s.log.Debug().Msgf("filter.Service.CheckFilter: (%v) additional size check required", f.Name)
ok, err := s.AdditionalSizeCheck(f, release)
if err != nil {
log.Error().Stack().Err(err).Msgf("filter.Service.CheckFilter: (%v) additional size check error", f.Name)
s.log.Error().Stack().Err(err).Msgf("filter.Service.CheckFilter: (%v) additional size check error", f.Name)
return false, err
}
if !ok {
log.Trace().Msgf("filter.Service.CheckFilter: (%v) additional size check not matching what filter wanted", f.Name)
s.log.Trace().Msgf("filter.Service.CheckFilter: (%v) additional size check not matching what filter wanted", f.Name)
return false, nil
}
}
@ -268,13 +270,13 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e
// found matching filter, lets find the filter actions and attach
actions, err := s.actionRepo.FindByFilterID(context.TODO(), f.ID)
if err != nil {
log.Error().Err(err).Msgf("filter.Service.CheckFilter: error finding actions for filter: %+v", f.Name)
s.log.Error().Err(err).Msgf("filter.Service.CheckFilter: error finding actions for filter: %+v", f.Name)
return false, err
}
// if no actions, continue to next filter
if len(actions) == 0 {
log.Trace().Msgf("filter.Service.CheckFilter: no actions found for filter '%v', trying next one..", f.Name)
s.log.Trace().Msgf("filter.Service.CheckFilter: no actions found for filter '%v', trying next one..", f.Name)
return false, err
}
release.Filter.Actions = actions
@ -293,30 +295,30 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e
func (s *service) AdditionalSizeCheck(f domain.Filter, release *domain.Release) (bool, error) {
// do additional size check against indexer api or torrent for size
log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) additional size check required", f.Name)
s.log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) additional size check required", f.Name)
switch release.Indexer {
case "ptp", "btn", "ggn", "redacted", "mock":
if release.Size == 0 {
log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to check via api", f.Name)
s.log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to check via api", f.Name)
torrentInfo, err := s.apiService.GetTorrentByID(release.Indexer, release.TorrentID)
if err != nil || torrentInfo == nil {
log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not get torrent info from api: '%v' from: %v", f.Name, release.TorrentID, release.Indexer)
s.log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not get torrent info from api: '%v' from: %v", f.Name, release.TorrentID, release.Indexer)
return false, err
}
log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) got torrent info from api: %+v", f.Name, torrentInfo)
s.log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) got torrent info from api: %+v", f.Name, torrentInfo)
release.Size = torrentInfo.ReleaseSizeBytes()
}
default:
log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to download torrent metafile", f.Name)
s.log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to download torrent metafile", f.Name)
// if indexer doesn't have api, download torrent and add to tmpPath
err := release.DownloadTorrentFile()
if err != nil {
log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not download torrent file with id: '%v' from: %v", f.Name, release.TorrentID, release.Indexer)
s.log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not download torrent file with id: '%v' from: %v", f.Name, release.TorrentID, release.Indexer)
return false, err
}
}
@ -324,12 +326,12 @@ func (s *service) AdditionalSizeCheck(f domain.Filter, release *domain.Release)
// compare size against filter
match, err := checkSizeFilter(f.MinSize, f.MaxSize, release.Size)
if err != nil {
log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) error checking extra size filter", f.Name)
s.log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) error checking extra size filter", f.Name)
return false, err
}
//no match, lets continue to next filter
if !match {
log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) filter did not match after additional size check, trying next", f.Name)
s.log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) filter did not match after additional size check, trying next", f.Name)
return false, nil
}

View file

@ -19,13 +19,13 @@ type authService interface {
type authHandler struct {
encoder encoder
config domain.Config
config *domain.Config
service authService
cookieStore *sessions.CookieStore
}
func newAuthHandler(encoder encoder, config domain.Config, cookieStore *sessions.CookieStore, service authService) *authHandler {
func newAuthHandler(encoder encoder, config *domain.Config, cookieStore *sessions.CookieStore, service authService) *authHandler {
return &authHandler{
encoder: encoder,
config: config,

View file

@ -3,8 +3,6 @@ package http
import (
"net/http"
"github.com/autobrr/autobrr/internal/config"
"github.com/go-chi/chi"
)
@ -39,14 +37,12 @@ func (h configHandler) Routes(r chi.Router) {
func (h configHandler) getConfig(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
c := config.Config
conf := configJson{
Host: c.Host,
Port: c.Port,
LogLevel: c.LogLevel,
LogPath: c.LogPath,
BaseURL: c.BaseURL,
Host: h.server.config.Host,
Port: h.server.config.Port,
LogLevel: h.server.config.LogLevel,
LogPath: h.server.config.LogPath,
BaseURL: h.server.config.BaseURL,
Version: h.server.version,
Commit: h.server.commit,
Date: h.server.date,

View file

@ -20,7 +20,7 @@ type Server struct {
sse *sse.Server
db *database.DB
config domain.Config
config *domain.Config
cookieStore *sessions.CookieStore
version string
@ -38,7 +38,7 @@ type Server struct {
releaseService releaseService
}
func NewServer(config domain.Config, sse *sse.Server, db *database.DB, version string, commit string, date string, actionService actionService, authService authService, downloadClientSvc downloadClientService, filterSvc filterService, feedSvc feedService, indexerSvc indexerService, ircSvc ircService, notificationSvc notificationService, releaseSvc releaseService) Server {
func NewServer(config *domain.Config, sse *sse.Server, db *database.DB, version string, commit string, date string, actionService actionService, authService authService, downloadClientSvc downloadClientService, filterSvc filterService, feedSvc feedService, indexerSvc indexerService, ircSvc ircService, notificationSvc notificationService, releaseSvc releaseService) Server {
return Server{
config: config,
sse: sse,

View file

@ -4,13 +4,12 @@ import (
"fmt"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/mock"
"github.com/autobrr/autobrr/pkg/btn"
"github.com/autobrr/autobrr/pkg/ggn"
"github.com/autobrr/autobrr/pkg/ptp"
"github.com/autobrr/autobrr/pkg/red"
"github.com/rs/zerolog/log"
)
type APIService interface {
@ -26,11 +25,13 @@ type apiClient interface {
}
type apiService struct {
log logger.Logger
apiClients map[string]apiClient
}
func NewAPIService() APIService {
func NewAPIService(log logger.Logger) APIService {
return &apiService{
log: log,
apiClients: make(map[string]apiClient),
}
}
@ -41,15 +42,15 @@ func (s *apiService) GetTorrentByID(indexer string, torrentID string) (*domain.T
return nil, nil
}
log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' trying to fetch torrent from api", indexer)
s.log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' trying to fetch torrent from api", indexer)
t, err := v.GetTorrentByID(torrentID)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not get torrent: '%v' from: %v", torrentID, indexer)
s.log.Error().Stack().Err(err).Msgf("could not get torrent: '%v' from: %v", torrentID, indexer)
return nil, err
}
log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' successfully fetched torrent from api: %+v", indexer, t)
s.log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' successfully fetched torrent from api: %+v", indexer, t)
return t, nil
}
@ -76,7 +77,7 @@ func (s *apiService) AddClient(indexer string, settings map[string]string) error
return fmt.Errorf("api.Service.AddClient: validation falied: settings can't be empty")
}
log.Trace().Msgf("api.Service.AddClient: init api client for '%v'", indexer)
s.log.Trace().Msgf("api.Service.AddClient: init api client for '%v'", indexer)
// init client
switch indexer {

View file

@ -10,10 +10,10 @@ import (
"strings"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/scheduler"
"github.com/gosimple/slug"
"github.com/rs/zerolog/log"
"gopkg.in/yaml.v2"
)
@ -32,7 +32,8 @@ type Service interface {
}
type service struct {
config domain.Config
log logger.Logger
config *domain.Config
repo domain.IndexerRepo
apiService APIService
scheduler scheduler.Service
@ -48,8 +49,9 @@ type service struct {
torznabIndexers map[string]*domain.IndexerDefinition
}
func NewService(config domain.Config, repo domain.IndexerRepo, apiService APIService, scheduler scheduler.Service) Service {
func NewService(log logger.Logger, config *domain.Config, repo domain.IndexerRepo, apiService APIService, scheduler scheduler.Service) Service {
return &service{
log: log,
config: config,
repo: repo,
apiService: apiService,
@ -73,14 +75,14 @@ func (s *service) Store(ctx context.Context, indexer domain.Indexer) (*domain.In
i, err := s.repo.Store(ctx, indexer)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to store indexer: %v", indexer.Name)
s.log.Error().Stack().Err(err).Msgf("failed to store indexer: %v", indexer.Name)
return nil, err
}
// add to indexerInstances
err = s.addIndexer(*i)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name)
s.log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name)
return nil, err
}
@ -96,7 +98,7 @@ func (s *service) Update(ctx context.Context, indexer domain.Indexer) (*domain.I
// add to indexerInstances
err = s.addIndexer(*i)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name)
s.log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name)
return nil, err
}
@ -238,7 +240,7 @@ func (s *service) Start() error {
// check if it has api and add to api service
if indexer.Enabled && indexer.HasApi() {
if err := s.apiService.AddClient(indexer.Identifier, indexer.SettingsMap); err != nil {
log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier)
s.log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier)
}
}
}
@ -249,7 +251,7 @@ func (s *service) Start() error {
}
}
log.Info().Msgf("Loaded %d indexers", len(indexerDefinitions))
s.log.Info().Msgf("Loaded %d indexers", len(indexerDefinitions))
return nil
}
@ -290,7 +292,7 @@ func (s *service) addIndexer(indexer domain.Indexer) error {
// check if it has api and add to api service
if indexerDefinition.Enabled && indexerDefinition.HasApi() {
if err := s.apiService.AddClient(indexerDefinition.Identifier, indexerDefinition.SettingsMap); err != nil {
log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier)
s.log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier)
}
}
}
@ -344,11 +346,11 @@ func (s *service) LoadIndexerDefinitions() error {
entries, err := fs.ReadDir(Definitions, "definitions")
if err != nil {
log.Fatal().Stack().Msgf("failed reading directory: %s", err)
s.log.Fatal().Stack().Msgf("failed reading directory: %s", err)
}
if len(entries) == 0 {
log.Fatal().Stack().Msgf("failed reading directory: %s", err)
s.log.Fatal().Stack().Msgf("failed reading directory: %s", err)
return err
}
@ -360,19 +362,19 @@ func (s *service) LoadIndexerDefinitions() error {
file := "definitions/" + f.Name()
log.Trace().Msgf("parsing: %v", file)
s.log.Trace().Msgf("parsing: %v", file)
var d *domain.IndexerDefinition
data, err := fs.ReadFile(Definitions, file)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed reading file: %v", file)
s.log.Error().Stack().Err(err).Msgf("failed reading file: %v", file)
return err
}
err = yaml.Unmarshal(data, &d)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file)
s.log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file)
return err
}
@ -383,7 +385,7 @@ func (s *service) LoadIndexerDefinitions() error {
s.indexerDefinitions[d.Identifier] = d
}
log.Debug().Msgf("Loaded %d indexer definitions", len(s.indexerDefinitions))
s.log.Debug().Msgf("Loaded %d indexer definitions", len(s.indexerDefinitions))
return nil
}
@ -399,11 +401,11 @@ func (s *service) LoadCustomIndexerDefinitions() error {
//entries, err := fs.ReadDir(Definitions, "definitions")
entries, err := outputDirRead.ReadDir(0)
if err != nil {
log.Fatal().Stack().Msgf("failed reading directory: %s", err)
s.log.Fatal().Stack().Msgf("failed reading directory: %s", err)
}
if len(entries) == 0 {
log.Fatal().Stack().Msgf("failed reading directory: %s", err)
s.log.Fatal().Stack().Msgf("failed reading directory: %s", err)
return err
}
@ -417,20 +419,20 @@ func (s *service) LoadCustomIndexerDefinitions() error {
file := filepath.Join(s.config.CustomDefinitions, f.Name())
log.Trace().Msgf("parsing custom: %v", file)
s.log.Trace().Msgf("parsing custom: %v", file)
var d *domain.IndexerDefinition
//data, err := fs.ReadFile(Definitions, filePath)
data, err := os.ReadFile(file)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed reading file: %v", file)
s.log.Error().Stack().Err(err).Msgf("failed reading file: %v", file)
return err
}
err = yaml.Unmarshal(data, &d)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file)
s.log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file)
return err
}
@ -443,7 +445,7 @@ func (s *service) LoadCustomIndexerDefinitions() error {
customCount++
}
log.Debug().Msgf("Loaded %d custom indexer definitions", customCount)
s.log.Debug().Msgf("Loaded %d custom indexer definitions", customCount)
return nil
}

View file

@ -13,9 +13,10 @@ import (
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/release"
"github.com/dcarbone/zadapters/zstdlog"
"github.com/ergochat/irc-go/ircevent"
"github.com/ergochat/irc-go/ircmsg"
"github.com/rs/zerolog/log"
"github.com/rs/zerolog"
)
var (
@ -55,6 +56,7 @@ func (h *channelHealth) resetMonitoring() {
}
type Handler struct {
log zerolog.Logger
network *domain.IrcNetwork
releaseSvc release.Service
announceProcessors map[string]announce.Processor
@ -73,8 +75,9 @@ type Handler struct {
channelHealth map[string]*channelHealth
}
func NewHandler(network domain.IrcNetwork, definitions []*domain.IndexerDefinition, releaseSvc release.Service) *Handler {
func NewHandler(log logger.Logger, network domain.IrcNetwork, definitions []*domain.IndexerDefinition, releaseSvc release.Service) *Handler {
h := &Handler{
log: log.With().Time("time", time.Now()).Str("network", network.Server).Logger(),
client: nil,
network: &network,
releaseSvc: releaseSvc,
@ -106,7 +109,7 @@ func (h *Handler) InitIndexers(definitions []*domain.IndexerDefinition) {
// some channels are defined in mixed case
channel = strings.ToLower(channel)
h.announceProcessors[channel] = announce.NewAnnounceProcessor(h.releaseSvc, definition)
h.announceProcessors[channel] = announce.NewAnnounceProcessor(h.log, h.releaseSvc, definition)
h.channelHealth[channel] = &channelHealth{
name: channel,
@ -134,6 +137,8 @@ func (h *Handler) removeIndexer() {
func (h *Handler) Run() error {
addr := fmt.Sprintf("%v:%d", h.network.Server, h.network.Port)
subLogger := zstdlog.NewStdLoggerWithLevel(h.log.With().Logger(), zerolog.TraceLevel)
h.client = &ircevent.Connection{
Nick: h.network.NickServ.Account,
User: h.network.NickServ.Account,
@ -141,12 +146,12 @@ func (h *Handler) Run() error {
Password: h.network.Pass,
Server: addr,
KeepAlive: 4 * time.Minute,
Timeout: 1 * time.Minute,
Timeout: 2 * time.Minute,
ReconnectFreq: 15 * time.Second,
Version: "autobrr",
QuitMessage: "bye from autobrr",
Debug: true,
Log: logger.StdLeveledLogger,
Log: subLogger,
}
if h.network.TLS {
@ -162,7 +167,7 @@ func (h *Handler) Run() error {
h.client.AddCallback("PRIVMSG", h.onMessage)
if err := h.client.Connect(); err != nil {
log.Error().Stack().Err(err).Msgf("%v: connect error", h.network.Server)
h.log.Error().Stack().Err(err).Msgf("%v: connect error", h.network.Server)
// reset connection status on handler and channels
h.resetConnectionStatus()
@ -233,12 +238,12 @@ func (h *Handler) AddChannelHealth(channel string) {
}
func (h *Handler) Stop() {
log.Debug().Msgf("%v: Disconnecting...", h.network.Server)
h.log.Debug().Msgf("%v: Disconnecting...", h.network.Server)
h.client.Quit()
}
func (h *Handler) Restart() error {
log.Debug().Msgf("%v: Restarting network...", h.network.Server)
h.log.Debug().Msgf("%v: Restarting network...", h.network.Server)
h.client.Quit()
@ -255,7 +260,7 @@ func (h *Handler) onConnect(m ircmsg.Message) {
if h.network.NickServ.Password != "" {
err := h.HandleNickServIdentify(h.network.NickServ.Password)
if err != nil {
log.Error().Stack().Err(err).Msgf("error nickserv: %v", h.network.Name)
h.log.Error().Stack().Err(err).Msgf("error nickserv: %v", h.network.Name)
return
}
identified = true
@ -266,7 +271,7 @@ func (h *Handler) onConnect(m ircmsg.Message) {
if h.network.InviteCommand != "" {
err := h.handleConnectCommands(h.network.InviteCommand)
if err != nil {
log.Error().Stack().Err(err).Msgf("error sending connect command %v to network: %v", h.network.InviteCommand, h.network.Name)
h.log.Error().Stack().Err(err).Msgf("error sending connect command %v to network: %v", h.network.InviteCommand, h.network.Name)
return
}
@ -277,7 +282,7 @@ func (h *Handler) onConnect(m ircmsg.Message) {
for _, channel := range h.network.Channels {
err := h.HandleJoinChannel(channel.Name, channel.Password)
if err != nil {
log.Error().Stack().Err(err).Msgf("error joining channels %v", err)
h.log.Error().Stack().Err(err).Msgf("error joining channels %v", err)
return
}
}
@ -307,11 +312,11 @@ func (h *Handler) onMessage(msg ircmsg.Message) {
}
// clean message
cleanedMsg := cleanMessage(message)
log.Debug().Msgf("%v: %v %v: %v", h.network.Server, channel, announcer, cleanedMsg)
cleanedMsg := h.cleanMessage(message)
h.log.Debug().Msgf("%v: %v %v: %v", h.network.Server, channel, announcer, cleanedMsg)
if err := h.sendToAnnounceProcessor(channel, cleanedMsg); err != nil {
log.Error().Stack().Err(err).Msgf("could not queue line: %v", cleanedMsg)
h.log.Error().Stack().Err(err).Msgf("could not queue line: %v", cleanedMsg)
return
}
@ -330,7 +335,7 @@ func (h *Handler) sendToAnnounceProcessor(channel string, msg string) error {
// if it exists, add msg
err := queue.AddLineToQueue(channel, msg)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not queue line: %v", msg)
h.log.Error().Stack().Err(err).Msgf("could not queue line: %v", msg)
return err
}
@ -355,11 +360,11 @@ func (h *Handler) HandleJoinChannel(channel string, password string) error {
m.Params = []string{channel, password}
}
log.Debug().Msgf("%v: sending JOIN command %v", h.network.Server, strings.Join(m.Params, " "))
h.log.Debug().Msgf("%v: sending JOIN command %v", h.network.Server, strings.Join(m.Params, " "))
err := h.client.SendIRCMessage(m)
if err != nil {
log.Error().Stack().Err(err).Msgf("error handling join: %v", channel)
h.log.Error().Stack().Err(err).Msgf("error handling join: %v", channel)
return err
}
@ -368,17 +373,17 @@ func (h *Handler) HandleJoinChannel(channel string, password string) error {
func (h *Handler) handlePart(msg ircmsg.Message) {
if !h.isOurNick(msg.Nick()) {
log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg)
h.log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg)
return
}
channel := msg.Params[0]
log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel)
h.log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel)
err := h.client.Part(channel)
if err != nil {
log.Error().Err(err).Msgf("error handling part: %v", channel)
h.log.Error().Err(err).Msgf("error handling part: %v", channel)
return
}
@ -392,17 +397,17 @@ func (h *Handler) handlePart(msg ircmsg.Message) {
// TODO remove announceProcessor
log.Info().Msgf("%v: Left channel '%v'", h.network.Server, channel)
h.log.Info().Msgf("%v: Left channel '%v'", h.network.Server, channel)
return
}
func (h *Handler) HandlePartChannel(channel string) error {
log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel)
h.log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel)
err := h.client.Part(channel)
if err != nil {
log.Error().Err(err).Msgf("error handling part: %v", channel)
h.log.Error().Err(err).Msgf("error handling part: %v", channel)
return err
}
@ -416,21 +421,21 @@ func (h *Handler) HandlePartChannel(channel string) error {
// TODO remove announceProcessor
log.Info().Msgf("Left channel '%v' on network '%h'", channel, h.network.Server)
h.log.Info().Msgf("Left channel '%v' on network '%h'", channel, h.network.Server)
return nil
}
func (h *Handler) handleJoined(msg ircmsg.Message) {
if !h.isOurNick(msg.Params[0]) {
log.Debug().Msgf("%v: OTHER USER JOINED: %+v", h.network.Server, msg)
h.log.Debug().Msgf("%v: OTHER USER JOINED: %+v", h.network.Server, msg)
return
}
// get channel
channel := msg.Params[1]
log.Debug().Msgf("%v: JOINED: %v", h.network.Server, msg.Params[1])
h.log.Debug().Msgf("%v: JOINED: %v", h.network.Server, msg.Params[1])
// set monitoring on current channelHealth, or add new
v, ok := h.channelHealth[strings.ToLower(channel)]
@ -442,7 +447,7 @@ func (h *Handler) handleJoined(msg ircmsg.Message) {
valid := h.isValidChannel(channel)
if valid {
log.Info().Msgf("%v: Monitoring channel %v", h.network.Server, msg.Params[1])
h.log.Info().Msgf("%v: Monitoring channel %v", h.network.Server, msg.Params[1])
return
}
}
@ -459,11 +464,11 @@ func (h *Handler) handleConnectCommands(msg string) error {
Params: strings.Split(cmd, " "),
}
log.Debug().Msgf("%v: sending connect command", h.network.Server)
h.log.Debug().Msgf("%v: sending connect command", h.network.Server)
err := h.client.SendIRCMessage(m)
if err != nil {
log.Error().Err(err).Msgf("error handling invite: %v", m)
h.log.Error().Err(err).Msgf("error handling invite: %v", m)
return err
}
}
@ -479,11 +484,11 @@ func (h *Handler) handleInvite(msg ircmsg.Message) {
// get channel
channel := msg.Params[1]
log.Debug().Msgf("%v: INVITE from %v, joining %v", h.network.Server, msg.Nick(), channel)
h.log.Debug().Msgf("%v: INVITE from %v, joining %v", h.network.Server, msg.Nick(), channel)
err := h.client.Join(channel)
if err != nil {
log.Error().Stack().Err(err).Msgf("error handling join: %v", channel)
h.log.Error().Stack().Err(err).Msgf("error handling join: %v", channel)
return
}
@ -496,11 +501,11 @@ func (h *Handler) HandleNickServIdentify(password string) error {
Params: []string{"NickServ", "IDENTIFY", password},
}
log.Debug().Msgf("%v: NickServ: %v", h.network.Server, m)
h.log.Debug().Msgf("%v: NickServ: %v", h.network.Server, m)
err := h.client.SendIRCMessage(m)
if err != nil {
log.Error().Stack().Err(err).Msgf("error identifying with nickserv: %v", m)
h.log.Error().Stack().Err(err).Msgf("error identifying with nickserv: %v", m)
return err
}
@ -508,7 +513,7 @@ func (h *Handler) HandleNickServIdentify(password string) error {
}
func (h *Handler) HandleNickChange(nick string) error {
log.Debug().Msgf("%v: Nick change: %v", h.network.Server, nick)
h.log.Debug().Msgf("%v: Nick change: %v", h.network.Server, nick)
h.client.SetNick(nick)
@ -516,24 +521,24 @@ func (h *Handler) HandleNickChange(nick string) error {
}
func (h *Handler) handleMode(msg ircmsg.Message) {
log.Debug().Msgf("%v: MODE: %+v", h.network.Server, msg)
h.log.Debug().Msgf("%v: MODE: %+v", h.network.Server, msg)
if !h.isOurNick(msg.Params[0]) {
log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg)
h.log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg)
return
}
time.Sleep(5 * time.Second)
if h.network.NickServ.Password != "" && !strings.Contains(msg.Params[0], h.client.Nick) || !strings.Contains(msg.Params[1], "+r") {
log.Trace().Msgf("%v: MODE: Not correct permission yet: %v", h.network.Server, msg.Params)
h.log.Trace().Msgf("%v: MODE: Not correct permission yet: %v", h.network.Server, msg.Params)
return
}
for _, ch := range h.network.Channels {
err := h.HandleJoinChannel(ch.Name, ch.Password)
if err != nil {
log.Error().Err(err).Msgf("error joining channel: %v", ch.Name)
h.log.Error().Err(err).Msgf("error joining channel: %v", ch.Name)
continue
}
@ -572,12 +577,12 @@ func (h *Handler) GetLastPing() time.Time {
}
// irc line can contain lots of extra stuff like color so lets clean that
func cleanMessage(message string) string {
func (h *Handler) cleanMessage(message string) string {
var regexMessageClean = `\x0f|\x1f|\x02|\x03(?:[\d]{1,2}(?:,[\d]{1,2})?)?`
rxp, err := regexp.Compile(regexMessageClean)
if err != nil {
log.Error().Err(err).Msgf("error compiling regex: %v", regexMessageClean)
h.log.Error().Err(err).Msgf("error compiling regex: %v", regexMessageClean)
return ""
}

View file

@ -8,10 +8,10 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/indexer"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/release"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
type Service interface {
@ -28,6 +28,7 @@ type Service interface {
}
type service struct {
log logger.Logger
repo domain.IrcRepo
releaseService release.Service
indexerService indexer.Service
@ -38,8 +39,9 @@ type service struct {
lock sync.Mutex
}
func NewService(repo domain.IrcRepo, releaseSvc release.Service, indexerSvc indexer.Service) Service {
func NewService(log logger.Logger, repo domain.IrcRepo, releaseSvc release.Service, indexerSvc indexer.Service) Service {
return &service{
log: log,
repo: repo,
releaseService: releaseSvc,
indexerService: indexerSvc,
@ -55,7 +57,7 @@ type handlerKey struct {
func (s *service) StartHandlers() {
networks, err := s.repo.FindActiveNetworks(context.Background())
if err != nil {
log.Error().Msgf("failed to list networks: %v", err)
s.log.Error().Msgf("failed to list networks: %v", err)
}
for _, network := range networks {
@ -69,7 +71,7 @@ func (s *service) StartHandlers() {
s.lock.Lock()
channels, err := s.repo.ListChannels(network.ID)
if err != nil {
log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server)
s.log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server)
}
network.Channels = channels
@ -77,20 +79,20 @@ func (s *service) StartHandlers() {
definitions := s.indexerService.GetIndexersByIRCNetwork(network.Server)
// init new irc handler
handler := NewHandler(network, definitions, s.releaseService)
handler := NewHandler(s.log, network, definitions, s.releaseService)
// use network.Server + nick to use multiple indexers with different nick per network
// this allows for multiple handlers to one network
s.handlers[handlerKey{network.Server, network.NickServ.Account}] = handler
s.lock.Unlock()
log.Debug().Msgf("starting network: %+v", network.Name)
s.log.Debug().Msgf("starting network: %+v", network.Name)
s.stopWG.Add(1)
go func() {
if err := handler.Run(); err != nil {
log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name)
s.log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name)
}
}()
@ -100,22 +102,22 @@ func (s *service) StartHandlers() {
func (s *service) StopHandlers() {
for _, handler := range s.handlers {
log.Info().Msgf("stopping network: %+v", handler.network.Name)
s.log.Info().Msgf("stopping network: %+v", handler.network.Name)
handler.Stop()
}
log.Info().Msg("stopped all irc handlers")
s.log.Info().Msg("stopped all irc handlers")
}
func (s *service) startNetwork(network domain.IrcNetwork) error {
// look if we have the network in handlers already, if so start it
if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found {
log.Debug().Msgf("starting network: %+v", network.Name)
s.log.Debug().Msgf("starting network: %+v", network.Name)
if !existingHandler.client.Connected() {
go func() {
if err := existingHandler.Run(); err != nil {
log.Error().Err(err).Msgf("failed to start existingHandler for network %q", existingHandler.network.Name)
s.log.Error().Err(err).Msgf("failed to start existingHandler for network %q", existingHandler.network.Name)
}
}()
}
@ -125,7 +127,7 @@ func (s *service) startNetwork(network domain.IrcNetwork) error {
s.lock.Lock()
channels, err := s.repo.ListChannels(network.ID)
if err != nil {
log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server)
s.log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server)
}
network.Channels = channels
@ -133,18 +135,18 @@ func (s *service) startNetwork(network domain.IrcNetwork) error {
definitions := s.indexerService.GetIndexersByIRCNetwork(network.Server)
// init new irc handler
handler := NewHandler(network, definitions, s.releaseService)
handler := NewHandler(s.log, network, definitions, s.releaseService)
s.handlers[handlerKey{network.Server, network.NickServ.Account}] = handler
s.lock.Unlock()
log.Debug().Msgf("starting network: %+v", network.Name)
s.log.Debug().Msgf("starting network: %+v", network.Name)
s.stopWG.Add(1)
go func() {
if err := handler.Run(); err != nil {
log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name)
s.log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name)
}
}()
@ -157,7 +159,7 @@ func (s *service) startNetwork(network domain.IrcNetwork) error {
func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error {
// look if we have the network in handlers, if so restart it
if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found {
log.Debug().Msgf("irc: decide if irc network handler needs restart or updating: %+v", network.Server)
s.log.Debug().Msgf("irc: decide if irc network handler needs restart or updating: %+v", network.Server)
// if server, tls, invite command, port : changed - restart
// if nickserv account, nickserv password : changed - stay connected, and change those
@ -176,7 +178,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
restartNeeded = true
}
if restartNeeded {
log.Info().Msgf("irc: restarting network: %+v", network.Server)
s.log.Info().Msgf("irc: restarting network: %+v", network.Server)
// we need to reinitialize with new network config
existingHandler.UpdateNetwork(network)
@ -185,7 +187,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
go func() {
if err := existingHandler.Restart(); err != nil {
log.Error().Stack().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name)
s.log.Error().Stack().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name)
}
}()
@ -194,18 +196,18 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
}
if handler.NickServ.Account != network.NickServ.Account {
log.Debug().Msg("changing nick")
s.log.Debug().Msg("changing nick")
err := existingHandler.HandleNickChange(network.NickServ.Account)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to change nick %q", network.NickServ.Account)
s.log.Error().Stack().Err(err).Msgf("failed to change nick %q", network.NickServ.Account)
}
} else if handler.NickServ.Password != network.NickServ.Password {
log.Debug().Msg("nickserv: changing password")
s.log.Debug().Msg("nickserv: changing password")
err := existingHandler.HandleNickServIdentify(network.NickServ.Password)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to identify with nickserv %q", network.NickServ.Account)
s.log.Error().Stack().Err(err).Msgf("failed to identify with nickserv %q", network.NickServ.Account)
}
}
@ -249,19 +251,19 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
// leave channels
for _, leaveChannel := range channelsToLeave {
log.Debug().Msgf("%v: part channel %v", network.Server, leaveChannel)
s.log.Debug().Msgf("%v: part channel %v", network.Server, leaveChannel)
err := existingHandler.HandlePartChannel(leaveChannel)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to leave channel: %q", leaveChannel)
s.log.Error().Stack().Err(err).Msgf("failed to leave channel: %q", leaveChannel)
}
}
// join channels
for _, joinChannel := range channelsToJoin {
log.Debug().Msgf("%v: join new channel %v", network.Server, joinChannel)
s.log.Debug().Msgf("%v: join new channel %v", network.Server, joinChannel)
err := existingHandler.HandleJoinChannel(joinChannel.Name, joinChannel.Password)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to join channel: %q", joinChannel.Name)
s.log.Error().Stack().Err(err).Msgf("failed to join channel: %q", joinChannel.Name)
}
}
@ -277,7 +279,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
} else {
err := s.startNetwork(*network)
if err != nil {
log.Error().Stack().Err(err).Msgf("failed to start network: %q", network.Name)
s.log.Error().Stack().Err(err).Msgf("failed to start network: %q", network.Name)
}
}
@ -287,12 +289,12 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error
func (s *service) restartNetwork(network domain.IrcNetwork) error {
// look if we have the network in handlers, if so restart it
if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found {
log.Info().Msgf("restarting network: %v", network.Name)
s.log.Info().Msgf("restarting network: %v", network.Name)
if existingHandler.client.Connected() {
go func() {
if err := existingHandler.Restart(); err != nil {
log.Error().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name)
s.log.Error().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name)
}
}()
}
@ -306,7 +308,7 @@ func (s *service) restartNetwork(network domain.IrcNetwork) error {
func (s *service) StopNetwork(key handlerKey) error {
if handler, found := s.handlers[key]; found {
handler.Stop()
log.Debug().Msgf("stopped network: %+v", key.server)
s.log.Debug().Msgf("stopped network: %+v", key.server)
}
return nil
@ -318,7 +320,7 @@ func (s *service) StopAndRemoveNetwork(key handlerKey) error {
// remove from handlers
delete(s.handlers, key)
log.Debug().Msgf("stopped network: %+v", key)
s.log.Debug().Msgf("stopped network: %+v", key)
}
return nil
@ -327,7 +329,7 @@ func (s *service) StopAndRemoveNetwork(key handlerKey) error {
func (s *service) StopNetworkIfRunning(key handlerKey) error {
if handler, found := s.handlers[key]; found {
handler.Stop()
log.Debug().Msgf("stopped network: %+v", key.server)
s.log.Debug().Msgf("stopped network: %+v", key.server)
}
return nil
@ -336,13 +338,13 @@ func (s *service) StopNetworkIfRunning(key handlerKey) error {
func (s *service) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetwork, error) {
network, err := s.repo.GetNetworkByID(ctx, id)
if err != nil {
log.Error().Err(err).Msgf("failed to get network: %v", id)
s.log.Error().Err(err).Msgf("failed to get network: %v", id)
return nil, err
}
channels, err := s.repo.ListChannels(network.ID)
if err != nil {
log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server)
s.log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server)
return nil, err
}
network.Channels = append(network.Channels, channels...)
@ -353,7 +355,7 @@ func (s *service) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw
func (s *service) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) {
networks, err := s.repo.ListNetworks(ctx)
if err != nil {
log.Error().Err(err).Msgf("failed to list networks: %v", err)
s.log.Error().Err(err).Msgf("failed to list networks: %v", err)
return nil, err
}
@ -362,7 +364,7 @@ func (s *service) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
for _, n := range networks {
channels, err := s.repo.ListChannels(n.ID)
if err != nil {
log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err)
s.log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err)
return nil, err
}
n.Channels = append(n.Channels, channels...)
@ -376,7 +378,7 @@ func (s *service) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetworkWithHealth, error) {
networks, err := s.repo.ListNetworks(ctx)
if err != nil {
log.Error().Err(err).Msgf("failed to list networks: %v", err)
s.log.Error().Err(err).Msgf("failed to list networks: %v", err)
return nil, err
}
@ -410,7 +412,7 @@ func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetwor
channels, err := s.repo.ListChannels(n.ID)
if err != nil {
log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err)
s.log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err)
return nil, err
}
@ -457,7 +459,7 @@ func (s *service) DeleteNetwork(ctx context.Context, id int64) error {
return err
}
log.Debug().Msgf("delete network: %v", id)
s.log.Debug().Msgf("delete network: %v", id)
// Remove network and handler
//if err = s.StopNetwork(network.Server); err != nil {
@ -483,7 +485,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
if err := s.repo.UpdateNetwork(ctx, network); err != nil {
return err
}
log.Debug().Msgf("irc.service: update network: %+v", network)
s.log.Debug().Msgf("irc.service: update network: %+v", network)
// stop or start network
// TODO get current state to see if enabled or not?
@ -493,7 +495,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
// if channels len : changes - join or leave
err := s.checkIfNetworkRestartNeeded(network)
if err != nil {
log.Error().Stack().Err(err).Msgf("could not restart network: %+v", network.Name)
s.log.Error().Stack().Err(err).Msgf("could not restart network: %+v", network.Name)
return fmt.Errorf("could not restart network: %v", network.Name)
}
@ -501,7 +503,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
// take into account multiple channels per network
err := s.StopAndRemoveNetwork(handlerKey{network.Server, network.NickServ.Account})
if err != nil {
log.Error().Stack().Err(err).Msgf("could not stop network: %+v", network.Name)
s.log.Error().Stack().Err(err).Msgf("could not stop network: %+v", network.Name)
return fmt.Errorf("could not stop network: %v", network.Name)
}
}
@ -512,7 +514,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork) error {
existingNetwork, err := s.repo.CheckExistingNetwork(ctx, network)
if err != nil {
log.Error().Err(err).Msg("could not check for existing network")
s.log.Error().Err(err).Msg("could not check for existing network")
return err
}
@ -520,12 +522,12 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork)
if err := s.repo.StoreNetwork(network); err != nil {
return err
}
log.Debug().Msgf("store network: %+v", network)
s.log.Debug().Msgf("store network: %+v", network)
if network.Channels != nil {
for _, channel := range network.Channels {
if err := s.repo.StoreChannel(network.ID, &channel); err != nil {
log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query")
s.log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query")
return errors.Wrap(err, "error storing channel on network")
//return err
}
@ -538,7 +540,7 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork)
// get channels for existing network
existingChannels, err := s.repo.ListChannels(existingNetwork.ID)
if err != nil {
log.Error().Err(err).Msgf("failed to list channels for network %q", existingNetwork.Server)
s.log.Error().Err(err).Msgf("failed to list channels for network %q", existingNetwork.Server)
}
existingNetwork.Channels = existingChannels
@ -561,7 +563,7 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork)
err := s.checkIfNetworkRestartNeeded(existingNetwork)
if err != nil {
log.Error().Err(err).Msgf("could not restart network: %+v", existingNetwork.Name)
s.log.Error().Err(err).Msgf("could not restart network: %+v", existingNetwork.Name)
return fmt.Errorf("could not restart network: %v", existingNetwork.Name)
}
}

View file

@ -2,71 +2,144 @@ package logger
import (
"io"
stdlog "log"
"os"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/dcarbone/zadapters/zstdlog"
"github.com/r3labs/sse/v2"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/rs/zerolog/pkgerrors"
"gopkg.in/natefinch/lumberjack.v2"
)
var (
StdLogger *stdlog.Logger
StdLeveledLogger *stdlog.Logger
)
// Logger interface
type Logger interface {
Log() *zerolog.Event
Fatal() *zerolog.Event
Err(err error) *zerolog.Event
Error() *zerolog.Event
Warn() *zerolog.Event
Info() *zerolog.Event
Trace() *zerolog.Event
Debug() *zerolog.Event
With() zerolog.Context
RegisterSSEHook(sse *sse.Server)
SetLogLevel(level string)
}
func Setup(cfg domain.Config, sse *sse.Server) {
// DefaultLogger default logging controller
type DefaultLogger struct {
log zerolog.Logger
level zerolog.Level
writers []io.Writer
}
func New(cfg *domain.Config) Logger {
l := &DefaultLogger{
writers: make([]io.Writer, 0),
level: zerolog.DebugLevel,
}
// set log level
l.SetLogLevel(cfg.LogLevel)
// use pretty logging for dev only
if cfg.Version == "dev" {
// setup console writer
consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}
l.writers = append(l.writers, consoleWriter)
} else {
// default to stderr
l.writers = append(l.writers, os.Stderr)
}
if cfg.LogPath != "" {
l.writers = append(l.writers,
&lumberjack.Logger{
Filename: cfg.LogPath,
MaxSize: 50, // megabytes
MaxBackups: 3,
},
)
}
// set some defaults
zerolog.TimeFieldFormat = time.RFC3339
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
switch cfg.LogLevel {
// init new logger
l.log = zerolog.New(io.MultiWriter(l.writers...)).With().Stack().Logger()
return l
}
func (l *DefaultLogger) RegisterSSEHook(sse *sse.Server) {
l.log = l.log.Hook(&ServerSentEventHook{sse: sse})
}
func (l *DefaultLogger) SetLogLevel(level string) {
switch level {
case "INFO":
l.level = zerolog.InfoLevel
zerolog.SetGlobalLevel(zerolog.InfoLevel)
case "DEBUG":
l.level = zerolog.DebugLevel
zerolog.SetGlobalLevel(zerolog.DebugLevel)
case "ERROR":
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
l.level = zerolog.ErrorLevel
case "WARN":
zerolog.SetGlobalLevel(zerolog.WarnLevel)
l.level = zerolog.WarnLevel
case "TRACE":
l.level = zerolog.TraceLevel
zerolog.SetGlobalLevel(zerolog.TraceLevel)
default:
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
l.level = zerolog.Disabled
}
// setup console writer
consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}
writers := io.MultiWriter(consoleWriter)
// if logPath set create file writer
if cfg.LogPath != "" {
fileWriter := &lumberjack.Logger{
Filename: cfg.LogPath,
MaxSize: 100, // megabytes
MaxBackups: 3,
}
// overwrite writers
writers = io.MultiWriter(consoleWriter, fileWriter)
}
log.Logger = log.Hook(&ServerSentEventHook{sse: sse})
log.Logger = log.Output(writers)
// init a logger to use
//log := zerolog.New(os.Stdout)
// creates a *log.Logger with no level prefix
StdLogger = zstdlog.NewStdLogger(log.Logger)
// creates a *log.Logger with a level prefix
StdLeveledLogger = zstdlog.NewStdLoggerWithLevel(log.Logger, zerolog.TraceLevel)
}
// Log log something at fatal level.
func (l *DefaultLogger) Log() *zerolog.Event {
return l.log.Log().Time("time", time.Now())
}
// Fatal log something at fatal level. This will panic!
func (l *DefaultLogger) Fatal() *zerolog.Event {
return l.log.Fatal().Time("time", time.Now())
}
// Error log something at Error level
func (l *DefaultLogger) Error() *zerolog.Event {
return l.log.Error().Time("time", time.Now())
}
// Err log something at Err level
func (l *DefaultLogger) Err(err error) *zerolog.Event {
return l.log.Err(err).Time("time", time.Now())
}
// Warn log something at warning level.
func (l *DefaultLogger) Warn() *zerolog.Event {
return l.log.Warn().Time("time", time.Now())
}
// Info log something at fatal level.
func (l *DefaultLogger) Info() *zerolog.Event {
return l.log.Info().Time("time", time.Now())
}
// Debug log something at debug level.
func (l *DefaultLogger) Debug() *zerolog.Event {
return l.log.Debug().Time("time", time.Now())
}
// Trace log something at fatal level. This will panic!
func (l *DefaultLogger) Trace() *zerolog.Event {
return l.log.Trace().Time("time", time.Now())
}
// With log with context
func (l *DefaultLogger) With() zerolog.Context {
return l.log.With()
}

View file

@ -10,8 +10,6 @@ import (
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/rs/zerolog/log"
)
type DiscordMessage struct {
@ -33,7 +31,7 @@ type DiscordEmbedsFields struct {
Inline bool `json:"inline,omitempty"`
}
func discordNotification(event domain.EventsReleasePushed, webhookURL string) {
func (s *service) discordNotification(event domain.EventsReleasePushed, webhookURL string) {
t := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
@ -120,13 +118,13 @@ func discordNotification(event domain.EventsReleasePushed, webhookURL string) {
jsonData, err := json.Marshal(m)
if err != nil {
log.Error().Err(err).Msgf("discord client could not marshal data: %v", m)
s.log.Error().Err(err).Msgf("discord client could not marshal data: %v", m)
return
}
req, err := http.NewRequest(http.MethodPost, webhookURL, bytes.NewBuffer(jsonData))
if err != nil {
log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName)
s.log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName)
return
}
@ -135,13 +133,13 @@ func discordNotification(event domain.EventsReleasePushed, webhookURL string) {
res, err := client.Do(req)
if err != nil {
log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName)
s.log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName)
return
}
defer res.Body.Close()
log.Debug().Msg("notification successfully sent to discord")
s.log.Debug().Msg("notification successfully sent to discord")
return
}

View file

@ -3,7 +3,10 @@ package notification
import (
"context"
"fmt"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/containrrr/shoutrrr"
t "github.com/containrrr/shoutrrr/pkg/types"
)
@ -19,11 +22,13 @@ type Service interface {
}
type service struct {
log logger.Logger
repo domain.NotificationRepo
}
func NewService(repo domain.NotificationRepo) Service {
func NewService(log logger.Logger, repo domain.NotificationRepo) Service {
return &service{
log: log,
repo: repo,
}
}
@ -132,7 +137,7 @@ func (s *service) send(notifications []domain.Notification, event domain.EventsR
if evt == string(event.Status) {
switch n.Type {
case domain.NotificationTypeDiscord:
go discordNotification(event, n.Webhook)
go s.discordNotification(event, n.Webhook)
default:
return nil
}

View file

@ -8,8 +8,7 @@ import (
"github.com/autobrr/autobrr/internal/action"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/filter"
"github.com/rs/zerolog/log"
"github.com/autobrr/autobrr/internal/logger"
)
type Service interface {
@ -30,14 +29,16 @@ type actionClientTypeKey struct {
}
type service struct {
log logger.Logger
repo domain.ReleaseRepo
actionSvc action.Service
filterSvc filter.Service
}
func NewService(repo domain.ReleaseRepo, actionSvc action.Service, filterSvc filter.Service) Service {
func NewService(log logger.Logger, repo domain.ReleaseRepo, actionSvc action.Service, filterSvc filter.Service) Service {
return &service{
log: log,
repo: repo,
actionSvc: actionSvc,
filterSvc: filterSvc,
@ -85,7 +86,7 @@ func (s *service) Process(release *domain.Release) {
// get filters by priority
filters, err := s.filterSvc.FindByIndexerIdentifier(release.Indexer)
if err != nil {
log.Error().Err(err).Msgf("announce.Service.Process: error finding filters for indexer: %v", release.Indexer)
s.log.Error().Err(err).Msgf("announce.Service.Process: error finding filters for indexer: %v", release.Indexer)
return
}
@ -109,23 +110,23 @@ func (s *service) Process(release *domain.Release) {
// test filter
match, err := s.filterSvc.CheckFilter(f, release)
if err != nil {
log.Error().Err(err).Msg("announce.Service.Process: could not find filter")
s.log.Error().Err(err).Msg("announce.Service.Process: could not find filter")
return
}
if !match {
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, no match", release.Indexer, release.Filter.Name, release.TorrentName)
s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, no match", release.Indexer, release.Filter.Name, release.TorrentName)
continue
}
log.Info().Msgf("Matched '%v' (%v) for %v", release.TorrentName, release.Filter.Name, release.Indexer)
s.log.Info().Msgf("Matched '%v' (%v) for %v", release.TorrentName, release.Filter.Name, release.Indexer)
// save release here to only save those with rejections from actions instead of all releases
if release.ID == 0 {
release.FilterStatus = domain.ReleaseStatusFilterApproved
err = s.Store(context.Background(), release)
if err != nil {
log.Error().Err(err).Msgf("announce.Service.Process: error writing release to database: %+v", release)
s.log.Error().Err(err).Msgf("announce.Service.Process: error writing release to database: %+v", release)
return
}
}
@ -133,7 +134,7 @@ func (s *service) Process(release *domain.Release) {
// sleep for the delay period specified in the filter before running actions
delay := release.Filter.Delay
if delay > 0 {
log.Debug().Msgf("Delaying processing of '%v' (%v) for %v by %d seconds as specified in the filter", release.TorrentName, release.Filter.Name, release.Indexer, delay)
s.log.Debug().Msgf("Delaying processing of '%v' (%v) for %v by %d seconds as specified in the filter", release.TorrentName, release.Filter.Name, release.Indexer, delay)
time.Sleep(time.Duration(delay) * time.Second)
}
@ -143,22 +144,22 @@ func (s *service) Process(release *domain.Release) {
for _, a := range release.Filter.Actions {
// only run enabled actions
if !a.Enabled {
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action '%v' not enabled, skip", release.Indexer, release.Filter.Name, release.TorrentName, a.Name)
s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action '%v' not enabled, skip", release.Indexer, release.Filter.Name, release.TorrentName, a.Name)
continue
}
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v , run action: %v", release.Indexer, release.Filter.Name, release.TorrentName, a.Name)
s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v , run action: %v", release.Indexer, release.Filter.Name, release.TorrentName, a.Name)
// keep track of action clients to avoid sending the same thing all over again
_, tried := triedActionClients[actionClientTypeKey{Type: a.Type, ClientID: a.ClientID}]
if tried {
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action client already tried, skip", release.Indexer, release.Filter.Name, release.TorrentName)
s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action client already tried, skip", release.Indexer, release.Filter.Name, release.TorrentName)
continue
}
rejections, err = s.actionSvc.RunAction(a, *release)
if err != nil {
log.Error().Stack().Err(err).Msgf("announce.Service.Process: error running actions for filter: %v", release.Filter.Name)
s.log.Error().Stack().Err(err).Msgf("announce.Service.Process: error running actions for filter: %v", release.Filter.Name)
continue
}
@ -167,7 +168,7 @@ func (s *service) Process(release *domain.Release) {
triedActionClients[actionClientTypeKey{Type: a.Type, ClientID: a.ClientID}] = struct{}{}
// log something and fire events
log.Debug().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, rejected: %v", release.Indexer, release.Filter.Name, release.TorrentName, strings.Join(rejections, ", "))
s.log.Debug().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, rejected: %v", release.Indexer, release.Filter.Name, release.TorrentName, strings.Join(rejections, ", "))
}
// if no rejections consider action approved, run next

View file

@ -3,8 +3,9 @@ package scheduler
import (
"fmt"
"github.com/autobrr/autobrr/internal/logger"
"github.com/robfig/cron/v3"
"github.com/rs/zerolog/log"
)
type Service interface {
@ -16,13 +17,15 @@ type Service interface {
}
type service struct {
log logger.Logger
cron *cron.Cron
jobs map[string]cron.EntryID
}
func NewService() Service {
func NewService(log logger.Logger) Service {
return &service{
log: log,
cron: cron.New(cron.WithChain(
cron.Recover(cron.DefaultLogger),
)),
@ -31,14 +34,14 @@ func NewService() Service {
}
func (s *service) Start() {
log.Debug().Msg("scheduler.Start")
s.log.Debug().Msg("scheduler.Start")
s.cron.Start()
return
}
func (s *service) Stop() {
log.Debug().Msg("scheduler.Stop")
s.log.Debug().Msg("scheduler.Stop")
s.cron.Stop()
return
}
@ -51,7 +54,7 @@ func (s *service) AddJob(job cron.Job, interval string, identifier string) (int,
return 0, fmt.Errorf("scheduler: add job failed: %w", err)
}
log.Debug().Msgf("scheduler.AddJob: job successfully added: %v", id)
s.log.Debug().Msgf("scheduler.AddJob: job successfully added: %v", id)
// add to job map
s.jobs[identifier] = id
@ -75,7 +78,7 @@ func (s *service) RemoveJobByIdentifier(id string) error {
return nil
}
log.Debug().Msgf("scheduler.Remove: removing job: %v", id)
s.log.Debug().Msgf("scheduler.Remove: removing job: %v", id)
// remove from cron
s.cron.Remove(v)

View file

@ -6,12 +6,12 @@ import (
"github.com/autobrr/autobrr/internal/feed"
"github.com/autobrr/autobrr/internal/indexer"
"github.com/autobrr/autobrr/internal/irc"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/scheduler"
"github.com/rs/zerolog/log"
)
type Server struct {
log logger.Logger
Hostname string
Port int
@ -24,8 +24,9 @@ type Server struct {
lock sync.Mutex
}
func NewServer(ircSvc irc.Service, indexerSvc indexer.Service, feedSvc feed.Service, scheduler scheduler.Service) *Server {
func NewServer(log logger.Logger, ircSvc irc.Service, indexerSvc indexer.Service, feedSvc feed.Service, scheduler scheduler.Service) *Server {
return &Server{
log: log,
indexerService: indexerSvc,
ircService: ircSvc,
feedService: feedSvc,
@ -34,14 +35,14 @@ func NewServer(ircSvc irc.Service, indexerSvc indexer.Service, feedSvc feed.Serv
}
func (s *Server) Start() error {
log.Info().Msgf("Starting server. Listening on %v:%v", s.Hostname, s.Port)
s.log.Info().Msgf("Starting server. Listening on %v:%v", s.Hostname, s.Port)
// start cron scheduler
s.scheduler.Start()
// instantiate indexers
if err := s.indexerService.Start(); err != nil {
log.Error().Err(err).Msg("Could not start indexer service")
s.log.Error().Err(err).Msg("Could not start indexer service")
return err
}
@ -50,14 +51,14 @@ func (s *Server) Start() error {
// start torznab feeds
if err := s.feedService.Start(); err != nil {
log.Error().Err(err).Msg("Could not start feed service")
s.log.Error().Err(err).Msg("Could not start feed service")
}
return nil
}
func (s *Server) Shutdown() {
log.Info().Msg("Shutting down server")
s.log.Info().Msg("Shutting down server")
// stop all irc handlers
s.ircService.StopHandlers()

View file

@ -3,6 +3,7 @@ package user
import (
"context"
"errors"
"github.com/autobrr/autobrr/internal/domain"
)