Sharing: Add accounts table #11

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-02-02 00:31:09 +01:00
parent 32f03ab149
commit 90dd094a21
9 changed files with 80 additions and 72 deletions

View file

@ -3,6 +3,7 @@ package api
import (
"archive/zip"
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
@ -427,21 +428,31 @@ func AlbumThumbnail(router *gin.RouterGroup, conf *config.Config) {
router.GET("/albums/:uuid/thumbnail/:type", func(c *gin.Context) {
typeName := c.Param("type")
uuid := c.Param("uuid")
start := time.Now()
thumbType, ok := thumb.Types[typeName]
if !ok {
log.Errorf("thumbs: invalid type \"%s\"", typeName)
log.Errorf("album: invalid thumb type %s", typeName)
c.Data(http.StatusBadRequest, "image/svg+xml", photoIconSvg)
return
}
q := query.New(conf.OriginalsPath(), conf.Db())
gc := conf.Cache()
cacheKey := fmt.Sprintf("album-thumbnail:%s:%s", uuid, typeName)
if cacheData, ok := gc.Get(cacheKey); ok {
log.Debugf("album: %s cache hit [%s]", cacheKey, time.Since(start))
c.Data(http.StatusOK, "image/jpeg", cacheData.([]byte))
return
}
f, err := q.FindAlbumThumbByUUID(uuid)
if err != nil {
log.Debugf("album has no photos yet, using generic thumb image: %s", uuid)
log.Debugf("album: no photos yet, using generic image for %s", uuid)
c.Data(http.StatusOK, "image/svg+xml", albumIconSvg)
return
}
@ -449,7 +460,7 @@ func AlbumThumbnail(router *gin.RouterGroup, conf *config.Config) {
fileName := path.Join(conf.OriginalsPath(), f.FileName)
if !fs.FileExists(fileName) {
log.Errorf("could not find original for thumbnail: %s", fileName)
log.Errorf("album: could not find original for %s", fileName)
c.Data(http.StatusNotFound, "image/svg+xml", photoIconSvg)
// Set missing flag so that the file doesn't show up in search results anymore
@ -472,9 +483,21 @@ func AlbumThumbnail(router *gin.RouterGroup, conf *config.Config) {
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", f.DownloadFileName()))
}
c.File(thumbnail)
thumbData, err := ioutil.ReadFile(thumbnail)
if err != nil {
log.Errorf("album: %s", err)
c.Data(http.StatusOK, "image/svg+xml", albumIconSvg)
return
}
gc.Set(cacheKey, thumbData, time.Hour)
log.Debugf("album: %s cached [%s]", cacheKey, time.Since(start))
c.Data(http.StatusOK, "image/jpeg", thumbData)
} else {
log.Errorf("could not create thumbnail: %s", err)
log.Errorf("album: %s", err)
c.Data(http.StatusBadRequest, "image/svg+xml", photoIconSvg)
}
})

View file

@ -132,7 +132,7 @@ func LabelThumbnail(router *gin.RouterGroup, conf *config.Config) {
thumbType, ok := thumb.Types[typeName]
if !ok {
log.Errorf("thumbs: invalid type \"%s\"", typeName)
log.Errorf("label: invalid thumb type \"%s\"", typeName)
c.Data(http.StatusOK, "image/svg+xml", labelIconSvg)
return
}
@ -143,7 +143,7 @@ func LabelThumbnail(router *gin.RouterGroup, conf *config.Config) {
cacheKey := fmt.Sprintf("label-thumbnail:%s:%s", labelUUID, typeName)
if cacheData, ok := gc.Get(cacheKey); ok {
log.Debugf("%s cache hit [%s]", cacheKey, time.Since(start))
log.Debugf("label: %s cache hit [%s]", cacheKey, time.Since(start))
c.Data(http.StatusOK, "image/jpeg", cacheData.([]byte))
return
}
@ -159,7 +159,7 @@ func LabelThumbnail(router *gin.RouterGroup, conf *config.Config) {
fileName := path.Join(conf.OriginalsPath(), f.FileName)
if !fs.FileExists(fileName) {
log.Errorf("could not find original for thumbnail: %s", fileName)
log.Errorf("label: could not find original for %s", fileName)
c.Data(http.StatusOK, "image/svg+xml", labelIconSvg)
// Set missing flag so that the file doesn't show up in search results anymore
@ -181,18 +181,18 @@ func LabelThumbnail(router *gin.RouterGroup, conf *config.Config) {
thumbData, err := ioutil.ReadFile(thumbnail)
if err != nil {
log.Errorf("could not read thumbnail: %s", err)
log.Errorf("label: %s", err)
c.Data(http.StatusOK, "image/svg+xml", labelIconSvg)
return
}
gc.Set(cacheKey, thumbData, time.Hour*4)
log.Debugf("%s cached [%s]", cacheKey, time.Since(start))
log.Debugf("label: %s cached [%s]", cacheKey, time.Since(start))
c.Data(http.StatusOK, "image/jpeg", thumbData)
} else {
log.Errorf("could not create thumbnail: %s", err)
log.Errorf("label: %s", err)
c.Data(http.StatusOK, "image/svg+xml", labelIconSvg)
return

View file

@ -25,7 +25,7 @@ func GetThumbnail(router *gin.RouterGroup, conf *config.Config) {
thumbType, ok := thumb.Types[typeName]
if !ok {
log.Errorf("thumbs: invalid type \"%s\"", typeName)
log.Errorf("photo: invalid thumb type \"%s\"", typeName)
c.Data(http.StatusBadRequest, "image/svg+xml", photoIconSvg)
return
}
@ -47,7 +47,7 @@ func GetThumbnail(router *gin.RouterGroup, conf *config.Config) {
fileName := path.Join(conf.OriginalsPath(), f.FileName)
if !fs.FileExists(fileName) {
log.Errorf("could not find original for thumbnail: %s", fileName)
log.Errorf("photo: could not find original for %s", fileName)
c.Data(http.StatusNotFound, "image/svg+xml", photoIconSvg)
// Set missing flag so that the file doesn't show up in search results anymore
@ -72,6 +72,8 @@ func GetThumbnail(router *gin.RouterGroup, conf *config.Config) {
c.File(thumbnail)
} else {
log.Errorf("photo: %s", err)
f.FileError = err.Error()
db.Save(&f)

View file

@ -60,6 +60,7 @@ func (c *Config) MigrateDb() {
db := c.Db()
db.AutoMigrate(
&entity.Account{},
&entity.File{},
&entity.Photo{},
&entity.Event{},
@ -68,7 +69,6 @@ func (c *Config) MigrateDb() {
&entity.Camera{},
&entity.Lens{},
&entity.Country{},
&entity.Share{},
&entity.Album{},
&entity.PhotoAlbum{},
@ -154,6 +154,7 @@ func (c *Config) DropTables() {
db := c.Db()
db.DropTableIfExists(
&entity.Account{},
&entity.File{},
&entity.Photo{},
&entity.Event{},
@ -162,7 +163,6 @@ func (c *Config) DropTables() {
&entity.Camera{},
&entity.Lens{},
&entity.Country{},
&entity.Share{},
&entity.Album{},
&entity.PhotoAlbum{},

View file

@ -0,0 +1,32 @@
package entity
import (
"database/sql"
"time"
)
// Account represents a remote service account for uploading, downloading or syncing media files.
type Account struct {
ID uint `gorm:"primary_key"`
Name string `gorm:"type:varchar(128);"`
URL string `gorm:"type:varbinary(512);"`
Protocol string `gorm:"type:varbinary(256);"`
ApiKey string `gorm:"type:varbinary(256);"`
Username string `gorm:"type:varbinary(256);"`
Password string `gorm:"type:varbinary(256);"`
LastError string `gorm:"type:varbinary(256);"`
IgnoreErrors bool
PushSize string `gorm:"type:varbinary(16);"`
PushExif bool
PushDelete bool
PushSidecar bool
SyncPush bool
SyncPull bool
SyncPaused int
SyncInterval int
SyncRetry int
SyncedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}

View file

@ -1,6 +1,7 @@
package entity
import (
"database/sql"
"strings"
"time"
@ -18,14 +19,11 @@ type Album struct {
AlbumName string `gorm:"type:varchar(128);"`
AlbumDescription string `gorm:"type:text;"`
AlbumNotes string `gorm:"type:text;"`
AlbumViews uint
AlbumFavorite bool
AlbumPublic bool
AlbumLat float64
AlbumLng float64
AlbumRadius float64
AlbumOrder string `gorm:"type:varchar(16);"`
AlbumTemplate string `gorm:"type:varchar(128);"`
AlbumOrder string `gorm:"type:varbinary(32);"`
ShareTemplate string `gorm:"type:varbinary(256);"`
SharePassword string `gorm:"type:varbinary(256);"`
ShareExpires sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`

View file

@ -9,7 +9,7 @@ import (
"github.com/photoprism/photoprism/pkg/txt"
)
// A photo can have multiple images and sidecar files
// Photo represents a photo that can have multiple image or sidecar files.
type Photo struct {
ID uint `gorm:"primary_key"`
TakenAt time.Time `gorm:"type:datetime;index:idx_photos_taken_uuid;" json:"TakenAt"`
@ -36,6 +36,7 @@ type Photo struct {
LensID uint `gorm:"index:idx_photos_camera_lens;" json:"LensID"`
LocationID string `gorm:"type:varbinary(16);index;" json:"LocationID"`
PlaceID string `gorm:"type:varbinary(16);index;" json:"PlaceID"`
AccountID uint `json:"AccountID"`
LocationEstimated bool `json:"LocationEstimated"`
PhotoCountry string `gorm:"index:idx_photos_country_year_month;" json:"PhotoCountry"`
PhotoYear int `gorm:"index:idx_photos_country_year_month;"`
@ -50,6 +51,7 @@ type Photo struct {
Lens *Lens `json:"Lens"`
Location *Location `json:"-"`
Place *Place `json:"-"`
Account *Account `json:"-"`
Files []File
Labels []PhotoLabel
Keywords []Keyword `json:"-"`

View file

@ -1,35 +0,0 @@
package entity
import (
"time"
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/pkg/rnd"
)
// Shared photos and/or albums
type Share struct {
UUID string `gorm:"type:varbinary(36);primary_key;auto_increment:false"`
ShareUUID string `gorm:"type:varbinary(36);index;"`
ShareViews uint
ShareUrl string `gorm:"type:varchar(64);"`
SharePassword string `gorm:"type:varbinary(200);"`
ShareExpires time.Time
Photo *Photo
Album *Album
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
func (Share) TableName() string {
return "shares"
}
func (s *Share) BeforeCreate(scope *gorm.Scope) error {
if err := scope.SetColumn("ShareUUID", rnd.PPID('s')); err != nil {
return err
}
return nil
}

View file

@ -1,14 +0,0 @@
package entity
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestShare_TableName(t *testing.T) {
share := &Share{}
tableName := share.TableName()
assert.Equal(t, "shares", tableName)
}