feat: show new updates in dashboard (#690)

* feat: show new update banner

* feat(http): add request logger

* refactor: updates checker

* feat: make update check optional

* fix: empty releases

* add toggle switch for update checks

* feat: toggle updates check from settings

* feat: toggle updates check from settings

* feat: check on toggle enabled

---------

Co-authored-by: soup <soup@r4tio.dev>
This commit is contained in:
ze0s 2023-02-05 18:44:11 +01:00 committed by GitHub
parent 3fdd7cf5e4
commit 2917a7d42d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 687 additions and 121 deletions

View file

@ -6,46 +6,42 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/notification"
"github.com/autobrr/autobrr/pkg/version"
"github.com/autobrr/autobrr/internal/update"
"github.com/rs/zerolog"
)
type CheckUpdatesJob struct {
Name string
Log zerolog.Logger
Version string
NotifSvc notification.Service
Name string
Log zerolog.Logger
Version string
NotifSvc notification.Service
updateService *update.Service
lastCheckVersion string
}
func (j *CheckUpdatesJob) Run() {
v := version.Checker{
Owner: "autobrr",
Repo: "autobrr",
}
newAvailable, newVersion, err := v.CheckNewVersion(context.TODO(), j.Version)
newRelease, err := j.updateService.CheckUpdateAvailable(context.TODO())
if err != nil {
j.Log.Error().Err(err).Msg("could not check for new release")
return
}
if newAvailable {
j.Log.Info().Msgf("a new release has been found: %v Consider updating.", newVersion)
if newRelease != nil {
// this is not persisted so this can trigger more than once
// lets check if we have different versions between runs
if newVersion != j.lastCheckVersion {
if newRelease.TagName != j.lastCheckVersion {
j.Log.Info().Msgf("a new release has been found: %v Consider updating.", newRelease.TagName)
j.NotifSvc.Send(domain.NotificationEventAppUpdateAvailable, domain.NotificationPayload{
Subject: "New update available!",
Message: newVersion,
Message: newRelease.TagName,
Event: domain.NotificationEventAppUpdateAvailable,
Timestamp: time.Now(),
})
}
j.lastCheckVersion = newVersion
j.lastCheckVersion = newRelease.TagName
}
}

View file

@ -4,8 +4,10 @@ import (
"sync"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/notification"
"github.com/autobrr/autobrr/internal/update"
"github.com/robfig/cron/v3"
"github.com/rs/zerolog"
@ -21,19 +23,22 @@ type Service interface {
type service struct {
log zerolog.Logger
config *domain.Config
version string
notificationSvc notification.Service
updateSvc *update.Service
cron *cron.Cron
jobs map[string]cron.EntryID
m sync.RWMutex
}
func NewService(log logger.Logger, version string, notificationSvc notification.Service) Service {
func NewService(log logger.Logger, config *domain.Config, notificationSvc notification.Service, updateSvc *update.Service) Service {
return &service{
log: log.With().Str("module", "scheduler").Logger(),
version: version,
config: config,
notificationSvc: notificationSvc,
updateSvc: updateSvc,
cron: cron.New(cron.WithChain(
cron.Recover(cron.DefaultLogger),
)),
@ -56,16 +61,19 @@ func (s *service) Start() {
func (s *service) addAppJobs() {
time.Sleep(5 * time.Second)
checkUpdates := &CheckUpdatesJob{
Name: "app-check-updates",
Log: s.log.With().Str("job", "app-check-updates").Logger(),
Version: s.version,
NotifSvc: s.notificationSvc,
lastCheckVersion: "",
}
if s.config.CheckForUpdates {
checkUpdates := &CheckUpdatesJob{
Name: "app-check-updates",
Log: s.log.With().Str("job", "app-check-updates").Logger(),
Version: s.version,
NotifSvc: s.notificationSvc,
updateService: s.updateSvc,
lastCheckVersion: s.version,
}
if id, err := s.AddJob(checkUpdates, time.Duration(36*time.Hour), "app-check-updates"); err != nil {
s.log.Error().Err(err).Msgf("scheduler.addAppJobs: error adding job: %v", id)
if id, err := s.AddJob(checkUpdates, 2*time.Hour, "app-check-updates"); err != nil {
s.log.Error().Err(err).Msgf("scheduler.addAppJobs: error adding job: %v", id)
}
}
}
@ -81,7 +89,7 @@ func (s *service) AddJob(job cron.Job, interval time.Duration, identifier string
cron.SkipIfStillRunning(cron.DiscardLogger)).Then(job),
)
s.log.Debug().Msgf("scheduler.AddJob: job successfully added: %v", id)
s.log.Debug().Msgf("scheduler.AddJob: job successfully added: %s id %d", identifier, id)
s.m.Lock()
// add to job map