Sharing: Add accounts table #11
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
parent
32f03ab149
commit
90dd094a21
9 changed files with 80 additions and 72 deletions
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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{},
|
||||
|
|
32
internal/entity/account.go
Normal file
32
internal/entity/account.go
Normal 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"`
|
||||
}
|
|
@ -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"`
|
||||
|
|
|
@ -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:"-"`
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
Loading…
Reference in a new issue