Files
photoprism/internal/workers/backup.go
2024-07-02 06:32:17 +02:00

88 lines
2.1 KiB
Go

package workers
import (
"errors"
"fmt"
"runtime/debug"
"time"
"github.com/dustin/go-humanize/english"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/mutex"
"github.com/photoprism/photoprism/internal/photoprism/backup"
)
// Backup represents a background backup worker.
type Backup struct {
conf *config.Config
}
// NewBackup returns a new Backup worker.
func NewBackup(conf *config.Config) *Backup {
return &Backup{conf: conf}
}
// StartScheduled starts a scheduled run of the backup worker based on the current configuration.
func (w *Backup) StartScheduled() {
if err := w.Start(w.conf.BackupDatabase(), w.conf.BackupAlbums(), true, w.conf.BackupRetain()); err != nil {
log.Errorf("scheduler: %s (backup)", err)
}
}
// Start creates index and album backups based on the current configuration.
func (w *Backup) Start(database, albums bool, force bool, retain int) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("backup: %s (worker panic)\nstack: %s", r, debug.Stack())
log.Error(err)
}
}()
// Return if no backups should be created.
if !database && !albums {
return nil
}
// Return error if backup worker is already running.
if err = mutex.BackupWorker.Start(); err != nil {
return err
}
defer mutex.BackupWorker.Stop()
// Start creating backups.
start := time.Now()
// Create database backup.
if database {
databasePath := w.conf.BackupDatabasePath()
if err = backup.Database(databasePath, "", false, force, retain); err != nil {
log.Errorf("backup: %s (database)", err)
}
}
if mutex.BackupWorker.Canceled() {
return errors.New("canceled")
}
// Create albums backup.
if albums {
albumsPath := w.conf.BackupAlbumsPath()
if count, backupErr := backup.Albums(albumsPath, false); backupErr != nil {
log.Errorf("backup: %s (albums)", backupErr.Error())
} else if count > 0 {
log.Infof("backup: saved %s", english.Plural(count, "album backup", "album backups"))
}
}
elapsed := time.Since(start)
// Log success message.
log.Infof("backup: completed in %s", elapsed)
return nil
}