Introduce thumbnail filtering options.

This commit is contained in:
PJ-Watson
2022-08-05 19:37:55 +01:00
parent 446ef9a464
commit 5c4eeef870
11 changed files with 508 additions and 28 deletions

View File

@@ -151,30 +151,31 @@ type ComplexityRoot struct {
}
Mutation struct {
AuthorizeUser func(childComplexity int, username string, password string) int
ChangeUserPreferences func(childComplexity int, language *string) int
CombineFaceGroups func(childComplexity int, destinationFaceGroupID int, sourceFaceGroupID int) int
CreateUser func(childComplexity int, username string, password *string, admin bool) int
DeleteShareToken func(childComplexity int, token string) int
DeleteUser func(childComplexity int, id int) int
DetachImageFaces func(childComplexity int, imageFaceIDs []int) int
FavoriteMedia func(childComplexity int, mediaID int, favorite bool) int
InitialSetupWizard func(childComplexity int, username string, password string, rootPath string) int
MoveImageFaces func(childComplexity int, imageFaceIDs []int, destinationFaceGroupID int) int
ProtectShareToken func(childComplexity int, token string, password *string) int
RecognizeUnlabeledFaces func(childComplexity int) int
ResetAlbumCover func(childComplexity int, albumID int) int
ScanAll func(childComplexity int) int
ScanUser func(childComplexity int, userID int) int
SetAlbumCover func(childComplexity int, coverID int) int
SetFaceGroupLabel func(childComplexity int, faceGroupID int, label *string) int
SetPeriodicScanInterval func(childComplexity int, interval int) int
SetScannerConcurrentWorkers func(childComplexity int, workers int) int
ShareAlbum func(childComplexity int, albumID int, expire *time.Time, password *string) int
ShareMedia func(childComplexity int, mediaID int, expire *time.Time, password *string) int
UpdateUser func(childComplexity int, id int, username *string, password *string, admin *bool) int
UserAddRootPath func(childComplexity int, id int, rootPath string) int
UserRemoveRootAlbum func(childComplexity int, userID int, albumID int) int
AuthorizeUser func(childComplexity int, username string, password string) int
ChangeUserPreferences func(childComplexity int, language *string) int
CombineFaceGroups func(childComplexity int, destinationFaceGroupID int, sourceFaceGroupID int) int
CreateUser func(childComplexity int, username string, password *string, admin bool) int
DeleteShareToken func(childComplexity int, token string) int
DeleteUser func(childComplexity int, id int) int
DetachImageFaces func(childComplexity int, imageFaceIDs []int) int
FavoriteMedia func(childComplexity int, mediaID int, favorite bool) int
InitialSetupWizard func(childComplexity int, username string, password string, rootPath string) int
MoveImageFaces func(childComplexity int, imageFaceIDs []int, destinationFaceGroupID int) int
ProtectShareToken func(childComplexity int, token string, password *string) int
RecognizeUnlabeledFaces func(childComplexity int) int
ResetAlbumCover func(childComplexity int, albumID int) int
ScanAll func(childComplexity int) int
ScanUser func(childComplexity int, userID int) int
SetAlbumCover func(childComplexity int, coverID int) int
SetFaceGroupLabel func(childComplexity int, faceGroupID int, label *string) int
SetPeriodicScanInterval func(childComplexity int, interval int) int
SetScannerConcurrentWorkers func(childComplexity int, workers int) int
SetThumbnailDownsampleMethod func(childComplexity int, method int) int
ShareAlbum func(childComplexity int, albumID int, expire *time.Time, password *string) int
ShareMedia func(childComplexity int, mediaID int, expire *time.Time, password *string) int
UpdateUser func(childComplexity int, id int, username *string, password *string, admin *bool) int
UserAddRootPath func(childComplexity int, id int, rootPath string) int
UserRemoveRootAlbum func(childComplexity int, userID int, albumID int) int
}
Notification struct {
@@ -236,6 +237,7 @@ type ComplexityRoot struct {
FaceDetectionEnabled func(childComplexity int) int
InitialSetup func(childComplexity int) int
PeriodicScanInterval func(childComplexity int) int
ThumbnailMethod func(childComplexity int) int
}
Subscription struct {
@@ -326,6 +328,7 @@ type MutationResolver interface {
UserRemoveRootAlbum(ctx context.Context, userID int, albumID int) (*models.Album, error)
SetPeriodicScanInterval(ctx context.Context, interval int) (int, error)
SetScannerConcurrentWorkers(ctx context.Context, workers int) (int, error)
SetThumbnailDownsampleMethod(ctx context.Context, method int) (int, error)
ChangeUserPreferences(ctx context.Context, language *string) (*models.UserPreferences, error)
ResetAlbumCover(ctx context.Context, albumID int) (*models.Album, error)
SetAlbumCover(ctx context.Context, coverID int) (*models.Album, error)
@@ -1057,6 +1060,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.SetScannerConcurrentWorkers(childComplexity, args["workers"].(int)), true
case "Mutation.setThumbnailDownsampleMethod":
if e.complexity.Mutation.SetThumbnailDownsampleMethod == nil {
break
}
args, err := ec.field_Mutation_setThumbnailDownsampleMethod_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.SetThumbnailDownsampleMethod(childComplexity, args["method"].(int)), true
case "Mutation.shareAlbum":
if e.complexity.Mutation.ShareAlbum == nil {
break
@@ -1478,6 +1493,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.SiteInfo.PeriodicScanInterval(childComplexity), true
case "SiteInfo.thumbnailMethod":
if e.complexity.SiteInfo.ThumbnailMethod == nil {
break
}
return e.complexity.SiteInfo.ThumbnailMethod(childComplexity), true
case "Subscription.notification":
if e.complexity.Subscription.Notification == nil {
break
@@ -2156,6 +2178,21 @@ func (ec *executionContext) field_Mutation_setScannerConcurrentWorkers_args(ctx
return args, nil
}
func (ec *executionContext) field_Mutation_setThumbnailDownsampleMethod_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 int
if tmp, ok := rawArgs["method"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("method"))
arg0, err = ec.unmarshalNInt2int(ctx, tmp)
if err != nil {
return nil, err
}
}
args["method"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_shareAlbum_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -7158,6 +7195,81 @@ func (ec *executionContext) fieldContext_Mutation_setScannerConcurrentWorkers(ct
return fc, nil
}
func (ec *executionContext) _Mutation_setThumbnailDownsampleMethod(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_setThumbnailDownsampleMethod(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().SetThumbnailDownsampleMethod(rctx, fc.Args["method"].(int))
}
directive1 := func(ctx context.Context) (interface{}, error) {
if ec.directives.IsAdmin == nil {
return nil, errors.New("directive isAdmin is not implemented")
}
return ec.directives.IsAdmin(ctx, nil, directive0)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(int); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be int`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(int)
fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_setThumbnailDownsampleMethod(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Int does not have child fields")
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Mutation_setThumbnailDownsampleMethod_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return
}
return fc, nil
}
func (ec *executionContext) _Mutation_changeUserPreferences(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_changeUserPreferences(ctx, field)
if err != nil {
@@ -8240,6 +8352,8 @@ func (ec *executionContext) fieldContext_Query_siteInfo(ctx context.Context, fie
return ec.fieldContext_SiteInfo_periodicScanInterval(ctx, field)
case "concurrentWorkers":
return ec.fieldContext_SiteInfo_concurrentWorkers(ctx, field)
case "thumbnailMethod":
return ec.fieldContext_SiteInfo_thumbnailMethod(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type SiteInfo", field.Name)
},
@@ -10584,6 +10698,70 @@ func (ec *executionContext) fieldContext_SiteInfo_concurrentWorkers(ctx context.
return fc, nil
}
func (ec *executionContext) _SiteInfo_thumbnailMethod(ctx context.Context, field graphql.CollectedField, obj *models.SiteInfo) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SiteInfo_thumbnailMethod(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ThumbnailMethod, nil
}
directive1 := func(ctx context.Context) (interface{}, error) {
if ec.directives.IsAdmin == nil {
return nil, errors.New("directive isAdmin is not implemented")
}
return ec.directives.IsAdmin(ctx, obj, directive0)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(int); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be int`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(int)
fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_SiteInfo_thumbnailMethod(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "SiteInfo",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Int does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Subscription_notification(ctx context.Context, field graphql.CollectedField) (ret func(ctx context.Context) graphql.Marshaler) {
fc, err := ec.fieldContext_Subscription_notification(ctx, field)
if err != nil {
@@ -14625,6 +14803,15 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
return ec._Mutation_setScannerConcurrentWorkers(ctx, field)
})
if out.Values[i] == graphql.Null {
invalids++
}
case "setThumbnailDownsampleMethod":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_setThumbnailDownsampleMethod(ctx, field)
})
if out.Values[i] == graphql.Null {
invalids++
}
@@ -15419,6 +15606,13 @@ func (ec *executionContext) _SiteInfo(ctx context.Context, sel ast.SelectionSet,
out.Values[i] = ec._SiteInfo_concurrentWorkers(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "thumbnailMethod":
out.Values[i] = ec._SiteInfo_thumbnailMethod(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}

View File

@@ -10,6 +10,7 @@ type SiteInfo struct {
InitialSetup bool `gorm:"not null"`
PeriodicScanInterval int `gorm:"not null"`
ConcurrentWorkers int `gorm:"not null"`
ThumbnailMethod int `gorm:"not null"`
}
func (SiteInfo) TableName() string {
@@ -26,6 +27,7 @@ func DefaultSiteInfo(db *gorm.DB) SiteInfo {
InitialSetup: true,
PeriodicScanInterval: 0,
ConcurrentWorkers: defaultConcurrentWorkers,
ThumbnailMethod: 0,
}
}

View File

@@ -0,0 +1,30 @@
package resolvers
import (
"context"
"github.com/photoview/photoview/api/graphql/models"
"github.com/pkg/errors"
"gorm.io/gorm"
)
func (r *mutationResolver) SetThumbnailDownsampleMethod(ctx context.Context, method int) (int, error) {
db := r.DB(ctx)
if method > 5 {
return 0, errors.New("The requested filter is unsupported, defaulting to nearest neighbor")
}
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Model(&models.SiteInfo{}).Update("thumbnail_method", method).Error; err != nil {
return 0, err
}
var siteInfo models.SiteInfo
if err := db.First(&siteInfo).Error; err != nil {
return 0, err
}
// scanner_queue.ChangeScannerConcurrentWorkers(siteInfo.ConcurrentWorkers)
return siteInfo.ThumbnailMethod, nil
}

View File

@@ -163,6 +163,9 @@ type Mutation {
"Set max number of concurrent scanner jobs running at once"
setScannerConcurrentWorkers(workers: Int!): Int! @isAdmin
"Set the filter to be used when generating thumbnails"
setThumbnailDownsampleMethod(method: Int!): Int! @isAdmin
"Change user preferences for the logged in user"
changeUserPreferences(language: String): UserPreferences! @isAuthorized
@@ -257,6 +260,8 @@ type SiteInfo {
periodicScanInterval: Int! @isAdmin
"How many max concurrent scanner jobs that should run at once"
concurrentWorkers: Int! @isAdmin
"The filter to use when generating thumbnails"
thumbnailMethod: Int! @isAdmin
}
type User {