mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Add various filter criteria (#1505)
* Add various filter criteria * Add tag name criterion
This commit is contained in:
@@ -33,6 +33,9 @@ input PerformerFilterType {
|
|||||||
OR: PerformerFilterType
|
OR: PerformerFilterType
|
||||||
NOT: PerformerFilterType
|
NOT: PerformerFilterType
|
||||||
|
|
||||||
|
name: StringCriterionInput
|
||||||
|
details: StringCriterionInput
|
||||||
|
|
||||||
"""Filter by favorite"""
|
"""Filter by favorite"""
|
||||||
filter_favorites: Boolean
|
filter_favorites: Boolean
|
||||||
"""Filter by birth year"""
|
"""Filter by birth year"""
|
||||||
@@ -105,6 +108,15 @@ input SceneFilterType {
|
|||||||
OR: SceneFilterType
|
OR: SceneFilterType
|
||||||
NOT: SceneFilterType
|
NOT: SceneFilterType
|
||||||
|
|
||||||
|
title: StringCriterionInput
|
||||||
|
details: StringCriterionInput
|
||||||
|
|
||||||
|
"""Filter by file oshash"""
|
||||||
|
oshash: StringCriterionInput
|
||||||
|
"""Filter by file checksum"""
|
||||||
|
checksum: StringCriterionInput
|
||||||
|
"""Filter by file phash"""
|
||||||
|
phash: StringCriterionInput
|
||||||
"""Filter by path"""
|
"""Filter by path"""
|
||||||
path: StringCriterionInput
|
path: StringCriterionInput
|
||||||
"""Filter by rating"""
|
"""Filter by rating"""
|
||||||
@@ -144,6 +156,15 @@ input SceneFilterType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input MovieFilterType {
|
input MovieFilterType {
|
||||||
|
|
||||||
|
name: StringCriterionInput
|
||||||
|
director: StringCriterionInput
|
||||||
|
synopsis: StringCriterionInput
|
||||||
|
|
||||||
|
"""Filter by duration (in seconds)"""
|
||||||
|
duration: IntCriterionInput
|
||||||
|
"""Filter by rating"""
|
||||||
|
rating: IntCriterionInput
|
||||||
"""Filter to only include movies with this studio"""
|
"""Filter to only include movies with this studio"""
|
||||||
studios: HierarchicalMultiCriterionInput
|
studios: HierarchicalMultiCriterionInput
|
||||||
"""Filter to only include movies missing this property"""
|
"""Filter to only include movies missing this property"""
|
||||||
@@ -153,6 +174,8 @@ input MovieFilterType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input StudioFilterType {
|
input StudioFilterType {
|
||||||
|
name: StringCriterionInput
|
||||||
|
details: StringCriterionInput
|
||||||
"""Filter to only include studios with this parent studio"""
|
"""Filter to only include studios with this parent studio"""
|
||||||
parents: MultiCriterionInput
|
parents: MultiCriterionInput
|
||||||
"""Filter by StashID"""
|
"""Filter by StashID"""
|
||||||
@@ -176,6 +199,11 @@ input GalleryFilterType {
|
|||||||
OR: GalleryFilterType
|
OR: GalleryFilterType
|
||||||
NOT: GalleryFilterType
|
NOT: GalleryFilterType
|
||||||
|
|
||||||
|
title: StringCriterionInput
|
||||||
|
details: StringCriterionInput
|
||||||
|
|
||||||
|
"""Filter by file checksum"""
|
||||||
|
checksum: StringCriterionInput
|
||||||
"""Filter by path"""
|
"""Filter by path"""
|
||||||
path: StringCriterionInput
|
path: StringCriterionInput
|
||||||
"""Filter to only include galleries missing this property"""
|
"""Filter to only include galleries missing this property"""
|
||||||
@@ -241,6 +269,10 @@ input ImageFilterType {
|
|||||||
OR: ImageFilterType
|
OR: ImageFilterType
|
||||||
NOT: ImageFilterType
|
NOT: ImageFilterType
|
||||||
|
|
||||||
|
title: StringCriterionInput
|
||||||
|
|
||||||
|
"""Filter by file checksum"""
|
||||||
|
checksum: StringCriterionInput
|
||||||
"""Filter by path"""
|
"""Filter by path"""
|
||||||
path: StringCriterionInput
|
path: StringCriterionInput
|
||||||
"""Filter by rating"""
|
"""Filter by rating"""
|
||||||
|
|||||||
@@ -203,6 +203,9 @@ func (qb *galleryQueryBuilder) makeFilter(galleryFilter *models.GalleryFilterTyp
|
|||||||
query.not(qb.makeFilter(galleryFilter.Not))
|
query.not(qb.makeFilter(galleryFilter.Not))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Title, "galleries.title"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Details, "galleries.details"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Checksum, "galleries.checksum"))
|
||||||
query.handleCriterion(boolCriterionHandler(galleryFilter.IsZip, "galleries.zip"))
|
query.handleCriterion(boolCriterionHandler(galleryFilter.IsZip, "galleries.zip"))
|
||||||
query.handleCriterion(stringCriterionHandler(galleryFilter.Path, "galleries.path"))
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Path, "galleries.path"))
|
||||||
query.handleCriterion(intCriterionHandler(galleryFilter.Rating, "galleries.rating"))
|
query.handleCriterion(intCriterionHandler(galleryFilter.Rating, "galleries.rating"))
|
||||||
|
|||||||
@@ -231,6 +231,8 @@ func (qb *imageQueryBuilder) makeFilter(imageFilter *models.ImageFilterType) *fi
|
|||||||
query.not(qb.makeFilter(imageFilter.Not))
|
query.not(qb.makeFilter(imageFilter.Not))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query.handleCriterion(stringCriterionHandler(imageFilter.Checksum, "images.checksum"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(imageFilter.Title, "images.title"))
|
||||||
query.handleCriterion(stringCriterionHandler(imageFilter.Path, "images.path"))
|
query.handleCriterion(stringCriterionHandler(imageFilter.Path, "images.path"))
|
||||||
query.handleCriterion(intCriterionHandler(imageFilter.Rating, "images.rating"))
|
query.handleCriterion(intCriterionHandler(imageFilter.Rating, "images.rating"))
|
||||||
query.handleCriterion(intCriterionHandler(imageFilter.OCounter, "images.o_counter"))
|
query.handleCriterion(intCriterionHandler(imageFilter.OCounter, "images.o_counter"))
|
||||||
|
|||||||
@@ -118,6 +118,11 @@ func (qb *movieQueryBuilder) All() ([]*models.Movie, error) {
|
|||||||
func (qb *movieQueryBuilder) makeFilter(movieFilter *models.MovieFilterType) *filterBuilder {
|
func (qb *movieQueryBuilder) makeFilter(movieFilter *models.MovieFilterType) *filterBuilder {
|
||||||
query := &filterBuilder{}
|
query := &filterBuilder{}
|
||||||
|
|
||||||
|
query.handleCriterion(stringCriterionHandler(movieFilter.Name, "movies.name"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(movieFilter.Director, "movies.director"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(movieFilter.Synopsis, "movies.synopsis"))
|
||||||
|
query.handleCriterion(intCriterionHandler(movieFilter.Rating, "movies.rating"))
|
||||||
|
query.handleCriterion(durationCriterionHandler(movieFilter.Duration, "movies.duration"))
|
||||||
query.handleCriterion(movieIsMissingCriterionHandler(qb, movieFilter.IsMissing))
|
query.handleCriterion(movieIsMissingCriterionHandler(qb, movieFilter.IsMissing))
|
||||||
query.handleCriterion(stringCriterionHandler(movieFilter.URL, "movies.url"))
|
query.handleCriterion(stringCriterionHandler(movieFilter.URL, "movies.url"))
|
||||||
query.handleCriterion(movieStudioCriterionHandler(qb, movieFilter.Studios))
|
query.handleCriterion(movieStudioCriterionHandler(qb, movieFilter.Studios))
|
||||||
|
|||||||
@@ -239,6 +239,9 @@ func (qb *performerQueryBuilder) makeFilter(filter *models.PerformerFilterType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tableName = performerTable
|
const tableName = performerTable
|
||||||
|
query.handleCriterion(stringCriterionHandler(filter.Name, tableName+".name"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(filter.Details, tableName+".details"))
|
||||||
|
|
||||||
query.handleCriterion(boolCriterionHandler(filter.FilterFavorites, tableName+".favorite"))
|
query.handleCriterion(boolCriterionHandler(filter.FilterFavorites, tableName+".favorite"))
|
||||||
|
|
||||||
query.handleCriterion(yearFilterCriterionHandler(filter.BirthYear, tableName+".birthdate"))
|
query.handleCriterion(yearFilterCriterionHandler(filter.BirthYear, tableName+".birthdate"))
|
||||||
|
|||||||
@@ -354,6 +354,11 @@ func (qb *sceneQueryBuilder) makeFilter(sceneFilter *models.SceneFilterType) *fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
query.handleCriterion(stringCriterionHandler(sceneFilter.Path, "scenes.path"))
|
query.handleCriterion(stringCriterionHandler(sceneFilter.Path, "scenes.path"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(sceneFilter.Title, "scenes.title"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(sceneFilter.Details, "scenes.details"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(sceneFilter.Oshash, "scenes.oshash"))
|
||||||
|
query.handleCriterion(stringCriterionHandler(sceneFilter.Checksum, "scenes.checksum"))
|
||||||
|
query.handleCriterion(phashCriterionHandler(sceneFilter.Phash))
|
||||||
query.handleCriterion(intCriterionHandler(sceneFilter.Rating, "scenes.rating"))
|
query.handleCriterion(intCriterionHandler(sceneFilter.Rating, "scenes.rating"))
|
||||||
query.handleCriterion(intCriterionHandler(sceneFilter.OCounter, "scenes.o_counter"))
|
query.handleCriterion(intCriterionHandler(sceneFilter.OCounter, "scenes.o_counter"))
|
||||||
query.handleCriterion(boolCriterionHandler(sceneFilter.Organized, "scenes.organized"))
|
query.handleCriterion(boolCriterionHandler(sceneFilter.Organized, "scenes.organized"))
|
||||||
@@ -430,6 +435,29 @@ func (qb *sceneQueryBuilder) Query(sceneFilter *models.SceneFilterType, findFilt
|
|||||||
return scenes, countResult, nil
|
return scenes, countResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func phashCriterionHandler(phashFilter *models.StringCriterionInput) criterionHandlerFunc {
|
||||||
|
return func(f *filterBuilder) {
|
||||||
|
if phashFilter != nil {
|
||||||
|
// convert value to int from hex
|
||||||
|
// ignore errors
|
||||||
|
value, _ := utils.StringToPhash(phashFilter.Value)
|
||||||
|
|
||||||
|
if modifier := phashFilter.Modifier; phashFilter.Modifier.IsValid() {
|
||||||
|
switch modifier {
|
||||||
|
case models.CriterionModifierEquals:
|
||||||
|
f.addWhere("scenes.phash = ?", value)
|
||||||
|
case models.CriterionModifierNotEquals:
|
||||||
|
f.addWhere("scenes.phash != ?", value)
|
||||||
|
case models.CriterionModifierIsNull:
|
||||||
|
f.addWhere("scenes.phash IS NULL")
|
||||||
|
case models.CriterionModifierNotNull:
|
||||||
|
f.addWhere("scenes.phash IS NOT NULL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func durationCriterionHandler(durationFilter *models.IntCriterionInput, column string) criterionHandlerFunc {
|
func durationCriterionHandler(durationFilter *models.IntCriterionInput, column string) criterionHandlerFunc {
|
||||||
return func(f *filterBuilder) {
|
return func(f *filterBuilder) {
|
||||||
if durationFilter != nil {
|
if durationFilter != nil {
|
||||||
|
|||||||
@@ -184,6 +184,8 @@ func (qb *studioQueryBuilder) Query(studioFilter *models.StudioFilterType, findF
|
|||||||
query.handleCountCriterion(studioFilter.SceneCount, studioTable, sceneTable, studioIDColumn)
|
query.handleCountCriterion(studioFilter.SceneCount, studioTable, sceneTable, studioIDColumn)
|
||||||
query.handleCountCriterion(studioFilter.ImageCount, studioTable, imageTable, studioIDColumn)
|
query.handleCountCriterion(studioFilter.ImageCount, studioTable, imageTable, studioIDColumn)
|
||||||
query.handleCountCriterion(studioFilter.GalleryCount, studioTable, galleryTable, studioIDColumn)
|
query.handleCountCriterion(studioFilter.GalleryCount, studioTable, galleryTable, studioIDColumn)
|
||||||
|
query.handleStringCriterionInput(studioFilter.Name, "studios.name")
|
||||||
|
query.handleStringCriterionInput(studioFilter.Details, "studios.details")
|
||||||
query.handleStringCriterionInput(studioFilter.URL, "studios.url")
|
query.handleStringCriterionInput(studioFilter.URL, "studios.url")
|
||||||
query.handleStringCriterionInput(studioFilter.StashID, "studio_stash_ids.stash_id")
|
query.handleStringCriterionInput(studioFilter.StashID, "studio_stash_ids.stash_id")
|
||||||
|
|
||||||
|
|||||||
@@ -55,3 +55,12 @@ func findNeighbors(bucket int, neighbors []int, hashes []*Phash, scenes *[]int)
|
|||||||
func PhashToString(phash int64) string {
|
func PhashToString(phash int64) string {
|
||||||
return strconv.FormatUint(uint64(phash), 16)
|
return strconv.FormatUint(uint64(phash), 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StringToPhash(s string) (int64, error) {
|
||||||
|
ret, err := strconv.ParseUint(s, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return int64(ret), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
### ✨ New Features
|
### ✨ New Features
|
||||||
* Add button to open scene in external player on handheld devices. ([#679](https://github.com/stashapp/stash/pull/679))
|
* Added filter criteria for name, details and hash related fields. ([#1505](https://github.com/stashapp/stash/pull/1505))
|
||||||
|
* Added button to open scene in external player on handheld devices. ([#679](https://github.com/stashapp/stash/pull/679))
|
||||||
* Added support for saved and default filters. ([#1474](https://github.com/stashapp/stash/pull/1474))
|
* Added support for saved and default filters. ([#1474](https://github.com/stashapp/stash/pull/1474))
|
||||||
* Added merge tags functionality. ([#1481](https://github.com/stashapp/stash/pull/1481))
|
* Added merge tags functionality. ([#1481](https://github.com/stashapp/stash/pull/1481))
|
||||||
* Added support for triggering plugin tasks during operations. ([#1452](https://github.com/stashapp/stash/pull/1452))
|
* Added support for triggering plugin tasks during operations. ([#1452](https://github.com/stashapp/stash/pull/1452))
|
||||||
|
|||||||
@@ -184,8 +184,16 @@ export class StringCriterionOption extends CriterionOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createStringCriterionOption(value: CriterionType) {
|
export function createStringCriterionOption(
|
||||||
return new StringCriterionOption(value, value, value);
|
value: CriterionType,
|
||||||
|
messageID?: string,
|
||||||
|
parameterName?: string
|
||||||
|
) {
|
||||||
|
return new StringCriterionOption(
|
||||||
|
messageID ?? value,
|
||||||
|
value,
|
||||||
|
parameterName ?? messageID ?? value
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StringCriterion extends Criterion<string> {
|
export class StringCriterion extends Criterion<string> {
|
||||||
@@ -236,6 +244,18 @@ export class MandatoryStringCriterionOption extends CriterionOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createMandatoryStringCriterionOption(
|
||||||
|
value: CriterionType,
|
||||||
|
messageID?: string,
|
||||||
|
parameterName?: string
|
||||||
|
) {
|
||||||
|
return new MandatoryStringCriterionOption(
|
||||||
|
messageID ?? value,
|
||||||
|
value,
|
||||||
|
parameterName ?? messageID ?? value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export class BooleanCriterionOption extends CriterionOption {
|
export class BooleanCriterionOption extends CriterionOption {
|
||||||
constructor(messageID: string, value: CriterionType, parameterName?: string) {
|
constructor(messageID: string, value: CriterionType, parameterName?: string) {
|
||||||
super({
|
super({
|
||||||
|
|||||||
@@ -38,12 +38,16 @@ import { GalleriesCriterion } from "./galleries";
|
|||||||
import { CriterionType } from "../types";
|
import { CriterionType } from "../types";
|
||||||
import { InteractiveCriterion } from "./interactive";
|
import { InteractiveCriterion } from "./interactive";
|
||||||
import { RatingCriterionOption } from "./rating";
|
import { RatingCriterionOption } from "./rating";
|
||||||
|
import { PhashCriterionOption } from "./phash";
|
||||||
|
|
||||||
export function makeCriteria(type: CriterionType = "none") {
|
export function makeCriteria(type: CriterionType = "none") {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "none":
|
case "none":
|
||||||
return new NoneCriterion();
|
return new NoneCriterion();
|
||||||
|
case "name":
|
||||||
case "path":
|
case "path":
|
||||||
|
case "checksum":
|
||||||
|
case "oshash":
|
||||||
return new StringCriterion(
|
return new StringCriterion(
|
||||||
new MandatoryStringCriterionOption(type, type)
|
new MandatoryStringCriterionOption(type, type)
|
||||||
);
|
);
|
||||||
@@ -111,6 +115,13 @@ export function makeCriteria(type: CriterionType = "none") {
|
|||||||
);
|
);
|
||||||
case "gender":
|
case "gender":
|
||||||
return new GenderCriterion();
|
return new GenderCriterion();
|
||||||
|
case "sceneChecksum":
|
||||||
|
case "galleryChecksum":
|
||||||
|
return new StringCriterion(
|
||||||
|
new StringCriterionOption("checksum", type, "checksum")
|
||||||
|
);
|
||||||
|
case "phash":
|
||||||
|
return new StringCriterion(PhashCriterionOption);
|
||||||
case "ethnicity":
|
case "ethnicity":
|
||||||
case "country":
|
case "country":
|
||||||
case "hair_color":
|
case "hair_color":
|
||||||
@@ -124,6 +135,10 @@ export function makeCriteria(type: CriterionType = "none") {
|
|||||||
case "aliases":
|
case "aliases":
|
||||||
case "url":
|
case "url":
|
||||||
case "stash_id":
|
case "stash_id":
|
||||||
|
case "details":
|
||||||
|
case "title":
|
||||||
|
case "director":
|
||||||
|
case "synopsis":
|
||||||
return new StringCriterion(new StringCriterionOption(type, type));
|
return new StringCriterion(new StringCriterionOption(type, type));
|
||||||
case "interactive":
|
case "interactive":
|
||||||
return new InteractiveCriterion();
|
return new InteractiveCriterion();
|
||||||
|
|||||||
15
ui/v2.5/src/models/list-filter/criteria/phash.ts
Normal file
15
ui/v2.5/src/models/list-filter/criteria/phash.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { CriterionModifier } from "src/core/generated-graphql";
|
||||||
|
import { CriterionOption } from "./criterion";
|
||||||
|
|
||||||
|
export const PhashCriterionOption = new CriterionOption({
|
||||||
|
messageID: "media_info.phash",
|
||||||
|
type: "phash",
|
||||||
|
parameterName: "phash",
|
||||||
|
inputType: "text",
|
||||||
|
modifierOptions: [
|
||||||
|
CriterionModifier.Equals,
|
||||||
|
CriterionModifier.NotEquals,
|
||||||
|
CriterionModifier.IsNull,
|
||||||
|
CriterionModifier.NotNull,
|
||||||
|
],
|
||||||
|
});
|
||||||
@@ -38,7 +38,14 @@ const displayModeOptions = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const criterionOptions = [
|
const criterionOptions = [
|
||||||
|
createStringCriterionOption("title"),
|
||||||
|
createStringCriterionOption("details"),
|
||||||
createStringCriterionOption("path"),
|
createStringCriterionOption("path"),
|
||||||
|
createStringCriterionOption(
|
||||||
|
"galleryChecksum",
|
||||||
|
"media_info.checksum",
|
||||||
|
"checksum"
|
||||||
|
),
|
||||||
RatingCriterionOption,
|
RatingCriterionOption,
|
||||||
OrganizedCriterionOption,
|
OrganizedCriterionOption,
|
||||||
AverageResolutionCriterionOption,
|
AverageResolutionCriterionOption,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
createMandatoryNumberCriterionOption,
|
createMandatoryNumberCriterionOption,
|
||||||
|
createMandatoryStringCriterionOption,
|
||||||
createStringCriterionOption,
|
createStringCriterionOption,
|
||||||
} from "./criteria/criterion";
|
} from "./criteria/criterion";
|
||||||
import { ImageIsMissingCriterionOption } from "./criteria/is-missing";
|
import { ImageIsMissingCriterionOption } from "./criteria/is-missing";
|
||||||
@@ -31,7 +32,9 @@ const sortByOptions = [
|
|||||||
|
|
||||||
const displayModeOptions = [DisplayMode.Grid, DisplayMode.Wall];
|
const displayModeOptions = [DisplayMode.Grid, DisplayMode.Wall];
|
||||||
const criterionOptions = [
|
const criterionOptions = [
|
||||||
createStringCriterionOption("path"),
|
createStringCriterionOption("title"),
|
||||||
|
createMandatoryStringCriterionOption("checksum", "media_info.checksum"),
|
||||||
|
createMandatoryStringCriterionOption("path"),
|
||||||
RatingCriterionOption,
|
RatingCriterionOption,
|
||||||
OrganizedCriterionOption,
|
OrganizedCriterionOption,
|
||||||
createMandatoryNumberCriterionOption("o_counter"),
|
createMandatoryNumberCriterionOption("o_counter"),
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { createStringCriterionOption } from "./criteria/criterion";
|
import {
|
||||||
|
createMandatoryNumberCriterionOption,
|
||||||
|
createStringCriterionOption,
|
||||||
|
} from "./criteria/criterion";
|
||||||
import { MovieIsMissingCriterionOption } from "./criteria/is-missing";
|
import { MovieIsMissingCriterionOption } from "./criteria/is-missing";
|
||||||
|
import { RatingCriterionOption } from "./criteria/rating";
|
||||||
import { StudiosCriterionOption } from "./criteria/studios";
|
import { StudiosCriterionOption } from "./criteria/studios";
|
||||||
import { ListFilterOptions } from "./filter-options";
|
import { ListFilterOptions } from "./filter-options";
|
||||||
import { DisplayMode } from "./types";
|
import { DisplayMode } from "./types";
|
||||||
@@ -19,6 +23,11 @@ const criterionOptions = [
|
|||||||
StudiosCriterionOption,
|
StudiosCriterionOption,
|
||||||
MovieIsMissingCriterionOption,
|
MovieIsMissingCriterionOption,
|
||||||
createStringCriterionOption("url"),
|
createStringCriterionOption("url"),
|
||||||
|
createStringCriterionOption("name"),
|
||||||
|
createStringCriterionOption("director"),
|
||||||
|
createStringCriterionOption("synopsis"),
|
||||||
|
createMandatoryNumberCriterionOption("duration"),
|
||||||
|
RatingCriterionOption,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const MovieListFilterOptions = new ListFilterOptions(
|
export const MovieListFilterOptions = new ListFilterOptions(
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ const numberCriteria: CriterionType[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const stringCriteria: CriterionType[] = [
|
const stringCriteria: CriterionType[] = [
|
||||||
|
"name",
|
||||||
|
"details",
|
||||||
"ethnicity",
|
"ethnicity",
|
||||||
"country",
|
"country",
|
||||||
"hair_color",
|
"hair_color",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
createMandatoryNumberCriterionOption,
|
createMandatoryNumberCriterionOption,
|
||||||
|
createMandatoryStringCriterionOption,
|
||||||
createStringCriterionOption,
|
createStringCriterionOption,
|
||||||
} from "./criteria/criterion";
|
} from "./criteria/criterion";
|
||||||
import { HasMarkersCriterionOption } from "./criteria/has-markers";
|
import { HasMarkersCriterionOption } from "./criteria/has-markers";
|
||||||
@@ -17,6 +18,7 @@ import {
|
|||||||
} from "./criteria/tags";
|
} from "./criteria/tags";
|
||||||
import { ListFilterOptions } from "./filter-options";
|
import { ListFilterOptions } from "./filter-options";
|
||||||
import { DisplayMode } from "./types";
|
import { DisplayMode } from "./types";
|
||||||
|
import { PhashCriterionOption } from "./criteria/phash";
|
||||||
|
|
||||||
const defaultSortBy = "date";
|
const defaultSortBy = "date";
|
||||||
const sortByOptions = [
|
const sortByOptions = [
|
||||||
@@ -46,7 +48,16 @@ const displayModeOptions = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const criterionOptions = [
|
const criterionOptions = [
|
||||||
createStringCriterionOption("path"),
|
createStringCriterionOption("title"),
|
||||||
|
createMandatoryStringCriterionOption("path"),
|
||||||
|
createStringCriterionOption("details"),
|
||||||
|
createMandatoryStringCriterionOption("oshash", "media_info.hash"),
|
||||||
|
createStringCriterionOption(
|
||||||
|
"sceneChecksum",
|
||||||
|
"media_info.checksum",
|
||||||
|
"checksum"
|
||||||
|
),
|
||||||
|
PhashCriterionOption,
|
||||||
RatingCriterionOption,
|
RatingCriterionOption,
|
||||||
OrganizedCriterionOption,
|
OrganizedCriterionOption,
|
||||||
createMandatoryNumberCriterionOption("o_counter"),
|
createMandatoryNumberCriterionOption("o_counter"),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
createMandatoryNumberCriterionOption,
|
createMandatoryNumberCriterionOption,
|
||||||
|
createMandatoryStringCriterionOption,
|
||||||
createStringCriterionOption,
|
createStringCriterionOption,
|
||||||
} from "./criteria/criterion";
|
} from "./criteria/criterion";
|
||||||
import { StudioIsMissingCriterionOption } from "./criteria/is-missing";
|
import { StudioIsMissingCriterionOption } from "./criteria/is-missing";
|
||||||
@@ -28,6 +29,8 @@ const sortByOptions = ["name", "random", "rating"]
|
|||||||
|
|
||||||
const displayModeOptions = [DisplayMode.Grid];
|
const displayModeOptions = [DisplayMode.Grid];
|
||||||
const criterionOptions = [
|
const criterionOptions = [
|
||||||
|
createMandatoryStringCriterionOption("name"),
|
||||||
|
createStringCriterionOption("details"),
|
||||||
ParentStudiosCriterionOption,
|
ParentStudiosCriterionOption,
|
||||||
StudioIsMissingCriterionOption,
|
StudioIsMissingCriterionOption,
|
||||||
RatingCriterionOption,
|
RatingCriterionOption,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
createMandatoryNumberCriterionOption,
|
createMandatoryNumberCriterionOption,
|
||||||
|
createMandatoryStringCriterionOption,
|
||||||
createStringCriterionOption,
|
createStringCriterionOption,
|
||||||
} from "./criteria/criterion";
|
} from "./criteria/criterion";
|
||||||
import { TagIsMissingCriterionOption } from "./criteria/is-missing";
|
import { TagIsMissingCriterionOption } from "./criteria/is-missing";
|
||||||
@@ -36,6 +37,7 @@ const sortByOptions = [
|
|||||||
|
|
||||||
const displayModeOptions = [DisplayMode.Grid, DisplayMode.List];
|
const displayModeOptions = [DisplayMode.Grid, DisplayMode.List];
|
||||||
const criterionOptions = [
|
const criterionOptions = [
|
||||||
|
createMandatoryStringCriterionOption("name"),
|
||||||
TagIsMissingCriterionOption,
|
TagIsMissingCriterionOption,
|
||||||
createStringCriterionOption("aliases"),
|
createStringCriterionOption("aliases"),
|
||||||
createMandatoryNumberCriterionOption("scene_count"),
|
createMandatoryNumberCriterionOption("scene_count"),
|
||||||
|
|||||||
@@ -92,4 +92,14 @@ export type CriterionType =
|
|||||||
| "death_year"
|
| "death_year"
|
||||||
| "url"
|
| "url"
|
||||||
| "stash_id"
|
| "stash_id"
|
||||||
| "interactive";
|
| "interactive"
|
||||||
|
| "name"
|
||||||
|
| "details"
|
||||||
|
| "title"
|
||||||
|
| "oshash"
|
||||||
|
| "checksum"
|
||||||
|
| "sceneChecksum"
|
||||||
|
| "galleryChecksum"
|
||||||
|
| "phash"
|
||||||
|
| "director"
|
||||||
|
| "synopsis";
|
||||||
|
|||||||
Reference in New Issue
Block a user