mirror of
https://github.com/stashapp/stash.git
synced 2026-04-24 16:04:56 +02:00
dupe checker select by codec
Added ability to select scenes in the duplicate checker based on preferred video codec. Added dropdown menu to select preferred video codec.
This commit is contained in:
parent
476688c84d
commit
7fe6469b75
2 changed files with 123 additions and 0 deletions
|
|
@ -48,6 +48,7 @@ import { objectTitle } from "src/core/files";
|
|||
const CLASSNAME = "duplicate-checker";
|
||||
|
||||
const defaultDurationDiff = "1";
|
||||
const defaultSelectedCodec = "hevc";
|
||||
|
||||
export const SceneDuplicateChecker: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
|
|
@ -59,6 +60,7 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
const durationDiff = Number.parseFloat(
|
||||
query.get("durationDiff") ?? defaultDurationDiff
|
||||
);
|
||||
let SelectedCodec = query.get("SelectedCodec") ?? defaultSelectedCodec;
|
||||
|
||||
const [currentPageSize, setCurrentPageSize] = useState(pageSize);
|
||||
const [isMultiDelete, setIsMultiDelete] = useState(false);
|
||||
|
|
@ -177,6 +179,19 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findSmallestScene = (group: GQL.SlimSceneDataFragment[]) => {
|
||||
// Get maximum file size of a scene
|
||||
const totalSize = (scene: GQL.SlimSceneDataFragment) => {
|
||||
return scene.files.reduce((prev: number, f) => Math.max(prev, f.size), 0);
|
||||
};
|
||||
// Find scene object with minimum total size
|
||||
return group.reduce((smallest, scene) => {
|
||||
const smallestSize = totalSize(smallest);
|
||||
const currentSize = totalSize(scene);
|
||||
return currentSize < smallestSize ? scene : smallest;
|
||||
});
|
||||
};
|
||||
|
||||
const findLargestResolutionScene = (group: GQL.SlimSceneDataFragment[]) => {
|
||||
// Get maximum resolution of a scene
|
||||
const sceneResolution = (scene: GQL.SlimSceneDataFragment) => {
|
||||
|
|
@ -259,6 +274,53 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
setCheckedScenes(checkedArray);
|
||||
};
|
||||
|
||||
const onSelectSmallestClick = () => {
|
||||
setSelectedScenes([]);
|
||||
const checkedArray: Record<string, boolean> = {};
|
||||
|
||||
filteredScenes.forEach((group) => {
|
||||
if (chkSafeSelect && !checkSameCodec(group)) {
|
||||
return;
|
||||
}
|
||||
// Find smallest scene in group a
|
||||
const smallest = findSmallestScene(group);
|
||||
group.forEach((scene) => {
|
||||
if (scene !== smallest) {
|
||||
checkedArray[scene.id] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
setCheckedScenes(checkedArray);
|
||||
};
|
||||
|
||||
const onSelectCodecClick = () => {
|
||||
setSelectedScenes([]);
|
||||
const checkedArray: Record<string, boolean> = {};
|
||||
|
||||
filteredScenes.forEach((group) => {
|
||||
if (chkSafeSelect && !checkSameCodec(group)) {
|
||||
return;
|
||||
}
|
||||
// select scenes where codec is not preferred
|
||||
let hasCodec = false;
|
||||
group.forEach((scene) => {
|
||||
if (scene.files[0]?.video_codec != SelectedCodec) {
|
||||
checkedArray[scene.id] = true;
|
||||
} else if (scene.files[0]?.video_codec == SelectedCodec) {
|
||||
hasCodec = true;
|
||||
}
|
||||
});
|
||||
if (!hasCodec) {
|
||||
// when no scenes with preferred codec are in the group select nothing
|
||||
group.forEach((scene) => {
|
||||
checkedArray[scene.id] = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
setCheckedScenes(checkedArray);
|
||||
};
|
||||
|
||||
const onSelectLargestResolutionClick = () => {
|
||||
setSelectedScenes([]);
|
||||
const checkedArray: Record<string, boolean> = {};
|
||||
|
|
@ -750,6 +812,47 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
</Col>
|
||||
</Row>
|
||||
</Form.Group>
|
||||
|
||||
<Form.Group>
|
||||
<Row noGutters>
|
||||
<Form.Label>
|
||||
<FormattedMessage id="dupe_check.select_all_but_specified_codec.title" />
|
||||
</Form.Label>
|
||||
<Col xs="auto">
|
||||
<Form.Control
|
||||
as="select"
|
||||
onChange={(e) =>
|
||||
setQuery({
|
||||
SelectedCodec:
|
||||
e.currentTarget.value === defaultSelectedCodec
|
||||
? undefined
|
||||
: e.currentTarget.value,
|
||||
page: undefined,
|
||||
})
|
||||
}
|
||||
defaultValue={SelectedCodec}
|
||||
className="input-control ml-4"
|
||||
>
|
||||
<option value={"av1"}>
|
||||
{intl.formatMessage({
|
||||
id: "dupe_check.select_all_but_specified_codec.av1",
|
||||
})}
|
||||
</option>
|
||||
<option value={"hevc"}>
|
||||
{intl.formatMessage({
|
||||
id: "dupe_check.select_all_but_specified_codec.hevc",
|
||||
})}
|
||||
</option>
|
||||
<option value={"h264"}>
|
||||
{intl.formatMessage({
|
||||
id: "dupe_check.select_all_but_specified_codec.h264",
|
||||
})}
|
||||
</option>
|
||||
</Form.Control>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form.Group>
|
||||
|
||||
<Form.Group>
|
||||
<Row noGutters>
|
||||
<Col xs="12">
|
||||
|
|
@ -762,6 +865,12 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
{intl.formatMessage({ id: "dupe_check.select_none" })}
|
||||
</Dropdown.Item>
|
||||
|
||||
<Dropdown.Item onClick={() => onSelectCodecClick()}>
|
||||
{intl.formatMessage({
|
||||
id: "dupe_check.select_all_but_specified_codec.label",
|
||||
})}
|
||||
</Dropdown.Item>
|
||||
|
||||
<Dropdown.Item
|
||||
onClick={() => onSelectLargestResolutionClick()}
|
||||
>
|
||||
|
|
@ -776,6 +885,12 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
})}
|
||||
</Dropdown.Item>
|
||||
|
||||
<Dropdown.Item onClick={() => onSelectSmallestClick()}>
|
||||
{intl.formatMessage({
|
||||
id: "dupe_check.select_all_but_smallest_file",
|
||||
})}
|
||||
</Dropdown.Item>
|
||||
|
||||
<Dropdown.Item onClick={() => onSelectByAge(true)}>
|
||||
{intl.formatMessage({
|
||||
id: "dupe_check.select_oldest",
|
||||
|
|
|
|||
|
|
@ -993,7 +993,15 @@
|
|||
"medium": "Medium"
|
||||
},
|
||||
"search_accuracy_label": "Search Accuracy",
|
||||
"select_all_but_specified_codec": {
|
||||
"title": "Preferred video codec",
|
||||
"label": "Select every file in each group, except for the file with the preferred codec",
|
||||
"av1": "av1",
|
||||
"hevc": "hevc",
|
||||
"h264": "h264"
|
||||
},
|
||||
"select_all_but_largest_file": "Select every file in each duplicated group, except the largest file",
|
||||
"select_all_but_smallest_file": "Select every file in each duplicated group, except the smallest file",
|
||||
"select_all_but_largest_resolution": "Select every file in each duplicated group, except the file with highest resolution",
|
||||
"select_none": "Select None",
|
||||
"select_oldest": "Select the oldest file in the duplicate group",
|
||||
|
|
|
|||
Loading…
Reference in a new issue