From db1e5c63d090a3e3d4872ab8fd9756def6523d7a Mon Sep 17 00:00:00 2001 From: InfiniteTF Date: Mon, 25 Oct 2021 01:49:37 +0200 Subject: [PATCH] Fix performer tagger (#1874) * Fix performer tagger --- .../src/components/Tagger/PerformerModal.tsx | 4 +- .../Tagger/performers/PerformerTagger.tsx | 23 +- .../Tagger/performers/StashSearchResult.tsx | 50 ++-- ui/v2.5/src/components/Tagger/utils.ts | 235 ------------------ 4 files changed, 35 insertions(+), 277 deletions(-) diff --git a/ui/v2.5/src/components/Tagger/PerformerModal.tsx b/ui/v2.5/src/components/Tagger/PerformerModal.tsx index f16f11e58..0c7057593 100755 --- a/ui/v2.5/src/components/Tagger/PerformerModal.tsx +++ b/ui/v2.5/src/components/Tagger/PerformerModal.tsx @@ -118,7 +118,7 @@ const PerformerModal: React.FC = ({ const performerData: GQL.PerformerCreateInput = { name: performer.name ?? "", aliases: performer.aliases, - gender: stringToGender(performer.gender ?? undefined), + gender: stringToGender(performer.gender ?? undefined, true), birthdate: performer.birthdate, ethnicity: performer.ethnicity, eye_color: performer.eye_color, @@ -162,7 +162,7 @@ const PerformerModal: React.FC = ({ // handle exclusions Object.keys(performerData).forEach((k) => { - if (excludedPerformerFields.includes(k) || excluded[k]) { + if (excluded[k]) { (performerData as Record)[k] = undefined; } }); diff --git a/ui/v2.5/src/components/Tagger/performers/PerformerTagger.tsx b/ui/v2.5/src/components/Tagger/performers/PerformerTagger.tsx index 947ccee02..0ca2a6123 100755 --- a/ui/v2.5/src/components/Tagger/performers/PerformerTagger.tsx +++ b/ui/v2.5/src/components/Tagger/performers/PerformerTagger.tsx @@ -18,7 +18,6 @@ import { ConfigurationContext } from "src/hooks/Config"; import StashSearchResult from "./StashSearchResult"; import PerformerConfig from "./Config"; import { LOCAL_FORAGE_KEY, ITaggerConfig, initialConfig } from "../constants"; -import { IStashBoxPerformer, selectPerformers } from "../utils"; import PerformerModal from "../PerformerModal"; import { useUpdatePerformer } from "../queries"; @@ -51,7 +50,7 @@ const PerformerTaggerList: React.FC = ({ const intl = useIntl(); const [loading, setLoading] = useState(false); const [searchResults, setSearchResults] = useState< - Record + Record >({}); const [searchErrors, setSearchErrors] = useState< Record @@ -87,13 +86,13 @@ const PerformerTaggerList: React.FC = ({ >({}); const [loadingUpdate, setLoadingUpdate] = useState(); const [modalPerformer, setModalPerformer] = useState< - IStashBoxPerformer | undefined + GQL.ScrapedPerformerDataFragment | undefined >(); const doBoxSearch = (performerID: string, searchVal: string) => { stashBoxPerformerQuery(searchVal, selectedEndpoint.index) .then((queryData) => { - const s = selectPerformers(queryData.data?.scrapeSinglePerformer ?? []); + const s = queryData.data?.scrapeSinglePerformer ?? []; setSearchResults({ ...searchResults, [performerID]: s, @@ -130,13 +129,11 @@ const PerformerTaggerList: React.FC = ({ }); stashBoxPerformerQuery(stashID, endpointIndex) .then((queryData) => { - const data = selectPerformers( - queryData.data?.scrapeSinglePerformer ?? [] - ); + const data = queryData.data?.scrapeSinglePerformer ?? []; if (data.length > 0) { setModalPerformer({ ...data[0], - id: performerID, + stored_id: performerID, }); } }) @@ -168,20 +165,20 @@ const PerformerTaggerList: React.FC = ({ const updatePerformer = useUpdatePerformer(); const handlePerformerUpdate = async (input: GQL.PerformerCreateInput) => { - const performerData = modalPerformer; setModalPerformer(undefined); - if (performerData?.id) { + const performerID = modalPerformer?.stored_id; + if (performerID) { const updateData: GQL.PerformerUpdateInput = { - id: performerData.id, ...input, + id: performerID, }; const res = await updatePerformer(updateData); if (!res.data?.performerUpdate) setError({ ...error, - [performerData.id]: { - message: `Failed to save performer "${performerData.name}"`, + [performerID]: { + message: `Failed to save performer "${modalPerformer?.name}"`, details: res?.errors?.[0].message === "UNIQUE constraint failed: performers.checksum" diff --git a/ui/v2.5/src/components/Tagger/performers/StashSearchResult.tsx b/ui/v2.5/src/components/Tagger/performers/StashSearchResult.tsx index cd97d2dfa..90a0089ee 100755 --- a/ui/v2.5/src/components/Tagger/performers/StashSearchResult.tsx +++ b/ui/v2.5/src/components/Tagger/performers/StashSearchResult.tsx @@ -2,13 +2,12 @@ import React, { useState } from "react"; import { Button } from "react-bootstrap"; import * as GQL from "src/core/generated-graphql"; -import { IStashBoxPerformer } from "../utils"; import { useUpdatePerformer } from "../queries"; import PerformerModal from "../PerformerModal"; interface IStashSearchResultProps { performer: GQL.SlimPerformerDataFragment; - stashboxPerformers: IStashBoxPerformer[]; + stashboxPerformers: GQL.ScrapedPerformerDataFragment[]; endpoint: string; onPerformerTagged: ( performer: Pick & @@ -25,7 +24,7 @@ const StashSearchResult: React.FC = ({ endpoint, }) => { const [modalPerformer, setModalPerformer] = useState< - IStashBoxPerformer | undefined + GQL.ScrapedPerformerDataFragment | undefined >(); const [saveState, setSaveState] = useState(""); const [error, setError] = useState<{ message?: string; details?: string }>( @@ -35,41 +34,38 @@ const StashSearchResult: React.FC = ({ const updatePerformer = useUpdatePerformer(); const handleSave = async (input: GQL.PerformerCreateInput) => { - const performerData = modalPerformer; - if (performerData?.id) { - setError({}); - setSaveState("Saving performer"); - setModalPerformer(undefined); + setError({}); + setSaveState("Saving performer"); + setModalPerformer(undefined); - const updateData: GQL.PerformerUpdateInput = { - id: performerData.id, - ...input, - }; + const updateData: GQL.PerformerUpdateInput = { + ...input, + id: performer.id, + }; - const res = await updatePerformer(updateData); + const res = await updatePerformer(updateData); - if (!res?.data?.performerUpdate) - setError({ - message: `Failed to save performer "${performer.name}"`, - details: - res?.errors?.[0].message === - "UNIQUE constraint failed: performers.checksum" - ? "Name already exists" - : res?.errors?.[0].message, - }); - else onPerformerTagged(performer); - setSaveState(""); - } + if (!res?.data?.performerUpdate) + setError({ + message: `Failed to save performer "${performer.name}"`, + details: + res?.errors?.[0].message === + "UNIQUE constraint failed: performers.checksum" + ? "Name already exists" + : res?.errors?.[0].message, + }); + else onPerformerTagged(performer); + setSaveState(""); }; const performers = stashboxPerformers.map((p) => ( )); diff --git a/ui/v2.5/src/components/Tagger/utils.ts b/ui/v2.5/src/components/Tagger/utils.ts index d4cfe43da..6f8f7fdff 100644 --- a/ui/v2.5/src/components/Tagger/utils.ts +++ b/ui/v2.5/src/components/Tagger/utils.ts @@ -1,5 +1,4 @@ import * as GQL from "src/core/generated-graphql"; -import { getCountryByISO } from "src/utils/country"; import { ParseMode } from "./constants"; const months = [ @@ -112,14 +111,6 @@ export function prepareQueryString( return s.replace(/\./g, " "); } -const toTitleCase = (phrase: string) => { - return phrase - .toLowerCase() - .split(" ") - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(" "); -}; - export const parsePath = (filePath: string) => { const path = filePath.toLowerCase(); const isWin = /^([a-z]:|\\\\)/.test(path); @@ -140,229 +131,3 @@ export const parsePath = (filePath: string) => { return { paths, file, ext }; }; - -export interface IStashBoxFingerprint { - hash: string; - algorithm: string; - duration: number; -} - -export interface IStashBoxPerformer { - id?: string; - stash_id: string; - name: string; - gender?: GQL.GenderEnum; - url?: string; - twitter?: string; - instagram?: string; - birthdate?: string; - ethnicity?: string; - country?: string; - eye_color?: string; - height?: string; - measurements?: string; - fake_tits?: string; - career_length?: string; - tattoos?: string; - piercings?: string; - aliases?: string; - images: string[]; - details?: string; - death_date?: string; - hair_color?: string; - weight?: string; -} - -export interface IStashBoxTag { - id?: string; - name: string; -} - -export interface IStashBoxStudio { - id?: string; - stash_id: string; - name: string; - url?: string; - image?: string; -} - -export interface IStashBoxScene { - stash_id: string; - title: string; - date: string; - duration: number; - details?: string; - url?: string; - - studio: IStashBoxStudio; - images: string[]; - tags: IStashBoxTag[]; - performers: IStashBoxPerformer[]; - fingerprints: IStashBoxFingerprint[]; -} - -const selectStudio = (studio: GQL.ScrapedStudio): IStashBoxStudio => ({ - id: studio?.stored_id ?? undefined, - stash_id: studio.remote_site_id!, - name: studio.name, - url: studio.url ?? undefined, -}); - -const selectFingerprints = ( - scene: GQL.ScrapedScene | null -): IStashBoxFingerprint[] => scene?.fingerprints ?? []; - -const selectTags = (tags: GQL.ScrapedTag[]): IStashBoxTag[] => - tags.map((t) => ({ - id: t.stored_id ?? undefined, - name: t.name ?? "", - })); - -export const selectPerformers = ( - performers: GQL.ScrapedPerformer[] -): IStashBoxPerformer[] => - performers.map((p) => ({ - id: p.stored_id ?? undefined, - stash_id: p.remote_site_id!, - name: p.name ?? "", - gender: (p.gender ?? GQL.GenderEnum.Female) as GQL.GenderEnum, - url: p.url ?? undefined, - twitter: p.twitter ?? undefined, - instagram: p.instagram ?? undefined, - birthdate: p.birthdate ?? undefined, - ethnicity: p.ethnicity ? toTitleCase(p.ethnicity) : undefined, - country: getCountryByISO(p.country) ?? undefined, - eye_color: p.eye_color ? toTitleCase(p.eye_color) : undefined, - height: p.height ?? undefined, - measurements: p.measurements ?? undefined, - fake_tits: p.fake_tits ? toTitleCase(p.fake_tits) : undefined, - career_length: p.career_length ?? undefined, - tattoos: p.tattoos ? toTitleCase(p.tattoos) : undefined, - piercings: p.piercings ? toTitleCase(p.piercings) : undefined, - aliases: p.aliases ?? undefined, - images: p.images ?? [], - details: p.details ?? undefined, - death_date: p.death_date ?? undefined, - hair_color: p.hair_color ?? undefined, - })); - -export const selectScenes = ( - scenes?: (GQL.ScrapedScene | null)[] -): IStashBoxScene[] => { - const result = (scenes ?? []) - .filter((s) => s !== null) - .map( - (s) => - ({ - stash_id: s?.remote_site_id!, - title: s?.title ?? "", - date: s?.date ?? "", - duration: s?.duration ?? 0, - details: s?.details, - url: s?.url, - images: s?.image ? [s.image] : [], - studio: selectStudio(s?.studio!), - fingerprints: selectFingerprints(s), - performers: selectPerformers(s?.performers ?? []), - tags: selectTags(s?.tags ?? []), - } as IStashBoxScene) - ); - - return result; -}; - -export const sortScenesByDuration = ( - scenes: IStashBoxScene[], - targetDuration?: number -) => - scenes.sort((a, b) => { - if (!targetDuration) return 0; - - const aDur = [ - a.duration, - ...a.fingerprints.map((f) => f.duration), - ].map((d) => Math.abs(d - targetDuration)); - const bDur = [ - b.duration, - ...b.fingerprints.map((f) => f.duration), - ].map((d) => Math.abs(d - targetDuration)); - - if (aDur.length > 0 && bDur.length === 0) return -1; - if (aDur.length === 0 && bDur.length > 0) return 1; - - const aMatches = aDur.filter((match) => match <= 5); - const bMatches = bDur.filter((match) => match <= 5); - - if (aMatches.length > 0 || bMatches.length > 0) { - if (aMatches.length > bMatches.length) return -1; - if (aMatches.length < bMatches.length) return 1; - return 0; - } - - const aDiff = Math.min(...aDur); - const bDiff = Math.min(...bDur); - - if (aDiff < bDiff) return -1; - if (aDiff > bDiff) return 1; - return 0; - }); - -export const filterPerformer = ( - performer: IStashBoxPerformer, - excludedFields: string[] -) => { - const { - name, - aliases, - gender, - birthdate, - ethnicity, - country, - eye_color, - height, - measurements, - fake_tits, - career_length, - tattoos, - piercings, - } = performer; - return { - name: !excludedFields.includes("name") && name ? name : undefined, - aliases: - !excludedFields.includes("aliases") && aliases ? aliases : undefined, - gender: !excludedFields.includes("gender") && gender ? gender : undefined, - birthdate: - !excludedFields.includes("birthdate") && birthdate - ? birthdate - : undefined, - ethnicity: - !excludedFields.includes("ethnicity") && ethnicity - ? ethnicity - : undefined, - country: - !excludedFields.includes("country") && country ? country : undefined, - eye_color: - !excludedFields.includes("eye_color") && eye_color - ? eye_color - : undefined, - height: !excludedFields.includes("height") && height ? height : undefined, - measurements: - !excludedFields.includes("measurements") && measurements - ? measurements - : undefined, - fake_tits: - !excludedFields.includes("fake_tits") && fake_tits - ? fake_tits - : undefined, - career_length: - !excludedFields.includes("career_length") && career_length - ? career_length - : undefined, - tattoos: - !excludedFields.includes("tattoos") && tattoos ? tattoos : undefined, - piercings: - !excludedFields.includes("piercings") && piercings - ? piercings - : undefined, - }; -};