Files
photoprism/internal/entity/album_yaml.go
2025-03-27 16:42:24 +01:00

139 lines
3.2 KiB
Go

package entity
import (
"fmt"
"os"
"path/filepath"
"sync"
"time"
"gopkg.in/yaml.v2"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/fs"
)
var albumYamlMutex = sync.Mutex{}
// Yaml returns album data as YAML string.
func (m *Album) Yaml() (out []byte, err error) {
m.CreatedAt = m.CreatedAt.UTC().Truncate(time.Second)
m.UpdatedAt = m.UpdatedAt.UTC().Truncate(time.Second)
if err = Db().Model(m).Association("Photos").Find(&m.Photos).Error; err != nil {
log.Errorf("album: %s (yaml)", err)
return out, err
}
return yaml.Marshal(m)
}
// SaveAsYaml writes the album metadata to a YAML backup file with the specified filename.
func (m *Album) SaveAsYaml(fileName string) error {
if m == nil {
return fmt.Errorf("album entity is nil - you may have found a bug")
} else if m.AlbumUID == "" {
return fmt.Errorf("album uid is empty")
} else if fileName == "" {
return fmt.Errorf("yaml filename is empty")
}
data, err := m.Yaml()
if err != nil {
return err
}
// Make sure directory exists.
if err = fs.MkdirAll(filepath.Dir(fileName)); err != nil {
return err
}
albumYamlMutex.Lock()
defer albumYamlMutex.Unlock()
// Write YAML data to file.
if err = fs.WriteFile(fileName, data); err != nil {
return err
}
return nil
}
// YamlFileName returns the absolute file path for the YAML backup file.
func (m *Album) YamlFileName(backupPath string) (absolute, relative string, err error) {
if m == nil {
return "", "", fmt.Errorf("album entity is nil - you may have found a bug")
} else if m.AlbumUID == "" {
return "", "", fmt.Errorf("album uid is empty")
}
relative = filepath.Join(m.AlbumType, m.AlbumUID+fs.ExtYaml)
if backupPath == "" {
return "", relative, fmt.Errorf("backup path is empty")
}
absolute = filepath.Join(backupPath, relative)
return absolute, relative, err
}
// SaveBackupYaml writes the album metadata to a YAML backup file based on the specified storage paths.
func (m *Album) SaveBackupYaml(backupPath string) error {
if m == nil {
return fmt.Errorf("album entity is nil - you may have found a bug")
} else if m.AlbumUID == "" {
return fmt.Errorf("album uid is empty")
} else if backupPath == "" {
return fmt.Errorf("backup path is empty")
}
// Get album YAML backup filename.
fileName, relName, err := m.YamlFileName(backupPath)
if err != nil {
log.Warnf("album: %s (save %s)", err, clean.Log(relName))
return err
}
var action string
if fs.FileExists(fileName) {
action = "update"
} else {
action = "create"
}
// Write album metadata to YAML backup file.
if err = m.SaveAsYaml(fileName); err != nil {
log.Warnf("album: %s (%s %s)", err, action, clean.Log(relName))
return err
} else {
log.Debugf("album: %sd backup file %s", action, clean.Log(relName))
}
return nil
}
// LoadFromYaml restores the album metadata from a YAML backup file.
func (m *Album) LoadFromYaml(fileName string) error {
if m == nil {
return fmt.Errorf("album entity is nil - you may have found a bug")
} else if fileName == "" {
return fmt.Errorf("yaml filename is empty")
}
data, err := os.ReadFile(fileName)
if err != nil {
return err
}
if err = yaml.Unmarshal(data, m); err != nil {
return err
}
return nil
}