diff --git a/gqlgen.yml b/gqlgen.yml index 3693475e5..f24c1fca8 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -14,6 +14,7 @@ resolver: struct_tag: gqlgen autobind: + - github.com/stashapp/stash/internal/api - github.com/stashapp/stash/pkg/models - github.com/stashapp/stash/pkg/plugin - github.com/stashapp/stash/pkg/scraper @@ -41,30 +42,13 @@ models: fields: title: resolver: true - # override models, from internal/api/models.go - BaseFile: - model: github.com/stashapp/stash/internal/api.BaseFile - GalleryFile: - model: github.com/stashapp/stash/internal/api.GalleryFile - fields: - # override fingerprint field - fingerprints: - fieldName: FingerprintSlice VideoFile: fields: - # override fingerprint field - fingerprints: - fieldName: FingerprintSlice # override float fields - #1572 duration: fieldName: DurationFinite frame_rate: fieldName: FrameRateFinite - ImageFile: - fields: - # override fingerprint field - fingerprints: - fieldName: FingerprintSlice # autobind on config causes generation issues BlobsStorageType: model: github.com/stashapp/stash/internal/manager/config.BlobsStorageType diff --git a/graphql/schema/types/file.graphql b/graphql/schema/types/file.graphql index b0388571e..b5a878b42 100644 --- a/graphql/schema/types/file.graphql +++ b/graphql/schema/types/file.graphql @@ -27,6 +27,7 @@ interface BaseFile { mod_time: Time! size: Int64! + fingerprint(type: String!): String fingerprints: [Fingerprint!]! created_at: Time! @@ -44,6 +45,7 @@ type VideoFile implements BaseFile { mod_time: Time! size: Int64! + fingerprint(type: String!): String fingerprints: [Fingerprint!]! format: String! @@ -70,6 +72,7 @@ type ImageFile implements BaseFile { mod_time: Time! size: Int64! + fingerprint(type: String!): String fingerprints: [Fingerprint!]! width: Int! @@ -92,6 +95,7 @@ type GalleryFile implements BaseFile { mod_time: Time! size: Int64! + fingerprint(type: String!): String fingerprints: [Fingerprint!]! created_at: Time! diff --git a/internal/api/models.go b/internal/api/models.go index 40d93cc2e..d8f4dc63c 100644 --- a/internal/api/models.go +++ b/internal/api/models.go @@ -1,11 +1,64 @@ package api import ( + "fmt" + "github.com/stashapp/stash/pkg/models" ) -type BaseFile interface{} +type BaseFile interface { + IsBaseFile() +} + +type VisualFile interface { + IsVisualFile() +} + +func convertVisualFile(f models.File) (VisualFile, error) { + switch f := f.(type) { + case VisualFile: + return f, nil + case *models.VideoFile: + return &VideoFile{VideoFile: f}, nil + case *models.ImageFile: + return &ImageFile{ImageFile: f}, nil + default: + return nil, fmt.Errorf("file %s is not a visual file", f.Base().Path) + } +} type GalleryFile struct { *models.BaseFile } + +func (GalleryFile) IsBaseFile() {} + +func (GalleryFile) IsVisualFile() {} + +func (f *GalleryFile) Fingerprints() []models.Fingerprint { + return f.BaseFile.Fingerprints +} + +type VideoFile struct { + *models.VideoFile +} + +func (VideoFile) IsBaseFile() {} + +func (VideoFile) IsVisualFile() {} + +func (f *VideoFile) Fingerprints() []models.Fingerprint { + return f.VideoFile.Fingerprints +} + +type ImageFile struct { + *models.ImageFile +} + +func (ImageFile) IsBaseFile() {} + +func (ImageFile) IsVisualFile() {} + +func (f *ImageFile) Fingerprints() []models.Fingerprint { + return f.ImageFile.Fingerprints +} diff --git a/internal/api/resolver.go b/internal/api/resolver.go index 4698add70..a5ed859a3 100644 --- a/internal/api/resolver.go +++ b/internal/api/resolver.go @@ -81,6 +81,15 @@ func (r *Resolver) Subscription() SubscriptionResolver { func (r *Resolver) Tag() TagResolver { return &tagResolver{r} } +func (r *Resolver) GalleryFile() GalleryFileResolver { + return &galleryFileResolver{r} +} +func (r *Resolver) VideoFile() VideoFileResolver { + return &videoFileResolver{r} +} +func (r *Resolver) ImageFile() ImageFileResolver { + return &imageFileResolver{r} +} func (r *Resolver) SavedFilter() SavedFilterResolver { return &savedFilterResolver{r} } @@ -104,6 +113,9 @@ type imageResolver struct{ *Resolver } type studioResolver struct{ *Resolver } type movieResolver struct{ *Resolver } type tagResolver struct{ *Resolver } +type galleryFileResolver struct{ *Resolver } +type videoFileResolver struct{ *Resolver } +type imageFileResolver struct{ *Resolver } type savedFilterResolver struct{ *Resolver } type pluginResolver struct{ *Resolver } type configResultResolver struct{ *Resolver } diff --git a/internal/api/resolver_model_file.go b/internal/api/resolver_model_file.go new file mode 100644 index 000000000..35013cfbd --- /dev/null +++ b/internal/api/resolver_model_file.go @@ -0,0 +1,30 @@ +package api + +import "context" + +func (r *galleryFileResolver) Fingerprint(ctx context.Context, obj *GalleryFile, type_ string) (*string, error) { + fp := obj.BaseFile.Fingerprints.For(type_) + if fp != nil { + v := fp.Value() + return &v, nil + } + return nil, nil +} + +func (r *imageFileResolver) Fingerprint(ctx context.Context, obj *ImageFile, type_ string) (*string, error) { + fp := obj.ImageFile.Fingerprints.For(type_) + if fp != nil { + v := fp.Value() + return &v, nil + } + return nil, nil +} + +func (r *videoFileResolver) Fingerprint(ctx context.Context, obj *VideoFile, type_ string) (*string, error) { + fp := obj.VideoFile.Fingerprints.For(type_) + if fp != nil { + v := fp.Value() + return &v, nil + } + return nil, nil +} diff --git a/internal/api/resolver_model_image.go b/internal/api/resolver_model_image.go index bc9d991a7..49f94b8b7 100644 --- a/internal/api/resolver_model_image.go +++ b/internal/api/resolver_model_image.go @@ -2,21 +2,12 @@ package api import ( "context" - "fmt" "github.com/stashapp/stash/internal/api/loaders" "github.com/stashapp/stash/internal/api/urlbuilders" "github.com/stashapp/stash/pkg/models" ) -func convertVisualFile(f models.File) (models.VisualFile, error) { - vf, ok := f.(models.VisualFile) - if !ok { - return nil, fmt.Errorf("file %s is not a visual file", f.Base().Path) - } - return vf, nil -} - func (r *imageResolver) getFiles(ctx context.Context, obj *models.Image) ([]models.File, error) { fileIDs, err := loaders.From(ctx).ImageFiles.Load(obj.ID) if err != nil { @@ -32,13 +23,13 @@ func (r *imageResolver) Title(ctx context.Context, obj *models.Image) (*string, return &ret, nil } -func (r *imageResolver) VisualFiles(ctx context.Context, obj *models.Image) ([]models.VisualFile, error) { +func (r *imageResolver) VisualFiles(ctx context.Context, obj *models.Image) ([]VisualFile, error) { files, err := r.getFiles(ctx, obj) if err != nil { return nil, err } - ret := make([]models.VisualFile, len(files)) + ret := make([]VisualFile, len(files)) for i, f := range files { ret[i], err = convertVisualFile(f) if err != nil { @@ -57,13 +48,13 @@ func (r *imageResolver) Date(ctx context.Context, obj *models.Image) (*string, e return nil, nil } -func (r *imageResolver) Files(ctx context.Context, obj *models.Image) ([]*models.ImageFile, error) { +func (r *imageResolver) Files(ctx context.Context, obj *models.Image) ([]*ImageFile, error) { files, err := r.getFiles(ctx, obj) if err != nil { return nil, err } - var ret []*models.ImageFile + var ret []*ImageFile for _, f := range files { // filter out non-image files @@ -72,7 +63,9 @@ func (r *imageResolver) Files(ctx context.Context, obj *models.Image) ([]*models continue } - ret = append(ret, imageFile) + ret = append(ret, &ImageFile{ + ImageFile: imageFile, + }) } return ret, nil diff --git a/internal/api/resolver_model_scene.go b/internal/api/resolver_model_scene.go index bfc5194c0..e820099c5 100644 --- a/internal/api/resolver_model_scene.go +++ b/internal/api/resolver_model_scene.go @@ -73,13 +73,21 @@ func (r *sceneResolver) Date(ctx context.Context, obj *models.Scene) (*string, e return nil, nil } -func (r *sceneResolver) Files(ctx context.Context, obj *models.Scene) ([]*models.VideoFile, error) { +func (r *sceneResolver) Files(ctx context.Context, obj *models.Scene) ([]*VideoFile, error) { files, err := r.getFiles(ctx, obj) if err != nil { return nil, err } - return files, nil + ret := make([]*VideoFile, len(files)) + + for i, f := range files { + ret[i] = &VideoFile{ + VideoFile: f, + } + } + + return ret, nil } func (r *sceneResolver) Rating(ctx context.Context, obj *models.Scene) (*int, error) { diff --git a/pkg/models/model_file.go b/pkg/models/model_file.go index b4ca2c3c1..0ff90d1af 100644 --- a/pkg/models/model_file.go +++ b/pkg/models/model_file.go @@ -133,10 +133,6 @@ type BaseFile struct { UpdatedAt time.Time `json:"updated_at"` } -func (f *BaseFile) FingerprintSlice() []Fingerprint { - return f.Fingerprints -} - // SetFingerprints sets the fingerprints of the file. // If a fingerprint of the same type already exists, it is overwritten. func (f *BaseFile) SetFingerprints(fp Fingerprints) {