From eb795ff9ab90a6ec5053a8676fa5fec51096d55f Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Thu, 10 Nov 2022 12:51:49 +1100 Subject: [PATCH] Add new fields to scene tagger (#3094) * Add new fields to scene tagger * Update scraper docs with new fields * Set code and director in identify * Add new fields to identify dialog --- internal/identify/identify.go | 10 ++++++ .../Dialogs/IdentifyDialog/FieldOptions.tsx | 11 ++++-- .../Dialogs/IdentifyDialog/constants.ts | 10 ++++++ .../Tagger/scenes/StashSearchResult.tsx | 36 +++++++++++++++++++ .../src/docs/en/Manual/ScraperDevelopment.md | 2 ++ 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/internal/identify/identify.go b/internal/identify/identify.go index 98bcaa34e..c828f4164 100644 --- a/internal/identify/identify.go +++ b/internal/identify/identify.go @@ -280,6 +280,16 @@ func getScenePartial(scene *models.Scene, scraped *scraper.ScrapedScene, fieldOp partial.URL = models.NewOptionalString(*scraped.URL) } } + if scraped.Director != nil && (scene.Director != *scraped.Director) { + if shouldSetSingleValueField(fieldOptions["director"], scene.Director != "") { + partial.Director = models.NewOptionalString(*scraped.Director) + } + } + if scraped.Code != nil && (scene.Code != *scraped.Code) { + if shouldSetSingleValueField(fieldOptions["code"], scene.Code != "") { + partial.Code = models.NewOptionalString(*scraped.Code) + } + } if setOrganized && !scene.Organized { // just reuse the boolean since we know it's true diff --git a/ui/v2.5/src/components/Dialogs/IdentifyDialog/FieldOptions.tsx b/ui/v2.5/src/components/Dialogs/IdentifyDialog/FieldOptions.tsx index 8b04da91b..f8c146fbb 100644 --- a/ui/v2.5/src/components/Dialogs/IdentifyDialog/FieldOptions.tsx +++ b/ui/v2.5/src/components/Dialogs/IdentifyDialog/FieldOptions.tsx @@ -3,7 +3,12 @@ import { Form, Button, Table } from "react-bootstrap"; import { Icon } from "src/components/Shared"; import * as GQL from "src/core/generated-graphql"; import { FormattedMessage, useIntl } from "react-intl"; -import { multiValueSceneFields, SceneField, sceneFields } from "./constants"; +import { + multiValueSceneFields, + SceneField, + sceneFieldMessageID, + sceneFields, +} from "./constants"; import { ThreeStateBoolean } from "./ThreeStateBoolean"; import { faCheck, @@ -13,7 +18,7 @@ import { interface IFieldOptionsEditor { options: GQL.IdentifyFieldOptions | undefined; - field: string; + field: SceneField; editField: () => void; editOptions: (o?: GQL.IdentifyFieldOptions | null) => void; editing: boolean; @@ -64,7 +69,7 @@ const FieldOptionsEditor: React.FC = ({ }, [resetOptions]); function renderField() { - return intl.formatMessage({ id: field }); + return intl.formatMessage({ id: sceneFieldMessageID(field) }); } function renderStrategy() { diff --git a/ui/v2.5/src/components/Dialogs/IdentifyDialog/constants.ts b/ui/v2.5/src/components/Dialogs/IdentifyDialog/constants.ts index 11c7fe6e8..dd4c0ba99 100644 --- a/ui/v2.5/src/components/Dialogs/IdentifyDialog/constants.ts +++ b/ui/v2.5/src/components/Dialogs/IdentifyDialog/constants.ts @@ -13,6 +13,8 @@ export const sceneFields = [ "date", "details", "url", + "code", + "director", "studio", "performers", "tags", @@ -25,3 +27,11 @@ export const multiValueSceneFields: SceneField[] = [ "performers", "tags", ]; + +export function sceneFieldMessageID(field: SceneField) { + if (field === "code") { + return "scene_code"; + } + + return field; +} diff --git a/ui/v2.5/src/components/Tagger/scenes/StashSearchResult.tsx b/ui/v2.5/src/components/Tagger/scenes/StashSearchResult.tsx index 3feb34a2e..5ced87910 100755 --- a/ui/v2.5/src/components/Tagger/scenes/StashSearchResult.tsx +++ b/ui/v2.5/src/components/Tagger/scenes/StashSearchResult.tsx @@ -365,6 +365,8 @@ const StashSearchResult: React.FC = ({ url: resolveField("url", stashScene.url, scene.url), tag_ids: tagIDs, stash_ids: stashScene.stash_ids ?? [], + code: resolveField("code", stashScene.code, scene.code), + director: resolveField("director", stashScene.director, scene.director), }; const includeStashID = !excludedFieldList.includes("stash_ids"); @@ -427,6 +429,8 @@ const StashSearchResult: React.FC = ({ details: "details", studio: "studio", stash_ids: "stash_ids", + code: "code", + director: "director", }; const maybeRenderCoverImage = () => { @@ -510,6 +514,21 @@ const StashSearchResult: React.FC = ({ } }; + const maybeRenderStudioCode = () => { + if (isActive && scene.code) { + return ( +
+ setExcludedField(fields.code, v)} + > + {scene.code} + +
+ ); + } + }; + const maybeRenderDateField = () => { if (isActive && scene.date) { return ( @@ -525,6 +544,21 @@ const StashSearchResult: React.FC = ({ } }; + const maybeRenderDirector = () => { + if (scene.director) { + return ( +
+ setExcludedField(fields.director, v)} + > + : {scene.director} + +
+ ); + } + }; + const maybeRenderURL = () => { if (scene.url) { return ( @@ -688,6 +722,7 @@ const StashSearchResult: React.FC = ({ )} + {maybeRenderStudioCode()} {maybeRenderDateField()} {getDurationStatus(scene, stashSceneFile?.duration)} {getFingerprintStatus(scene, stashScene)} @@ -696,6 +731,7 @@ const StashSearchResult: React.FC = ({ {isActive && (
{maybeRenderStashBoxID()} + {maybeRenderDirector()} {maybeRenderURL()} {maybeRenderDetails()}
diff --git a/ui/v2.5/src/docs/en/Manual/ScraperDevelopment.md b/ui/v2.5/src/docs/en/Manual/ScraperDevelopment.md index 4fd0ccedf..b0ff5cdfe 100644 --- a/ui/v2.5/src/docs/en/Manual/ScraperDevelopment.md +++ b/ui/v2.5/src/docs/en/Manual/ScraperDevelopment.md @@ -800,6 +800,8 @@ Details ``` Title Details +Code +Director URL Date Image