Add findFolder and findFolders queries to graphql schema (#5965)

* Add findFolder and findFolders queries to graphql schema
* Add zip file criterion to file and folder queries
This commit is contained in:
WithoutPants
2025-06-26 15:48:29 +10:00
committed by GitHub
parent 661d2f64bb
commit 7eff7f02d0
16 changed files with 800 additions and 12 deletions

View File

@@ -24,6 +24,7 @@ type FileFilterType struct {
Basename *StringCriterionInput `json:"basename"`
Dir *StringCriterionInput `json:"dir"`
ParentFolder *HierarchicalMultiCriterionInput `json:"parent_folder"`
ZipFile *MultiCriterionInput `json:"zip_file"`
ModTime *TimestampCriterionInput `json:"mod_time"`
Duplicated *PHashDuplicationCriterionInput `json:"duplicated"`
Hashes []*FingerprintFilterInput `json:"hashes"`

92
pkg/models/folder.go Normal file
View File

@@ -0,0 +1,92 @@
package models
import (
"context"
"path/filepath"
"strings"
)
type FolderQueryOptions struct {
QueryOptions
FolderFilter *FolderFilterType
TotalDuration bool
Megapixels bool
TotalSize bool
}
type FolderFilterType struct {
OperatorFilter[FolderFilterType]
Path *StringCriterionInput `json:"path,omitempty"`
Basename *StringCriterionInput `json:"basename,omitempty"`
// Filter by parent directory path
Dir *StringCriterionInput `json:"dir,omitempty"`
ParentFolder *HierarchicalMultiCriterionInput `json:"parent_folder,omitempty"`
ZipFile *MultiCriterionInput `json:"zip_file,omitempty"`
// Filter by modification time
ModTime *TimestampCriterionInput `json:"mod_time,omitempty"`
GalleryCount *IntCriterionInput `json:"gallery_count,omitempty"`
// Filter by files that meet this criteria
FilesFilter *FileFilterType `json:"files_filter,omitempty"`
// Filter by related galleries that meet this criteria
GalleriesFilter *GalleryFilterType `json:"galleries_filter,omitempty"`
// Filter by creation time
CreatedAt *TimestampCriterionInput `json:"created_at,omitempty"`
// Filter by last update time
UpdatedAt *TimestampCriterionInput `json:"updated_at,omitempty"`
}
func PathsFolderFilter(paths []string) *FileFilterType {
if paths == nil {
return nil
}
sep := string(filepath.Separator)
var ret *FileFilterType
var or *FileFilterType
for _, p := range paths {
newOr := &FileFilterType{}
if or != nil {
or.Or = newOr
} else {
ret = newOr
}
or = newOr
if !strings.HasSuffix(p, sep) {
p += sep
}
or.Path = &StringCriterionInput{
Modifier: CriterionModifierEquals,
Value: p + "%",
}
}
return ret
}
type FolderQueryResult struct {
QueryResult[FolderID]
getter FolderGetter
folders []*Folder
resolveErr error
}
func NewFolderQueryResult(folderGetter FolderGetter) *FolderQueryResult {
return &FolderQueryResult{
getter: folderGetter,
}
}
func (r *FolderQueryResult) Resolve(ctx context.Context) ([]*Folder, error) {
// cache results
if r.folders == nil && r.resolveErr == nil {
r.folders, r.resolveErr = r.getter.FindMany(ctx, r.IDs)
}
return r.folders, r.resolveErr
}

View File

@@ -201,6 +201,29 @@ func (_m *FolderReaderWriter) FindMany(ctx context.Context, id []models.FolderID
return r0, r1
}
// Query provides a mock function with given fields: ctx, options
func (_m *FolderReaderWriter) Query(ctx context.Context, options models.FolderQueryOptions) (*models.FolderQueryResult, error) {
ret := _m.Called(ctx, options)
var r0 *models.FolderQueryResult
if rf, ok := ret.Get(0).(func(context.Context, models.FolderQueryOptions) *models.FolderQueryResult); ok {
r0 = rf(ctx, options)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.FolderQueryResult)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, models.FolderQueryOptions) error); ok {
r1 = rf(ctx, options)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Update provides a mock function with given fields: ctx, f
func (_m *FolderReaderWriter) Update(ctx context.Context, f *models.Folder) error {
ret := _m.Called(ctx, f)

View File

@@ -35,6 +35,14 @@ func (i FolderID) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(i.String()))
}
func FolderIDsFromInts(ids []int) []FolderID {
ret := make([]FolderID, len(ids))
for i, id := range ids {
ret[i] = FolderID(id)
}
return ret
}
// Folder represents a folder in the file system.
type Folder struct {
ID FolderID `json:"id"`

View File

@@ -17,6 +17,10 @@ type FolderFinder interface {
FindByParentFolderID(ctx context.Context, parentFolderID FolderID) ([]*Folder, error)
}
type FolderQueryer interface {
Query(ctx context.Context, options FolderQueryOptions) (*FolderQueryResult, error)
}
type FolderCounter interface {
CountAllInPaths(ctx context.Context, p []string) (int, error)
}
@@ -48,6 +52,7 @@ type FolderFinderDestroyer interface {
// FolderReader provides all methods to read folders.
type FolderReader interface {
FolderFinder
FolderQueryer
FolderCounter
}