mirror of
https://github.com/stashapp/stash.git
synced 2026-04-19 21:41:42 +02:00
FR: Add Missing is-missing Filter Options Across all Object Types (#6565)
Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
parent
ed58d18334
commit
b77abd64e2
9 changed files with 142 additions and 6 deletions
|
|
@ -308,7 +308,16 @@ func (qb *galleryFilterHandler) missingCriterionHandler(isMissing *string) crite
|
|||
case "tags":
|
||||
galleryRepository.tags.join(f, "tags_join", "galleries.id")
|
||||
f.addWhere("tags_join.gallery_id IS NULL")
|
||||
case "cover":
|
||||
f.addLeftJoin("galleries_images", "cover_join", "cover_join.gallery_id = galleries.id AND cover_join.cover = 1")
|
||||
f.addWhere("cover_join.image_id IS NULL")
|
||||
default:
|
||||
if err := validateIsMissing(*isMissing, []string{
|
||||
"title", "code", "rating", "details", "photographer",
|
||||
}); err != nil {
|
||||
f.setError(err)
|
||||
return
|
||||
}
|
||||
f.addWhere("(galleries." + *isMissing + " IS NULL OR TRIM(galleries." + *isMissing + ") = '')")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,25 @@ func (qb *groupFilterHandler) missingCriterionHandler(isMissing *string) criteri
|
|||
case "scenes":
|
||||
f.addLeftJoin("groups_scenes", "", "groups_scenes.group_id = groups.id")
|
||||
f.addWhere("groups_scenes.scene_id IS NULL")
|
||||
case "url":
|
||||
groupsURLsTableMgr.join(f, "", "groups.id")
|
||||
f.addWhere("group_urls.url IS NULL")
|
||||
case "studio":
|
||||
f.addWhere("groups.studio_id IS NULL")
|
||||
case "performers":
|
||||
f.addLeftJoin("groups_scenes", "gs_perf", "groups.id = gs_perf.group_id")
|
||||
f.addLeftJoin("performers_scenes", "ps_perf", "gs_perf.scene_id = ps_perf.scene_id")
|
||||
f.addWhere("ps_perf.performer_id IS NULL")
|
||||
case "tags":
|
||||
groupRepository.tags.join(f, "tags_join", "groups.id")
|
||||
f.addWhere("tags_join.group_id IS NULL")
|
||||
default:
|
||||
if err := validateIsMissing(*isMissing, []string{
|
||||
"aliases", "description", "director", "date", "rating",
|
||||
}); err != nil {
|
||||
f.setError(err)
|
||||
return
|
||||
}
|
||||
f.addWhere("(groups." + *isMissing + " IS NULL OR TRIM(groups." + *isMissing + ") = '')")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,9 @@ func (qb *imageFilterHandler) missingCriterionHandler(isMissing *string) criteri
|
|||
return func(ctx context.Context, f *filterBuilder) {
|
||||
if isMissing != nil && *isMissing != "" {
|
||||
switch *isMissing {
|
||||
case "url":
|
||||
imagesURLsTableMgr.join(f, "", "images.id")
|
||||
f.addWhere("image_urls.url IS NULL")
|
||||
case "studio":
|
||||
f.addWhere("images.studio_id IS NULL")
|
||||
case "performers":
|
||||
|
|
@ -183,6 +186,12 @@ func (qb *imageFilterHandler) missingCriterionHandler(isMissing *string) criteri
|
|||
imageRepository.tags.join(f, "tags_join", "images.id")
|
||||
f.addWhere("tags_join.image_id IS NULL")
|
||||
default:
|
||||
if err := validateIsMissing(*isMissing, []string{
|
||||
"title", "details", "photographer", "date", "code", "rating",
|
||||
}); err != nil {
|
||||
f.setError(err)
|
||||
return
|
||||
}
|
||||
f.addWhere("(images." + *isMissing + " IS NULL OR TRIM(images." + *isMissing + ") = '')")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,7 +316,19 @@ func (qb *performerFilterHandler) performerIsMissingCriterionHandler(isMissing *
|
|||
case "aliases":
|
||||
performersAliasesTableMgr.join(f, "", "performers.id")
|
||||
f.addWhere("performer_aliases.alias IS NULL")
|
||||
case "tags":
|
||||
f.addLeftJoin(performersTagsTable, "tags_join", "tags_join.performer_id = performers.id")
|
||||
f.addWhere("tags_join.performer_id IS NULL")
|
||||
default:
|
||||
if err := validateIsMissing(*isMissing, []string{
|
||||
"disambiguation", "gender", "birthdate", "death_date",
|
||||
"ethnicity", "country", "hair_color", "eye_color", "height", "weight",
|
||||
"measurements", "fake_tits", "penis_length", "circumcised",
|
||||
"career_start", "career_end", "tattoos", "piercings", "details", "rating",
|
||||
}); err != nil {
|
||||
f.setError(err)
|
||||
return
|
||||
}
|
||||
f.addWhere("(performers." + *isMissing + " IS NULL OR TRIM(performers." + *isMissing + ") = '')")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -426,6 +426,12 @@ func (qb *sceneFilterHandler) isMissingCriterionHandler(isMissing *string) crite
|
|||
case "cover":
|
||||
f.addWhere("scenes.cover_blob IS NULL")
|
||||
default:
|
||||
if err := validateIsMissing(*isMissing, []string{
|
||||
"title", "code", "details", "director", "rating",
|
||||
}); err != nil {
|
||||
f.setError(err)
|
||||
return
|
||||
}
|
||||
f.addWhere("(scenes." + *isMissing + " IS NULL OR TRIM(scenes." + *isMissing + ") = '')")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,16 @@ func (o sortOptions) validateSort(sort string) error {
|
|||
return fmt.Errorf("invalid sort: %s", sort)
|
||||
}
|
||||
|
||||
func validateIsMissing(isMissing string, allowed []string) error {
|
||||
for _, v := range allowed {
|
||||
if v == isMissing {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid is_missing field: %s", isMissing)
|
||||
}
|
||||
|
||||
func getSortDirection(direction string) string {
|
||||
if direction != "ASC" && direction != "DESC" {
|
||||
return "ASC"
|
||||
|
|
|
|||
|
|
@ -150,7 +150,19 @@ func (qb *studioFilterHandler) isMissingCriterionHandler(isMissing *string) crit
|
|||
case "stash_id":
|
||||
studioRepository.stashIDs.join(f, "studio_stash_ids", "studios.id")
|
||||
f.addWhere("studio_stash_ids.studio_id IS NULL")
|
||||
case "aliases":
|
||||
studiosAliasesTableMgr.join(f, "", "studios.id")
|
||||
f.addWhere("studio_aliases.alias IS NULL")
|
||||
case "tags":
|
||||
f.addLeftJoin(studiosTagsTable, "tags_join", "tags_join.studio_id = studios.id")
|
||||
f.addWhere("tags_join.studio_id IS NULL")
|
||||
default:
|
||||
if err := validateIsMissing(*isMissing, []string{
|
||||
"details", "rating",
|
||||
}); err != nil {
|
||||
f.setError(err)
|
||||
return
|
||||
}
|
||||
f.addWhere("(studios." + *isMissing + " IS NULL OR TRIM(studios." + *isMissing + ") = '')")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,7 +198,19 @@ func (qb *tagFilterHandler) isMissingCriterionHandler(isMissing *string) criteri
|
|||
switch *isMissing {
|
||||
case "image":
|
||||
f.addWhere("tags.image_blob IS NULL")
|
||||
case "aliases":
|
||||
tagRepository.aliases.join(f, "", "tags.id")
|
||||
f.addWhere("tag_aliases.alias IS NULL")
|
||||
case "stash_id":
|
||||
tagRepository.stashIDs.join(f, "tag_stash_ids", "tags.id")
|
||||
f.addWhere("tag_stash_ids.tag_id IS NULL")
|
||||
default:
|
||||
if err := validateIsMissing(*isMissing, []string{
|
||||
"description",
|
||||
}); err != nil {
|
||||
f.setError(err)
|
||||
return
|
||||
}
|
||||
f.addWhere("(tags." + *isMissing + " IS NULL OR TRIM(tags." + *isMissing + ") = '')")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,13 @@ export const SceneIsMissingCriterionOption = new IsMissingCriterionOption(
|
|||
"is_missing",
|
||||
[
|
||||
"title",
|
||||
"cover",
|
||||
"code",
|
||||
"details",
|
||||
"director",
|
||||
"url",
|
||||
"date",
|
||||
"rating",
|
||||
"cover",
|
||||
"galleries",
|
||||
"studio",
|
||||
"group",
|
||||
|
|
@ -42,7 +45,19 @@ export const SceneIsMissingCriterionOption = new IsMissingCriterionOption(
|
|||
export const ImageIsMissingCriterionOption = new IsMissingCriterionOption(
|
||||
"isMissing",
|
||||
"is_missing",
|
||||
["title", "galleries", "studio", "performers", "tags"]
|
||||
[
|
||||
"title",
|
||||
"details",
|
||||
"photographer",
|
||||
"url",
|
||||
"date",
|
||||
"code",
|
||||
"rating",
|
||||
"galleries",
|
||||
"studio",
|
||||
"performers",
|
||||
"tags",
|
||||
]
|
||||
);
|
||||
|
||||
export const PerformerIsMissingCriterionOption = new IsMissingCriterionOption(
|
||||
|
|
@ -58,14 +73,21 @@ export const PerformerIsMissingCriterionOption = new IsMissingCriterionOption(
|
|||
"weight",
|
||||
"measurements",
|
||||
"fake_tits",
|
||||
"penis_length",
|
||||
"circumcised",
|
||||
"career_start",
|
||||
"career_end",
|
||||
"tattoos",
|
||||
"piercings",
|
||||
"aliases",
|
||||
"gender",
|
||||
"birthdate",
|
||||
"death_date",
|
||||
"disambiguation",
|
||||
"tags",
|
||||
"image",
|
||||
"details",
|
||||
"rating",
|
||||
"stash_id",
|
||||
]
|
||||
);
|
||||
|
|
@ -73,23 +95,49 @@ export const PerformerIsMissingCriterionOption = new IsMissingCriterionOption(
|
|||
export const GalleryIsMissingCriterionOption = new IsMissingCriterionOption(
|
||||
"isMissing",
|
||||
"is_missing",
|
||||
["title", "details", "url", "date", "studio", "performers", "tags", "scenes"]
|
||||
[
|
||||
"title",
|
||||
"code",
|
||||
"details",
|
||||
"photographer",
|
||||
"url",
|
||||
"date",
|
||||
"rating",
|
||||
"cover",
|
||||
"studio",
|
||||
"performers",
|
||||
"tags",
|
||||
"scenes",
|
||||
]
|
||||
);
|
||||
|
||||
export const TagIsMissingCriterionOption = new IsMissingCriterionOption(
|
||||
"isMissing",
|
||||
"is_missing",
|
||||
["image"]
|
||||
["image", "aliases", "description", "stash_id"]
|
||||
);
|
||||
|
||||
export const StudioIsMissingCriterionOption = new IsMissingCriterionOption(
|
||||
"isMissing",
|
||||
"is_missing",
|
||||
["image", "stash_id", "details"]
|
||||
["image", "stash_id", "details", "url", "aliases", "tags", "rating"]
|
||||
);
|
||||
|
||||
export const GroupIsMissingCriterionOption = new IsMissingCriterionOption(
|
||||
"isMissing",
|
||||
"is_missing",
|
||||
["front_image", "back_image", "scenes"]
|
||||
[
|
||||
"aliases",
|
||||
"description",
|
||||
"director",
|
||||
"date",
|
||||
"url",
|
||||
"rating",
|
||||
"studio",
|
||||
"performers",
|
||||
"tags",
|
||||
"front_image",
|
||||
"back_image",
|
||||
"scenes",
|
||||
]
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue