mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
merge sorting + add URLs
This commit is contained in:
parent
e0de8e7c7c
commit
e057b2899b
8 changed files with 56 additions and 0 deletions
|
|
@ -89,6 +89,10 @@ input TitleDuplicationCriterionInput {
|
|||
duplicated: Boolean
|
||||
}
|
||||
|
||||
input URLDuplicationCriterionInput {
|
||||
duplicated: Boolean
|
||||
}
|
||||
|
||||
input StashIDCriterionInput {
|
||||
"""
|
||||
If present, this value is treated as a predicate.
|
||||
|
|
@ -262,6 +266,8 @@ input SceneFilterType {
|
|||
duplicated_stash_id: StashIDDuplicationCriterionInput
|
||||
"Filter Scenes that have the same title"
|
||||
duplicated_title: TitleDuplicationCriterionInput
|
||||
"Filter Scenes that have the same URL"
|
||||
duplicated_url: URLDuplicationCriterionInput
|
||||
"Filter by resolution"
|
||||
resolution: ResolutionCriterionInput
|
||||
"Filter by orientation"
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ type TitleDuplicationCriterionInput struct {
|
|||
Duplicated *bool `json:"duplicated"`
|
||||
}
|
||||
|
||||
type URLDuplicationCriterionInput struct {
|
||||
Duplicated *bool `json:"duplicated"`
|
||||
}
|
||||
|
||||
type SceneFilterType struct {
|
||||
OperatorFilter[SceneFilterType]
|
||||
ID *IntCriterionInput `json:"id"`
|
||||
|
|
@ -47,6 +51,8 @@ type SceneFilterType struct {
|
|||
DuplicatedStashID *StashIDDuplicationCriterionInput `json:"duplicated_stash_id"`
|
||||
// Filter Scenes that have the same title
|
||||
DuplicatedTitle *TitleDuplicationCriterionInput `json:"duplicated_title"`
|
||||
// Filter Scenes that have the same URL
|
||||
DuplicatedURL *URLDuplicationCriterionInput `json:"duplicated_url"`
|
||||
// Filter by resolution
|
||||
Resolution *ResolutionCriterionInput `json:"resolution"`
|
||||
// Filter by orientation
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ func (qb *sceneFilterHandler) criterionHandler() criterionHandler {
|
|||
qb.phashDuplicatedCriterionHandler(sceneFilter.Duplicated, qb.addSceneFilesTable),
|
||||
qb.stashIDDuplicatedCriterionHandler(sceneFilter.DuplicatedStashID),
|
||||
qb.titleDuplicatedCriterionHandler(sceneFilter.DuplicatedTitle),
|
||||
qb.urlDuplicatedCriterionHandler(sceneFilter.DuplicatedURL),
|
||||
&dateCriterionHandler{sceneFilter.Date, "scenes.date", nil},
|
||||
×tampCriterionHandler{sceneFilter.CreatedAt, "scenes.created_at", nil},
|
||||
×tampCriterionHandler{sceneFilter.UpdatedAt, "scenes.updated_at", nil},
|
||||
|
|
@ -331,6 +332,22 @@ func (qb *sceneFilterHandler) titleDuplicatedCriterionHandler(duplicatedFilter *
|
|||
}
|
||||
}
|
||||
|
||||
func (qb *sceneFilterHandler) urlDuplicatedCriterionHandler(duplicatedFilter *models.URLDuplicationCriterionInput) criterionHandlerFunc {
|
||||
return func(ctx context.Context, f *filterBuilder) {
|
||||
if duplicatedFilter != nil && duplicatedFilter.Duplicated != nil {
|
||||
var v string
|
||||
if *duplicatedFilter.Duplicated {
|
||||
v = ">"
|
||||
} else {
|
||||
v = "="
|
||||
}
|
||||
|
||||
// Find URLs that appear on more than one scene
|
||||
f.addInnerJoin("(SELECT scene_id FROM scene_urls INNER JOIN (SELECT url FROM scene_urls GROUP BY url HAVING COUNT(DISTINCT scene_id) "+v+" 1) dupes ON scene_urls.url = dupes.url)", "scurl", "scenes.id = scurl.scene_id")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (qb *sceneFilterHandler) codecCriterionHandler(codec *models.StringCriterionInput, codecColumn string, addJoinFn func(f *filterBuilder)) criterionHandlerFunc {
|
||||
return func(ctx context.Context, f *filterBuilder) {
|
||||
if codec != nil {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Option, SelectedList } from "./SidebarListFilter";
|
|||
import { DuplicatedCriterionOption } from "src/models/list-filter/criteria/phash";
|
||||
import { DuplicatedStashIDCriterionOption } from "src/models/list-filter/criteria/stash-ids";
|
||||
import { DuplicatedTitleCriterionOption } from "src/models/list-filter/criteria/title";
|
||||
import { DuplicatedURLCriterionOption } from "src/models/list-filter/criteria/url";
|
||||
import { SidebarSection } from "src/components/Shared/Sidebar";
|
||||
import { Icon } from "src/components/Shared/Icon";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
|
|
@ -16,6 +17,7 @@ const DUPLICATE_TYPES = {
|
|||
phash: DuplicatedCriterionOption,
|
||||
stash_id: DuplicatedStashIDCriterionOption,
|
||||
title: DuplicatedTitleCriterionOption,
|
||||
url: DuplicatedURLCriterionOption,
|
||||
} as const;
|
||||
|
||||
type DuplicateTypeId = keyof typeof DUPLICATE_TYPES;
|
||||
|
|
@ -32,6 +34,7 @@ const DUPLICATE_TYPE_MESSAGE_IDS: Record<DuplicateTypeId, string> = {
|
|||
phash: "media_info.phash",
|
||||
stash_id: "stash_id",
|
||||
title: "title",
|
||||
url: "url",
|
||||
};
|
||||
|
||||
export const SidebarDuplicateFilter: React.FC<ISidebarDuplicateFilterProps> = ({
|
||||
|
|
|
|||
|
|
@ -1063,6 +1063,7 @@
|
|||
"duplicated_phash": "Duplicated (pHash)",
|
||||
"duplicated_stash_id": "Duplicated (Stash ID)",
|
||||
"duplicated_title": "Duplicated (Title)",
|
||||
"duplicated_url": "Duplicated (URL)",
|
||||
"duration": "Duration",
|
||||
"effect_filters": {
|
||||
"aspect": "Aspect",
|
||||
|
|
|
|||
20
ui/v2.5/src/models/list-filter/criteria/url.ts
Normal file
20
ui/v2.5/src/models/list-filter/criteria/url.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { UrlDuplicationCriterionInput } from "src/core/generated-graphql";
|
||||
import { BooleanCriterionOption, StringCriterion } from "./criterion";
|
||||
|
||||
export const DuplicatedURLCriterionOption = new BooleanCriterionOption(
|
||||
"duplicated_url",
|
||||
"duplicated_url",
|
||||
() => new DuplicatedURLCriterion()
|
||||
);
|
||||
|
||||
export class DuplicatedURLCriterion extends StringCriterion {
|
||||
constructor() {
|
||||
super(DuplicatedURLCriterionOption);
|
||||
}
|
||||
|
||||
public toCriterionInput(): UrlDuplicationCriterionInput {
|
||||
return {
|
||||
duplicated: this.value === "true",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ import {
|
|||
StashIDCriterionOption,
|
||||
} from "./criteria/stash-ids";
|
||||
import { DuplicatedTitleCriterionOption } from "./criteria/title";
|
||||
import { DuplicatedURLCriterionOption } from "./criteria/url";
|
||||
import { RatingCriterionOption } from "./criteria/rating";
|
||||
import { PathCriterionOption } from "./criteria/path";
|
||||
import { OrientationCriterionOption } from "./criteria/orientation";
|
||||
|
|
@ -106,6 +107,7 @@ const criterionOptions = [
|
|||
DuplicatedCriterionOption,
|
||||
DuplicatedStashIDCriterionOption,
|
||||
DuplicatedTitleCriterionOption,
|
||||
DuplicatedURLCriterionOption,
|
||||
OrganizedCriterionOption,
|
||||
RatingCriterionOption,
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count", {
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ export type CriterionType =
|
|||
| "duplicated"
|
||||
| "duplicated_stash_id"
|
||||
| "duplicated_title"
|
||||
| "duplicated_url"
|
||||
| "ignore_auto_tag"
|
||||
| "file_count"
|
||||
| "stash_id_endpoint"
|
||||
|
|
|
|||
Loading…
Reference in a new issue