2020-02-02 00:31:09 +01:00
|
|
|
package entity
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2020-03-31 17:26:25 +02:00
|
|
|
"sort"
|
2020-02-02 00:31:09 +01:00
|
|
|
"time"
|
2020-03-28 15:29:17 +01:00
|
|
|
|
|
|
|
"github.com/photoprism/photoprism/internal/form"
|
2020-04-05 22:26:53 +02:00
|
|
|
"github.com/photoprism/photoprism/internal/remote"
|
|
|
|
"github.com/photoprism/photoprism/internal/remote/webdav"
|
2020-04-02 18:17:07 +02:00
|
|
|
"github.com/photoprism/photoprism/pkg/fs"
|
2020-03-28 15:29:17 +01:00
|
|
|
"github.com/ulule/deepcopier"
|
2020-02-02 00:31:09 +01:00
|
|
|
)
|
|
|
|
|
2020-04-04 17:19:34 +02:00
|
|
|
const (
|
|
|
|
AccountSyncStatusRefresh = "refresh"
|
|
|
|
AccountSyncStatusDownload = "download"
|
|
|
|
AccountSyncStatusUpload = "upload"
|
|
|
|
AccountSyncStatusSynced = "synced"
|
|
|
|
)
|
|
|
|
|
2020-06-01 09:45:24 +02:00
|
|
|
type Accounts []Account
|
|
|
|
|
2020-02-02 00:31:09 +01:00
|
|
|
// Account represents a remote service account for uploading, downloading or syncing media files.
|
|
|
|
type Account struct {
|
2020-04-04 17:19:34 +02:00
|
|
|
ID uint `gorm:"primary_key"`
|
2020-09-13 17:51:43 +02:00
|
|
|
AccName string `gorm:"type:VARCHAR(255);"`
|
|
|
|
AccOwner string `gorm:"type:VARCHAR(255);"`
|
|
|
|
AccURL string `gorm:"type:VARBINARY(512);"`
|
|
|
|
AccType string `gorm:"type:VARBINARY(255);"`
|
|
|
|
AccKey string `gorm:"type:VARBINARY(255);"`
|
|
|
|
AccUser string `gorm:"type:VARBINARY(255);"`
|
|
|
|
AccPass string `gorm:"type:VARBINARY(255);"`
|
|
|
|
AccError string `gorm:"type:VARBINARY(512);"`
|
2020-04-04 17:19:34 +02:00
|
|
|
AccErrors int
|
|
|
|
AccShare bool
|
|
|
|
AccSync bool
|
|
|
|
RetryLimit int
|
2020-09-13 17:51:43 +02:00
|
|
|
SharePath string `gorm:"type:VARBINARY(255);"`
|
|
|
|
ShareSize string `gorm:"type:VARBINARY(16);"`
|
2020-04-04 17:19:34 +02:00
|
|
|
ShareExpires int
|
2020-09-13 17:51:43 +02:00
|
|
|
SyncPath string `gorm:"type:VARBINARY(255);"`
|
|
|
|
SyncStatus string `gorm:"type:VARBINARY(16);"`
|
2020-04-04 17:19:34 +02:00
|
|
|
SyncInterval int
|
|
|
|
SyncDate sql.NullTime `deepcopier:"skip"`
|
|
|
|
SyncUpload bool
|
|
|
|
SyncDownload bool
|
|
|
|
SyncFilenames bool
|
|
|
|
SyncRaw bool
|
|
|
|
CreatedAt time.Time `deepcopier:"skip"`
|
|
|
|
UpdatedAt time.Time `deepcopier:"skip"`
|
|
|
|
DeletedAt *time.Time `deepcopier:"skip" sql:"index"`
|
2020-02-02 00:31:09 +01:00
|
|
|
}
|
2020-03-28 15:29:17 +01:00
|
|
|
|
|
|
|
// CreateAccount creates a new account entity in the database.
|
2020-04-30 20:07:03 +02:00
|
|
|
func CreateAccount(form form.Account) (model *Account, err error) {
|
2020-04-04 17:19:34 +02:00
|
|
|
model = &Account{
|
|
|
|
ShareSize: "",
|
|
|
|
ShareExpires: 0,
|
|
|
|
RetryLimit: 3,
|
|
|
|
SyncStatus: AccountSyncStatusRefresh,
|
|
|
|
}
|
2020-03-28 15:29:17 +01:00
|
|
|
|
2020-05-26 11:00:39 +02:00
|
|
|
err = model.SaveForm(form)
|
2020-03-28 15:29:17 +01:00
|
|
|
|
|
|
|
return model, err
|
|
|
|
}
|
|
|
|
|
2020-05-22 16:29:12 +02:00
|
|
|
// Saves the entity using form data and stores it in the database.
|
2020-05-26 11:00:39 +02:00
|
|
|
func (m *Account) SaveForm(form form.Account) error {
|
2020-04-30 20:07:03 +02:00
|
|
|
db := Db()
|
|
|
|
|
2020-03-28 15:29:17 +01:00
|
|
|
if err := deepcopier.Copy(m).From(form); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-04-05 22:26:53 +02:00
|
|
|
if m.AccType != string(remote.ServiceWebDAV) {
|
2020-03-30 09:17:46 +02:00
|
|
|
// TODO: Only WebDAV supported at the moment
|
|
|
|
m.AccShare = false
|
|
|
|
m.AccSync = false
|
|
|
|
}
|
|
|
|
|
2020-04-06 22:09:45 +02:00
|
|
|
// Set defaults
|
2020-03-30 09:17:46 +02:00
|
|
|
if m.SharePath == "" {
|
|
|
|
m.SharePath = "/"
|
|
|
|
}
|
|
|
|
|
|
|
|
if m.SyncPath == "" {
|
|
|
|
m.SyncPath = "/"
|
|
|
|
}
|
|
|
|
|
2020-04-06 22:09:45 +02:00
|
|
|
// Refresh after performing changes
|
|
|
|
if m.AccSync && m.SyncStatus == AccountSyncStatusSynced {
|
|
|
|
m.SyncStatus = AccountSyncStatusRefresh
|
|
|
|
}
|
|
|
|
|
2020-03-28 15:29:17 +01:00
|
|
|
return db.Save(m).Error
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete deletes the entity from the database.
|
2020-04-30 20:07:03 +02:00
|
|
|
func (m *Account) Delete() error {
|
|
|
|
return Db().Delete(m).Error
|
2020-03-28 15:29:17 +01:00
|
|
|
}
|
2020-03-31 17:26:25 +02:00
|
|
|
|
2020-04-02 18:17:07 +02:00
|
|
|
// Directories returns a list of directories or albums in an account.
|
|
|
|
func (m *Account) Directories() (result fs.FileInfos, err error) {
|
2020-04-05 22:26:53 +02:00
|
|
|
if m.AccType == remote.ServiceWebDAV {
|
2020-04-03 18:08:49 +02:00
|
|
|
c := webdav.New(m.AccURL, m.AccUser, m.AccPass)
|
2020-12-05 01:24:33 +01:00
|
|
|
result, err = c.Directories("/", true, webdav.SyncTimeout)
|
2020-03-31 17:26:25 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 18:17:07 +02:00
|
|
|
sort.Sort(result)
|
2020-03-31 17:26:25 +02:00
|
|
|
|
|
|
|
return result, err
|
|
|
|
}
|
2020-05-26 11:00:39 +02:00
|
|
|
|
|
|
|
// Updates multiple columns in the database.
|
|
|
|
func (m *Account) Updates(values interface{}) error {
|
|
|
|
return UnscopedDb().Model(m).UpdateColumns(values).Error
|
|
|
|
}
|
|
|
|
|
|
|
|
// Updates a column in the database.
|
|
|
|
func (m *Account) Update(attr string, value interface{}) error {
|
|
|
|
return UnscopedDb().Model(m).UpdateColumn(attr, value).Error
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save updates the existing or inserts a new row.
|
|
|
|
func (m *Account) Save() error {
|
|
|
|
return Db().Save(m).Error
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create inserts a new row to the database.
|
|
|
|
func (m *Account) Create() error {
|
|
|
|
return Db().Create(m).Error
|
|
|
|
}
|