Updates to plugins RenameFile and DupFileManager

RenameFile Plugin Changes
### 0.5.6
- Fixed bug with studio getting the studio ID instead of the name of the studio in rename process.
- Improved performance by having code get all required scene details in one call to stash.
- To remove UI clutter, move rarely used options (performerAppendEnable, studioAppendEnable, tagAppendEnable, & fileRenameViaMove) to renamefile_settings.py
- Change options (performerAppendEnable, studioAppendEnable, tagAppendEnable) to default to True (enabled)

DupFileManager Plugin Changes
### 0.2.2
- Added dropdown menu logic to Advance Menu and reports.
- Added Graylist deletion option to Advance Menu.
- Report option to clear all flags from report.
- Report option to clear all (_DuplicateMarkForDeletion_?) tag from all scenes.
- Report option to delete from Stash DB all scenes with missing files in file system.
- Added popup tag list to report which list all tags associated with scene.
- Added popup performer list to report which list all performers associated with scene.
- Added popup gallery list to report which list all galleries associated with scene.
- Added popup group list to report which list all groups associated with scene.
- After merging tags in report, the report gets updated with the merged scene metadata.
- Added graylist deletion option to [**Advance Duplicate File Deletion Menu**].
- Added pinklist option to Settings->Plugins->Plugins and to [**Advance Duplicate File Deletion Menu**]
  - The pinklist is only used with the [**Advance Duplicate File Deletion Menu**], and it's **NOT** used in the primary process to selected candidates for deletion.
- Advance Menu now works with non-tagged scenes that are in the current report.
This commit is contained in:
David Maisonave
2024-11-26 09:29:26 -05:00
parent 1c8c0c6db6
commit e1f3335db8
11 changed files with 464 additions and 160 deletions

View File

@@ -29,8 +29,47 @@ table, th, td {border:1px solid black;}
color:red;
}
html.wait, html.wait * { cursor: wait !important; }
/* The dropdown container */
.dropdown {
float: left;
overflow: hidden;
}
/******** Dropdown button *********/
.dropdown .dropbtn {
font-size: 14px;
border: none;
outline: none;
color: white;
padding: 6px 10px;
background-color: transparent;
font-family: inherit; /* Important for vertical align on mobile phones */
margin: 0; /* Important for vertical align on mobile phones */
}
/* Dropdown content (hidden by default) */
.dropdown-content {
display: none;
position: absolute;
background-color: inherit;
min-width: 80px;
box-shadow: 0px 4px 12px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
float: none;
color: black;
padding: 6px 10px;
text-decoration: none;
display: block;
text-align: left;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://www.axter.com/js/jquery-3.7.1.min.js"></script>
<script>
var apiKey = ""; // For Stash installations with a password setup, populate this variable with the apiKey found in Stash->Settings->Security->[API Key]; ----- Or pass in the apiKey at the URL command line. Example: advance_options.html?apiKey=12345G4igiJdgssdgiwqInh5cCI6IkprewJ9hgdsfhgfdhd&GQL=http://localhost:9999/graphql
var GraphQl_URL = "http://localhost:9999/graphql";// For Stash installations with non-standard ports or URL's, populate this variable with actual URL; ----- Or pass in the URL at the command line using GQL param. Example: advance_options.html?GQL=http://localhost:9900/graphql
@@ -41,11 +80,15 @@ if (urlParams.get('GQL') != null && urlParams.get('GQL') !== "")
GraphQl_URL = urlParams.get('GQL');
console.log(urlParams);
console.log("GQL = " + GraphQl_URL);
console.log("apiKey = " + apiKey);
function RunPluginDupFileManager(Mode, Param = 0, Async = false) {
function RunPluginDupFileManager(Mode, Param = 0, Async = false, TagOnlyScenes = false) {
$('html').addClass('wait');
$("body").css("cursor", "progress");
if (TagOnlyScenes)
Param += ":TagOnlyScenes";
console.log("GraphQl_URL = " + GraphQl_URL + "; Mode = " + Mode + "; Param = " + Param);
//if ($("#InPathCheck").prop('checked'))
if (apiKey !== "")
$.ajaxSetup({beforeSend: function(xhr) {xhr.setRequestHeader('apiKey', apiKey);}});
$.ajax({method: "POST", url: GraphQl_URL, contentType: "application/json", dataType: "text", cache: Async, async: Async,
@@ -63,12 +106,15 @@ function RunPluginDupFileManager(Mode, Param = 0, Async = false) {
console.log("Setting default cursor");
}
$(document).ready(function(){
$("button").click(function(){
const AddedWarn = "? This will delete the files, and remove them from stash.";
console.log(this.id);
var blackliststr = "";
var comparestr = "less than ";
if (this.id.includes("Blacklist")) blackliststr = "in blacklist ";
if (this.id.includes("Graylist")) blackliststr = "in graylist ";
if (this.id.includes("Pinklist")) blackliststr = "in pinklist ";
if (this.id.includes("Greater")) comparestr = "greater than ";
else if (this.id.includes("Eq")) comparestr = "equal to ";
@@ -94,27 +140,27 @@ $(document).ready(function(){
else if (this.id === "pathToDelete" || this.id === "pathToDeleteBlacklist")
{
if (confirm("Are you sure you want to delete tag scenes " + blackliststr + "having _DuplicateMarkForDeletion tags, and in path " + $("#pathToDeleteText").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#pathToDeleteText").val());
RunPluginDupFileManager(this.id, $("#pathToDeleteText").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "sizeToDeleteLess" || this.id === "sizeToDeleteGreater" || this.id === "sizeToDeleteBlacklistLess" || this.id === "sizeToDeleteBlacklistGreater")
{
if (confirm("Are you sure you want to delete duplicate tag scenes " + blackliststr + "having file size " + comparestr + $("#sizeToDelete").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#sizeToDelete").val());
RunPluginDupFileManager(this.id, $("#sizeToDelete").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "durationToDeleteLess" || this.id === "durationToDeleteGreater" || this.id === "durationToDeleteBlacklistLess" || this.id === "durationToDeleteBlacklistGreater")
{
if (confirm("Are you sure you want to delete duplicate tag scenes " + blackliststr + "having file duration " + comparestr + $("#durationToDelete").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#durationToDelete").val());
RunPluginDupFileManager(this.id, $("#durationToDelete").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "commonResToDeleteLess" || this.id === "commonResToDeleteEq" || this.id === "commonResToDeleteGreater" || this.id === "commonResToDeleteBlacklistLess" || this.id === "commonResToDeleteBlacklistEq" || this.id === "commonResToDeleteBlacklistGreater")
{
if (confirm("Are you sure you want to delete duplicate tag scenes " + blackliststr + "having resolution " + comparestr + $("#commonResToDelete").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#commonResToDelete").val());
RunPluginDupFileManager(this.id, $("#commonResToDelete").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "resolutionToDeleteLess" || this.id === "resolutionToDeleteEq" || this.id === "resolutionToDeleteGreater" || this.id === "resolutionToDeleteBlacklistLess" || this.id === "resolutionToDeleteBlacklistEq" || this.id === "resolutionToDeleteBlacklistGreater")
{
if (confirm("Are you sure you want to delete duplicate tag scenes " + blackliststr + "having resolution " + comparestr + $("#resolutionToDelete").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#resolutionToDelete").val());
RunPluginDupFileManager(this.id, $("#resolutionToDelete").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "ratingToDeleteLess" || this.id === "ratingToDeleteEq" || this.id === "ratingToDeleteGreater" || this.id === "ratingToDeleteBlacklistLess" || this.id === "ratingToDeleteBlacklistEq" || this.id === "ratingToDeleteBlacklistGreater")
{
@@ -126,33 +172,37 @@ $(document).ready(function(){
else
result = confirm("Are you sure you want to delete duplicate tag scenes " + blackliststr + "having rating " + comparestr + $("#ratingToDelete").val() + AddedWarn);
if (result)
RunPluginDupFileManager(this.id, $("#ratingToDelete").val());
RunPluginDupFileManager(this.id, $("#ratingToDelete").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "tagToDelete" || this.id === "tagToDeleteBlacklist")
{
if (confirm("Are you sure you want to delete tag scenes " + blackliststr + "having _DuplicateMarkForDeletion tags, and having tag " + $("#tagToDeleteText").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#tagToDeleteText").val());
RunPluginDupFileManager(this.id, $("#tagToDeleteText").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "titleToDelete" || this.id === "titleToDeleteBlacklist")
{
if (confirm("Are you sure you want to delete tag scenes " + blackliststr + "having _DuplicateMarkForDeletion tags, and having title containing " + $("#titleToDeleteText").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#titleToDeleteText").val());
RunPluginDupFileManager(this.id, $("#titleToDeleteText").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "pathStrToDelete" || this.id === "pathStrToDeleteBlacklist")
{
if (confirm("Are you sure you want to delete tag scenes " + blackliststr + "having _DuplicateMarkForDeletion tags, and having path containing " + $("#pathStrToDeleteText").val() + AddedWarn))
RunPluginDupFileManager(this.id, $("#pathStrToDeleteText").val());
RunPluginDupFileManager(this.id, $("#pathStrToDeleteText").val(), true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "fileNotExistToDelete" || this.id === "fileNotExistToDeleteBlacklist")
{
if (confirm("Are you sure you want to delete tag scenes " + blackliststr + "having _DuplicateMarkForDeletion tags, and that do NOT exist in the file system?"))
RunPluginDupFileManager(this.id, true);
RunPluginDupFileManager(this.id, true, true, $("#DupTagOnlyCheck").prop('checked'));
}
else if (this.id === "applyCombo" || this.id === "applyComboBlacklist")
else if (this.id === "applyCombo" || this.id === "applyCombo_" || this.id === "applyComboBlacklist" || this.id === "applyComboGraylist" || this.id === "applyComboPinklist")
{
var Blacklist = "";
if (this.id === "applyComboBlacklist")
Blacklist = "Blacklist";
else if (this.id === "applyComboGraylist")
Blacklist = "Graylist";
else if (this.id === "applyComboPinklist")
Blacklist = "Pinklist";
var Param = "{";
if ($("#InPathCheck").prop('checked'))
Param += "\"" + "pathToDelete" + Blacklist + "\":\"" + $("#pathToDeleteText").val().replace("\\", "\\\\") + "\", ";
@@ -181,6 +231,8 @@ $(document).ready(function(){
Param += "\"" + "pathStrToDelete" + Blacklist + "\":\"" + $("#pathStrToDeleteText").val().replace("\\", "\\\\") + "\", ";
if ($("#fileNotExistCheck").prop('checked'))
Param += "\"" + "fileNotExistToDelete" + Blacklist + "\":\"true\", ";
if ($("#DupTagOnlyCheck_MultiOption").prop('checked'))
Param += "\"" + "TagOnlyScenes" + Blacklist + "\":\"true\", ";
Param += '}';
Param = Param.replace(', }', '}');
if (Param === "{}")
@@ -190,7 +242,7 @@ $(document).ready(function(){
}
console.log(Param);
if (confirm("Are you sure you want to delete tag scenes " + blackliststr + "having _DuplicateMarkForDeletion tags, and having the selected options" + AddedWarn + "\nSelected options:\n" + Param))
RunPluginDupFileManager(this.id, Param);
RunPluginDupFileManager(this.id, Param, true);
}
});
});
@@ -201,16 +253,50 @@ function DeleteDupInPath(){
</head>
<body>
<center><table style="color:darkgreen;background-color:powderblue;">
<tr><th>DupFileManager Advance <b style="color:red;">_DuplicateMarkForDeletion_?</b> Tagged Files Menu</th><th>Apply Multiple Options</th></tr>
<tr><th><div><b style="color:red;"><i>DupFileManager</i></b></div>Advance Duplicate File Deletion Menu</th><th>Apply Multiple Options</th></tr>
<tr>
<td><center>
<button type="button" id="tag_duplicates_task" value="-1" title="Create new report which tags duplicates with tag name _DuplicateMarkForDeletion using user settings for [Match Duplicate Distance].">Create Duplicate Report with Tagging</button>
<button type="button" id="viewreport" title="View duplicate file report.">View Dup Report</button>
</center></td>
<td>
<button type="button" id="applyCombo" title="Apply selected multiple options to delete scenes.">Delete</button>
<button type="button" id="applyComboBlacklist" title="Apply selected multiple options to delete scenes in blacklist.">Delete-Blacklist</button>
<table style="border-collapse: collapse; border: none;"><tr style="border: none;">
<tr><th colspan="3" style="font-size: 12px;border: none;">Create report overriding user [Match Duplicate Distance] and [significantTimeDiff] settings</th></tr>
<td style="border: none;"><div class="dropdown">
<button type="button" id="create_duplicate_report_task" value="-1" title="Create new report WITHOUT tags using user settings for [Match Duplicate Distance].">Create Duplicate Report <i class="fa fa-caret-down"></i></button>
<div class="dropdown-content">
<div><button type="button" id="create_duplicate_report_task0a" value="0" title="Create report using [Match Duplicate Distance]=0 (Exact Match). NO tagging.">Create Duplicate Report [Exact Match]</button></div>
<div><button type="button" id="create_duplicate_report_task1a" value="1" title="Create report using [Match Duplicate Distance]=1 (High Match). NO tagging.">Create Duplicate Report [High Match]</button></div>
<div><button type="button" id="create_duplicate_report_task2a" value="2" title="Create report using [Match Duplicate Distance]=2 (Medium Match). NO tagging.">Create Duplicate Report [Medium Match]</button></div>
<div><button type="button" id="create_duplicate_report_task3a" value="3" title="Create report using [Match Duplicate Distance]=3 (Low Match). NO tagging.">Create Duplicate Report [Low Match]</button></div>
<div style="height:2px;width:220px;border-width:0;color:gray;background-color:gray;">_</div>
<div><button type="button" id="tag_duplicates_task" value="-1" title="Create new report which tags duplicates with tag name _DuplicateMarkForDeletion using user settings for [Match Duplicate Distance].">Create Duplicate Report with Tagging (With Default Match Setting)</button></div>
<div><button type="button" id="tag_duplicates_task0a" value="0" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_0 and using [Match Duplicate Distance]=0 (Exact Match).">Create Duplicate Tagging Report [Exact Match]</button></div>
<div><button type="button" id="tag_duplicates_task1a" value="1" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_1 and using [Match Duplicate Distance]=1 (High Match).">Create Duplicate Tagging Report [High Match]</button></div>
<div><button type="button" id="tag_duplicates_task2a" value="2" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_2 and using [Match Duplicate Distance]=2 (Medium Match).">Create Duplicate Tagging Report [Medium Match]</button></div>
<div><button type="button" id="tag_duplicates_task3a" value="3" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_3 and using [Match Duplicate Distance]=3 (Low Match).">Create Duplicate Tagging Report [Low Match]</button></div>
</div>
</div></td>
<td style="border: none;padding: 0 15px;">
<label for="significantTimeDiff" title="Significant time difference setting, where 1 equals 100% and (.9) equals 90%.">Time Difference%:</label>
<input type="number" min="0.25" max="1.00" step="0.01" id="significantTimeDiff" name="significantTimeDiff" title="Significant time difference setting, where 1 equals 100% and (.9) equals 90%." value="0.90">
</td>
<td style="border: none;padding: 0 15px;">
<button type="button" id="viewreport" title="View duplicate file report.">View Dup Report</button>
</td>
</tr></table>
</td>
<td>
<div class="dropdown">
<center>Multi-Options: <button id="applyCombo" title="Apply selected multiple options to delete scenes.">Delete <i class="fa fa-caret-down"></i></button></center>
<div class="dropdown-content">
<div><button type="button" id="applyCombo_" title="Apply selected multiple options to delete scenes.">Delete All Candidates</button></div>
<div><button type="button" id="applyComboBlacklist" title="Apply selected multiple options to delete scenes in blacklist.">Delete-Blacklist</button></div>
<div><button type="button" id="applyComboGraylist" title="Apply selected multiple options to delete scenes in graylist.">Delete-Graylist</button></div>
<div><button type="button" id="applyComboPinklist" title="Apply selected multiple options to delete scenes in pinklist.">Delete-Pinklist</button></div>
</div>
</div>
</td>
</tr>
<tr>
<td><label title="When enabled, operations only apply to scenes which have the special tag _DuplicateMarkForDeletion_?" for="DupTagOnlyCheck">Apply action only to scenes with <b>_DuplicateMarkForDeletion_?</b> tag:</label><input title="When enabled, operations only apply to scenes which have the special tag _DuplicateMarkForDeletion_?" type="checkbox" id="DupTagOnlyCheck" name="DupTagOnlyCheck" value="true"></td>
<td><label title="When enabled, Multi-Options operations only apply to scenes which have the special tag _DuplicateMarkForDeletion_?" for="DupTagOnlyCheck_MultiOption">Dup Tag:</label><input title="When enabled, Multi-Options operations only apply to scenes which have the special tag _DuplicateMarkForDeletion_?" type="checkbox" id="DupTagOnlyCheck_MultiOption" name="DupTagOnlyCheck" value="true"></td>
</tr>
<tr>
<td><form id="pathToDeleteForm" action="javascript:DeleteDupInPath();" target="_self">
@@ -1797,50 +1883,6 @@ function DeleteDupInPath(){
<option value="Greater">Greater</option>
</select>
</td>
</tr>
</table></center>
<div id="div1"></div>
<br>
<center><table style="color:darkgreen;background-color:powderblue;">
<tr><th colspan="2">Create report with different <b style="color:red;">[Match Duplicate Distance]</b> options
<br><div style="font-size: 12px;">Overrides user [Match Duplicate Distance] and [significantTimeDiff] settings</div>
<form id="significantTimeDiffForm" action="javascript:DeleteDupInPath();" target="_self">
<label for="significantTimeDiff" title="Significant time difference setting, where 1 equals 100% and (.9) equals 90%.">Time Difference%:</label>
<input type="number" min="0.25" max="1.00" step="0.01" id="significantTimeDiff" name="significantTimeDiff" title="Significant time difference setting, where 1 equals 100% and (.9) equals 90%." value="0.90">
</form>
</th></tr>
<tr>
<td><table style="color:darkgreen;background-color:powderblue;">
<tr><th title="Create report with tagging (_DuplicateMarkForDeletion_)">Create Report with Tagging</th></tr>
<tr><td><center>
<button type="button" id="tag_duplicates_task0" value="0" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_0 and using [Match Duplicate Distance]=0 (Exact Match).">Create Duplicate Tagging Report [Exact Match]</button>
</center></td></tr>
<tr><td><center>
<button type="button" id="tag_duplicates_task1" value="1" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_1 and using [Match Duplicate Distance]=1 (High Match).">Create Duplicate Tagging Report [High Match]</button>
</center></td></tr>
<tr><td><center>
<button type="button" id="tag_duplicates_task2" value="2" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_2 and using [Match Duplicate Distance]=2 (Medium Match).">Create Duplicate Tagging Report [Medium Match]</button>
</center></td></tr>
<tr><td><center>
<button type="button" id="tag_duplicates_task3" value="3" title="Create report which tags duplicates with tag name _DuplicateMarkForDeletion_3 and using [Match Duplicate Distance]=3 (Low Match).">Create Duplicate Tagging Report [Low Match]</button>
</center></td></tr>
</table></td>
<td><table style="color:darkgreen;background-color:powderblue;">
<tr><th title="Create report with NO tagging (NO Dup Tag)">Create Report without Tagging</th></tr>
<tr><td><center>
<button type="button" id="create_duplicate_report_task0" value="0" title="Create report using [Match Duplicate Distance]=0 (Exact Match). NO tagging.">Create Duplicate Report [Exact Match]</button>
</center></td></tr>
<tr><td><center>
<button type="button" id="create_duplicate_report_task1" value="1" title="Create report using [Match Duplicate Distance]=1 (High Match). NO tagging.">Create Duplicate Report [High Match]</button>
</center></td></tr>
<tr><td><center>
<button type="button" id="create_duplicate_report_task2" value="2" title="Create report using [Match Duplicate Distance]=2 (Medium Match). NO tagging.">Create Duplicate Report [Medium Match]</button>
</center></td></tr>
<tr><td><center>
<button type="button" id="create_duplicate_report_task3" value="3" title="Create report using [Match Duplicate Distance]=3 (Low Match). NO tagging.">Create Duplicate Report [Low Match]</button>
</center></td></tr>
</table></td>
</tr>
<tr><td style="font-size: 12px;" colspan="2">
<b>Details:</b>
@@ -1901,6 +1943,8 @@ function DeleteDupInPath(){
</ol>
</td></tr>
</table></center>
<div id="div1"></div>
</body></html>