mirror of
https://github.com/stashapp/CommunityScripts.git
synced 2026-04-12 09:52:34 -05:00
Add SmartResolve plugin for duplicate scene workflows (#697)
* Add SmartResolve plugin for duplicate-checker workflow. Introduce SmartResolve with rule-based scene selection, protection/sync safeguards, in-row sync tooling, and documented settings for tuning Smart Resolve behavior. Made-with: Cursor * Update SmartResolve plugin to improve synchronization behavior and version increment to 1.0.02. Added a function to determine if a refresh is needed after sync, optimizing group loading based on cache state. * Revert Smart Resolve query-cache reuse in selection flow. Restore unconditional duplicate-group reload when running Select Smart Resolve to avoid the browser instability introduced by cache-key reuse, while keeping sync no-refresh behavior unchanged. Made-with: Cursor --------- Co-authored-by: KennyG <kennyg@kennyg.com>
This commit is contained in:
107
plugins/SmartResolve/README.md
Normal file
107
plugins/SmartResolve/README.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Smart Resolve
|
||||
|
||||
UI plugin for Stash’s **Scene Duplicate Checker** (`Settings → Tools → Scene Duplicate Checker`).
|
||||
|
||||
## What it does
|
||||
|
||||
1. **Smart Resolve analysis/tagging** — Adds `Select Smart Resolve` to Stash’s native **Select Options** menu and annotates duplicate rows with reason text plus sync recommendations.
|
||||
2. **Row tools** — Adds per-row **Sync data** / **Sync rec.** buttons and stash ID badges in the scene details icon row.
|
||||
3. **Safe selection** — Auto-selects delete candidates only when rules say it is safe; unresolved/sync-required sets are left unchecked.
|
||||
|
||||
## Smart Resolve rule flow
|
||||
|
||||
*Goal:* Identify a single candidate keeper regardless of initial candidate scene count.
|
||||
|
||||
Rules run per each duplicate group on the page.
|
||||
|
||||
1. **Determine a primary keep candidate**
|
||||
- Process each rule in order.
|
||||
- Any scene which is deficient of the identified criteria level is eliminated from being the potential keeper and any remaining tied survivors are evaluated as the next sub-step.
|
||||
- When a sub-step leaves only one file as the potential keeper, move to step 2.
|
||||
- For any step where the value is not known or null, assume 0 for this phase
|
||||
- Store step result as selection reason.
|
||||
- Rules 1-13 are toggleable via plugin settings; rule 14 remains always-on, deterministic fallback.
|
||||
1) Prefer the scene with the greatest total pixel resolution (product of x and y, 1920x1080=2073600)
|
||||
- Apply a 1% pixel-area tolerance: candidates within 1% of the top area are treated as tied for this step.
|
||||
2) Prefer the scene with the greatest framerate
|
||||
3) Prefer the scene with the better codec (AV1 > H265 > H264 > Others)
|
||||
3b) Prefer candidates whose primary file path includes `upgrade` (toggleable)
|
||||
4) Prefer the scene with greater duration
|
||||
5) Prefer the scene with smaller size (unless file name includes `upgrade`)
|
||||
- Files with the word `upgrade` cannot be eliminated from candidacy as per having a larger file size.
|
||||
- Apply file-size tolerance when eliminating larger files: allow `max(1MB, 1% of min file size)` above the smallest file size.
|
||||
- In a multi-file scenario, files larger than `min + tolerance` may be eliminated (unless `upgrade` token applies).
|
||||
6) Prefer the scene with an older scene date (2 day tollerance)
|
||||
7) Prefer the scene with more groups
|
||||
8) Prefer the scene with stashID
|
||||
9) Prefer the scene with more performers
|
||||
10) Prefer the scene with markers
|
||||
11) Prefer the scene with more tags
|
||||
12) Prefer the scene with LESS associated files
|
||||
13) Prefer the scene with more non-null metadata elements (title, studio_code, urls, date, director, galleries, studio, performers, groups, tags, details)
|
||||
14) Final deterministic tiebreaker, the scene with a lower scene_id
|
||||
2. **Evaluate each non-keeper iteratively to prevent data loss**
|
||||
Process each scene and each rule to determine status:
|
||||
```
|
||||
markForDeletion: (boolean)
|
||||
markParentForSync: (boolean)
|
||||
exceptions: ([array](string))
|
||||
```
|
||||
Exception rules (any of these will trigger markForDeletion=false)
|
||||
- Protection rules a-f are toggleable via plugin settings.
|
||||
a) Protect O-count: O-count scenes should never be marked for deletion
|
||||
b) Protect Group associations: Only mark for deletion if the same or more group information is attached to the primary candidate (i.e. k.groups{id,index} contains all (n.groups{id,index})
|
||||
- null allows a match with only other null
|
||||
- null does not match a non-null
|
||||
- Scenes may be members of multiple groups. A primary source (k) must replicate all non-keeper (n) sources to not have an exception
|
||||
- Miss-matched scenes should be flagged according to reason message and marked for manual resolution
|
||||
c) Protect performer mismatch by ID (markParentForSync=true)
|
||||
- If non-keeper has any performer ID not present on keeper, trigger exception
|
||||
- Only identical performer ID sets avoid this exception
|
||||
d) Protect tag loss >1 for non-stash'd scenes (markParentForSync=true)
|
||||
e) Protect older dates
|
||||
if K.date > n.date (markParentForSync=true)
|
||||
if K.date == null && n.date != null (markParentForSync=true)
|
||||
if K.date != null && n.date == null (no action)
|
||||
f) Protect scenes tagged with "Ignore:Smart Resolve" (case-insensitive); never auto-delete these scenes
|
||||
|
||||
3. **Generate decision reason (`reasonAgainst`)**
|
||||
- Generate message from decision code
|
||||
- If exception code array is not empty, expand message. Block marking, recommend sync.
|
||||
- row button becomes **Sync rec.**
|
||||
- unresolved count increments
|
||||
- smart auto-selection skips that set
|
||||
|
||||
Notes:
|
||||
A primary file is determined, then we determine if non-primary needs to be protected from loss. The primary file is never changed mid-analysis. Exceptions do not change the primary file, only protect loss.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Install the plugin folder under your Stash plugins directory and enable it in **Settings → Plugins**.
|
||||
2. Open the **Scene Duplicate Checker**.
|
||||
3. Open **Select Options** and click **Select Smart Resolve**.
|
||||
4. Review unresolved/sync-rec rows (`Sync rec.` buttons and unresolved counter).
|
||||
5. Use row **Sync data** where recommended, then re-run Smart Resolve.
|
||||
6. Use Stash’s native Delete/Merge actions on remaining selected rows.
|
||||
|
||||
Optional setting: **After Sync, mark source scenes for deletion** — default for the “check sources after sync” checkbox in the Sync modal.
|
||||
|
||||
## Settings UI
|
||||
|
||||

|
||||
|
||||
## Limits
|
||||
|
||||
- Rules evaluate **only visible duplicate groups on the current page**. Pagination and page size can change outcomes seen in a single run.
|
||||
- Any missing/unknown criterion values are normalized to `0` during candidate selection (line 20 behavior). This preserves determinism but can favor records with more populated metadata fields.
|
||||
- Step 1 is a strict elimination pipeline. Once a scene is eliminated by an earlier criterion, later criteria do not reintroduce it.
|
||||
- The `upgrade` filename exception is a string heuristic. It is not case-sensitive. This step is not expected to be a major factor, but creates an easy way to work around the plugin.
|
||||
- Group protection depends on `{group.id, scene_index}` containment semantics; mismatches are expected to force manual/sync resolution.
|
||||
- Date protection assumes parseable comparable date values. Stash provides some date parse semantics. However all null dates should be assumed to be the last date of any incomplete window. (i.e. 2020 -> 2020-12-31, 2020-06 -> 2020-06-30) Null, Invalid, or unparseable values should be treated as 2999-12-31 by implementation.
|
||||
- `markParentForSync` and `exceptions` are structured outputs in this spec, but UI sync-rec indicators must be wired to those flags in implementation.
|
||||
- This flow is designed for deterministic outcomes, not probabilistic ranking; tie-break behavior is intentionally resolved by lower `scene_id`.
|
||||
- Sync actions are `sceneUpdate`-based (metadata transfer), not full `sceneMerge`; scene IDs remain separate after sync.
|
||||
|
||||
## Repository
|
||||
|
||||
Maintained in [Stash-KennyG/CommunityScripts](https://github.com/Stash-KennyG/CommunityScripts).
|
||||
387
plugins/SmartResolve/SmartResolve.css
Normal file
387
plugins/SmartResolve/SmartResolve.css
Normal file
@@ -0,0 +1,387 @@
|
||||
#duplicate-resolver-toolbar {
|
||||
margin: 0.75rem 0 1rem;
|
||||
padding: 0.75rem 1rem;
|
||||
background: var(--bs-secondary-bg, rgba(0, 0, 0, 0.15));
|
||||
border-radius: 0.25rem;
|
||||
border: 1px solid var(--bs-border-color, rgba(255, 255, 255, 0.12));
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-toolbar-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-btn-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-btn-row:empty {
|
||||
display: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-core-actions {
|
||||
display: inline-flex;
|
||||
gap: 0.35rem;
|
||||
align-items: center;
|
||||
margin-left: 0.4rem;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-processing-indicator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
color: var(--bs-body-color, #d7dbe0);
|
||||
font-size: 0.75rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-processing-spinner {
|
||||
width: 0.85rem;
|
||||
height: 0.85rem;
|
||||
border: 2px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: var(--bs-info, #7cc7ff);
|
||||
border-radius: 50%;
|
||||
animation: dr-spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-processing-bar {
|
||||
width: 80px;
|
||||
height: 8px;
|
||||
overflow: hidden;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-processing-bar-fill {
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(124, 199, 255, 0.2) 0%,
|
||||
rgba(124, 199, 255, 0.95) 50%,
|
||||
rgba(124, 199, 255, 0.2) 100%
|
||||
);
|
||||
animation: dr-progress-slide 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes dr-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dr-progress-slide {
|
||||
0% {
|
||||
transform: translateX(-40px);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(80px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep duplicate rows compact and prevent action/icon wrapping. */
|
||||
#scene-duplicate-checker table.duplicate-checker-table td.scene-details .btn-group {
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker table.duplicate-checker-table td.scene-details,
|
||||
#scene-duplicate-checker table.duplicate-checker-table td:last-child {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-inline-reason {
|
||||
font-size: calc(1em + 2pt);
|
||||
color: var(--bs-warning, #ffd54a);
|
||||
}
|
||||
|
||||
#scene-duplicate-checker table.duplicate-checker-table tbody tr.dr-unresolved-highlight {
|
||||
background: rgba(255, 0, 0, 0.08) !important;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-stashid-btn {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-stashid-btn.dr-stashid-btn-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#scene-duplicate-checker .dr-stashid-box-icon {
|
||||
width: 0.95em;
|
||||
height: 0.95em;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-drawer {
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-drawer-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0.15rem 0 !important;
|
||||
font-size: 0.875rem;
|
||||
text-decoration: none;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-drawer-toggle:hover,
|
||||
#duplicate-resolver-toolbar .dr-drawer-toggle:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-drawer-panel {
|
||||
margin-top: 0.5rem;
|
||||
padding-top: 0.5rem;
|
||||
border-top: 1px solid var(--bs-border-color, rgba(255, 255, 255, 0.12));
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-drawer-toolbar {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-preview {
|
||||
font-size: 0.875rem;
|
||||
max-height: 14rem;
|
||||
overflow: auto;
|
||||
white-space: pre-wrap;
|
||||
margin: 0;
|
||||
padding: 0.5rem;
|
||||
background: var(--bs-body-bg, #1a1a1a);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-toolbar .dr-preview .dr-match-link {
|
||||
color: var(--bs-info, #7cc7ff);
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.duplicate-resolver-sync-btn {
|
||||
margin-left: 0.35rem !important;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
z-index: 1050;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-modal {
|
||||
background: var(--bs-secondary-bg, #30404d);
|
||||
color: var(--bs-body-color, #eee);
|
||||
border: 1px solid var(--bs-border-color, rgba(255, 255, 255, 0.18));
|
||||
border-radius: 0.35rem;
|
||||
max-width: 60rem;
|
||||
width: 100%;
|
||||
max-height: 90vh;
|
||||
overflow: auto;
|
||||
padding: 1rem 1.25rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay h3 {
|
||||
margin-top: 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-modal-header {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 0.45rem;
|
||||
margin: -1rem -1.25rem 0.75rem;
|
||||
padding: 0.7rem 1rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-modal-options {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-modal-options label {
|
||||
display: block;
|
||||
margin: 0.25rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-title {
|
||||
display: block;
|
||||
margin: 0.1rem 0 0.35rem;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-opt-hint {
|
||||
font-size: 0.82rem;
|
||||
opacity: 0.9;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-sync-compare {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.75rem;
|
||||
margin: 0.75rem 0 1rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-sync-compare .dr-col {
|
||||
background: var(--bs-secondary-bg, rgba(255, 255, 255, 0.03));
|
||||
border: 1px solid var(--bs-border-color, rgba(255, 255, 255, 0.08));
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.5rem 0.6rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-sync-compare h4 {
|
||||
margin: 0 0 0.4rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-sync-compare p {
|
||||
margin: 0;
|
||||
font-size: 0.82rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-row {
|
||||
border-top: 1px solid var(--bs-border-color, rgba(255, 255, 255, 0.08));
|
||||
padding-top: 0.55rem;
|
||||
margin-top: 0.55rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-desc {
|
||||
font-size: 0.78rem;
|
||||
opacity: 0.85;
|
||||
margin: 0.15rem 0 0.35rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.6rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-col {
|
||||
background: transparent;
|
||||
border-radius: 0.18rem;
|
||||
padding: 0.35rem 0.45rem;
|
||||
min-height: 3rem;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-list-control {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-list-control .input-group + .input-group {
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-chip-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.28rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-chip {
|
||||
max-width: 100%;
|
||||
padding: 0.10rem 0.35rem;
|
||||
border-radius: 0.14rem;
|
||||
line-height: 1.15;
|
||||
font-size: 0.84rem;
|
||||
font-weight: 400;
|
||||
border: 0;
|
||||
background-color: #b9c4cd;
|
||||
color: #21313f;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-col .input-group {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-col .input-group .dr-list-control {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-col .form-control,
|
||||
#duplicate-resolver-modal-overlay .dr-field-col .scene-description {
|
||||
min-height: calc(1.5em + 0.75rem + 2px);
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-empty {
|
||||
font-size: 0.74rem;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-modal-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
justify-content: flex-end;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-field-col .input-group-prepend .btn {
|
||||
min-width: 2.2rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-cover-value {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-cover-frame {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 0.18rem;
|
||||
padding: 0.35rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-cover-thumb {
|
||||
display: block;
|
||||
max-height: 180px;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
object-fit: contain;
|
||||
border-radius: 0.12rem;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-cover-caption {
|
||||
font-size: 0.72rem;
|
||||
opacity: 0.8;
|
||||
margin-top: 0.3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#duplicate-resolver-modal-overlay .dr-cover-placeholder {
|
||||
font-size: 0.78rem;
|
||||
opacity: 0.75;
|
||||
padding: 0.35rem 0.25rem;
|
||||
margin-bottom: 0.25rem;
|
||||
border: 1px dashed rgba(255, 255, 255, 0.2);
|
||||
border-radius: 0.12rem;
|
||||
text-align: center;
|
||||
}
|
||||
2874
plugins/SmartResolve/SmartResolve.js
Normal file
2874
plugins/SmartResolve/SmartResolve.js
Normal file
File diff suppressed because it is too large
Load Diff
96
plugins/SmartResolve/SmartResolve.yml
Normal file
96
plugins/SmartResolve/SmartResolve.yml
Normal file
@@ -0,0 +1,96 @@
|
||||
name: Smart Resolver
|
||||
description: Scene Duplicate Checker helper with Smart Select and mergeless Sync Data. Rules are processed in order to determine a primary keep candidate. Protection rules are then processed to determine if the non-primary scene should be marked for deletion.
|
||||
version: 1.0.02
|
||||
url: https://github.com/Stash-KennyG/CommunityScripts/tree/main/plugins/DuplicateResolver
|
||||
ui:
|
||||
javascript:
|
||||
- SmartResolve.js
|
||||
css:
|
||||
- SmartResolve.css
|
||||
settings:
|
||||
autoCheckAfterSync:
|
||||
displayName: After Sync, mark source scenes for deletion
|
||||
description: >-
|
||||
Successfully synced source scenes are marked by default after sync.
|
||||
type: BOOLEAN
|
||||
ignoreRule01TotalPixels:
|
||||
displayName: Ignore 01 - Most Total pixels
|
||||
description: When enabled, will not eliminate candidate with lower total pixels than the highest width*height (1% tolerance).
|
||||
type: BOOLEAN
|
||||
ignoreRule02Framerate:
|
||||
displayName: Ignore 02 - Highest Framerate
|
||||
description: When enabled, will not eliminate candidate with lower framerate than the highest file framerate.
|
||||
type: BOOLEAN
|
||||
ignoreRule03Codec:
|
||||
displayName: Ignore 03 - Codec tier
|
||||
description: When enabled, will not eliminate candidate with lower codec quality tier (AV1 > H265 > H264 > others).
|
||||
type: BOOLEAN
|
||||
ignoreRule04Duration:
|
||||
displayName: Ignore 04 - Longest Duration
|
||||
description: When enabled, will not eliminate candidate with shorter duration than the longest duration (rounded to nearest second).
|
||||
type: BOOLEAN
|
||||
ignoreRule05SmallerSize:
|
||||
displayName: Ignore 05 - Smaller file size
|
||||
description: When enabled, will not eliminate candidate with larger file size than the smallest (tollerance max(1MB or 1%)).
|
||||
type: BOOLEAN
|
||||
ignoreRule05bUpgradeToken:
|
||||
displayName: Ignore 05b - Upgrade token preference
|
||||
description: When enabled, will not eliminate candidate with primary file path containing "upgrade".
|
||||
type: BOOLEAN
|
||||
ignoreRule06OlderDate:
|
||||
displayName: Ignore 06 - Older date
|
||||
description: When enabled, will not eliminate candidate with later scene date than the oldest scene date (null is latest).
|
||||
type: BOOLEAN
|
||||
ignoreRule07MoreGroups:
|
||||
displayName: Ignore 07 - More groups
|
||||
description: When enabled, will not eliminate candidate with fewer group associations than the most groups.
|
||||
type: BOOLEAN
|
||||
ignoreRule08HasStashId:
|
||||
displayName: Ignore 08 - Has stash ID
|
||||
description: When enabled, will not eliminate candidate with fewer stash IDs than the most stash IDs.
|
||||
type: BOOLEAN
|
||||
ignoreRule09MorePerformers:
|
||||
displayName: Ignore 09 - More performers
|
||||
description: When enabled, will not eliminate candidate with fewer performer associations than the most performer associations.
|
||||
type: BOOLEAN
|
||||
ignoreRule10MoreMarkers:
|
||||
displayName: Ignore 10 - More markers
|
||||
description: When enabled, will not eliminate candidate with fewer scene markers than the most scene markers.
|
||||
type: BOOLEAN
|
||||
ignoreRule11MoreTags:
|
||||
displayName: Ignore 11 - More tags
|
||||
description: When enabled, will not eliminate candidate with fewer tags than the most tags.
|
||||
type: BOOLEAN
|
||||
ignoreRule12LessAssociatedFiles:
|
||||
displayName: Ignore 12 - Less associated files
|
||||
description: When enabled, will not eliminate candidate with more associated file entries than the least associated file entries.
|
||||
type: BOOLEAN
|
||||
ignoreRule13MoreMetadataCardinality:
|
||||
displayName: Ignore 13 - Metadata cardinality
|
||||
description: When enabled, will not eliminate candidate with fewer total populated metadata elements than the most.
|
||||
type: BOOLEAN
|
||||
unprotectAOCount:
|
||||
displayName: Unprotect O-count
|
||||
description: When enabled, will permit marking for deletion scenes with O-count > 0.
|
||||
type: BOOLEAN
|
||||
unprotectBGroupAssociation:
|
||||
|
||||
displayName: Unprotect Group association containment
|
||||
description: When enabled, will permit marking for deletion scenes with group associations not present on the primary candidate.
|
||||
type: BOOLEAN
|
||||
unprotectCPerformerMismatch:
|
||||
displayName: Unprotect Performer mismatch
|
||||
description: When enabled, will permit marking for deletion scenes with performer associations not present on the primary candidate.
|
||||
type: BOOLEAN
|
||||
unprotectDTagLossGt1NonStashed:
|
||||
displayName: Unprotect Tag loss >1 (non-stashed)
|
||||
description: When enabled, will permit marking unstashed scenes for deletion with more than 1 less tags than the primary candidate.
|
||||
type: BOOLEAN
|
||||
unprotectEOlderDate:
|
||||
displayName: Unprotect Older date
|
||||
description: When enabled, will permit marking for deletion scenes with an older date than the primary candidate.
|
||||
type: BOOLEAN
|
||||
unprotectFIgnoreSmartResolveTag:
|
||||
displayName: Unprotect Ignore:Smart Resolve tag
|
||||
description: When enabled, will permit marking for deletion scenes tagged "Ignore:Smart Resolve".
|
||||
type: BOOLEAN
|
||||
BIN
plugins/SmartResolve/about.png
Normal file
BIN
plugins/SmartResolve/about.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 222 KiB |
Reference in New Issue
Block a user