mirror of
https://github.com/plexguide/Huntarr.io.git
synced 2026-04-20 11:26:52 -04:00
764 lines
38 KiB
JavaScript
764 lines
38 KiB
JavaScript
(function() {
|
|
window.SettingsForms = window.SettingsForms || {};
|
|
|
|
window.SettingsForms.generateSwaparrForm = function(container, settings = {}) {
|
|
if (!settings || typeof settings !== "object") {
|
|
settings = {};
|
|
}
|
|
|
|
container.setAttribute("data-app-type", "swaparr");
|
|
|
|
let html = `
|
|
<div style="margin-bottom: 25px;">
|
|
<div style="display: flex; gap: 15px; flex-wrap: wrap;">
|
|
<button type="button" id="swaparr-save-button" disabled style="
|
|
background: #6b7280;
|
|
color: #9ca3af;
|
|
border: 1px solid #4b5563;
|
|
padding: 8px 16px;
|
|
border-radius: 6px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
cursor: not-allowed;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
transition: all 0.2s ease;
|
|
">
|
|
<i class="fas fa-save"></i>
|
|
Save Changes
|
|
</button>
|
|
|
|
<div style="margin-left: auto; display: flex; gap: 10px;">
|
|
<a href="https://github.com/ThijmenGThN/swaparr" target="_blank" rel="noopener" style="
|
|
background: linear-gradient(135deg, #24292e 0%, #161b22 100%);
|
|
color: #f0f6fc;
|
|
border: 1px solid #30363d;
|
|
padding: 8px 16px;
|
|
border-radius: 6px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
text-decoration: none;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
transition: all 0.2s ease;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
" onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
|
|
<i class="fab fa-github" style="font-size: 16px;"></i>
|
|
View on GitHub
|
|
</a>
|
|
|
|
<a href="https://github.com/ThijmenGThN/swaparr/stargazers" target="_blank" rel="noopener" style="
|
|
background: linear-gradient(135deg, #f1c40f 0%, #f39c12 100%);
|
|
color: #fff;
|
|
border: 1px solid #d35400;
|
|
padding: 8px 16px;
|
|
border-radius: 6px;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
text-decoration: none;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
transition: all 0.2s ease;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
text-shadow: 0 1px 2px rgba(0,0,0,0.3);
|
|
" onmouseover="this.style.transform='scale(1.05)'" onmouseout="this.style.transform='scale(1)'">
|
|
<i class="fas fa-star" style="margin-right: 4px;"></i>
|
|
<span id="swaparr-stars-count">Loading...</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Advanced Options Notice -->
|
|
<div style="
|
|
background: linear-gradient(135deg, #164e63 0%, #0e7490 50%, #0891b2 100%);
|
|
border: 1px solid #22d3ee;
|
|
border-radius: 6px;
|
|
padding: 10px;
|
|
margin: 10px 0 15px 0;
|
|
box-shadow: 0 2px 8px rgba(34, 211, 238, 0.1);
|
|
">
|
|
<p style="color: #e0f7fa; margin: 0; font-size: 0.8em; line-height: 1.4;">
|
|
<i class="fas fa-rocket" style="margin-right: 6px; color: #22d3ee;"></i>
|
|
<strong>Need Advanced Options?</strong> For enhanced control and features, we recommend
|
|
<a href="https://github.com/cleanuparr/cleanuparr" target="_blank" rel="noopener" style="color: #fbbf24; text-decoration: none; font-weight: 600;">
|
|
<strong>Cleanuparr</strong>
|
|
</a> which offers more comprehensive management capabilities.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="settings-group">
|
|
<h3>Swaparr Configuration</h3>
|
|
<p class="setting-help" style="margin-bottom: 20px; color: #9ca3af;">
|
|
Swaparr monitors your *arr applications' download queues and removes stalled downloads automatically.
|
|
</p>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_enabled">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparr" class="info-icon" title="Enable or disable Swaparr" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Enable Swaparr:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_enabled" ${
|
|
settings.enabled === true ? "checked" : ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Enable automatic removal of stalled downloads</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_max_strikes">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparr" class="info-icon" title="Number of strikes before removal" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Max Strikes:
|
|
</label>
|
|
<input type="number" id="swaparr_max_strikes" min="1" max="10" value="${
|
|
settings.max_strikes || 3
|
|
}">
|
|
<p class="setting-help">Number of strikes a download gets before being removed (default: 3)</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_max_download_time">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparr" class="info-icon" title="Maximum time before considering download stalled" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Max Download Time:
|
|
</label>
|
|
<input type="text" id="swaparr_max_download_time" value="${
|
|
settings.max_download_time || "2h"
|
|
}" placeholder="e.g., 2h, 120m, 7200s">
|
|
<p class="setting-help">Maximum time before considering a download stalled (examples: 2h, 120m, 7200s)</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_ignore_above_size">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparr" class="info-icon" title="Ignore downloads larger than this size" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Ignore Above Size:
|
|
</label>
|
|
<input type="text" id="swaparr_ignore_above_size" value="${
|
|
settings.ignore_above_size || "25GB"
|
|
}" placeholder="e.g., 25GB, 10GB, 5000MB">
|
|
<p class="setting-help">Ignore downloads larger than this size (examples: 25GB, 10GB, 5000MB)</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_remove_from_client">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparr" class="info-icon" title="Remove downloads from download client" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Remove from Client:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_remove_from_client" ${
|
|
settings.remove_from_client !== false ? "checked" : ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Also remove downloads from the download client (recommended: enabled)</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_research_removed">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparr" class="info-icon" title="Automatically blocklist and re-search removed downloads" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Re-Search Removed Download:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_research_removed" ${
|
|
settings.research_removed === true ? "checked" : ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">When a download is removed, blocklist it in the *arr app and automatically search for alternatives (retry once)</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_failed_import_detection">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparr" class="info-icon" title="Automatically handle failed imports" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Handle Failed Imports:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_failed_import_detection" ${
|
|
settings.failed_import_detection === true
|
|
? "checked"
|
|
: ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Automatically detect failed imports, blocklist them, and search for alternatives</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_dry_run">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrdry-run-mode" class="info-icon" title="Test mode - no actual removals" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Dry Run Mode:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_dry_run" ${
|
|
settings.dry_run === true ? "checked" : ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Test mode - logs what would be removed without actually removing anything</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_ignore_usenet_queued">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrignore-usenet-queued" class="info-icon" title="Ignore queued usenet downloads with 0% progress" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Ignore Queued Usenet:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_ignore_usenet_queued" ${
|
|
settings.ignore_usenet_queued !== false ? "checked" : ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Ignore usenet downloads with 0% progress to avoid false positives from sequential queue ETAs (recommended: enabled)</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_remove_completed_stalled">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrremove-completed-stalled" class="info-icon" title="Treat 100% complete downloads as stalled" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Remove Completed (100%) Stalled:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_remove_completed_stalled" ${
|
|
settings.remove_completed_stalled !== false ? "checked" : ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">When enabled (default), Swaparr can remove 100% complete downloads after max strikes if they are stuck. When disabled, downloads that are 100% complete but waiting for manual import (e.g. name/year mismatch) are left alone.</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_sleep_duration">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrsleep-duration" class="info-icon" title="Time between Swaparr cycles" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Sleep Duration (Minutes):
|
|
</label>
|
|
<div class="input-group" style="display: flex; align-items: center; gap: 10px;">
|
|
<input type="number" id="swaparr_sleep_duration" value="${
|
|
settings.sleep_duration
|
|
? Math.round(settings.sleep_duration / 60)
|
|
: 15
|
|
}" min="10" max="1440" style="width: 120px;">
|
|
<span style="color: #9ca3af; font-size: 14px;">minutes</span>
|
|
</div>
|
|
<p class="setting-help">Time to wait between Swaparr processing cycles (minimum 10 minutes, default: 15 minutes)</p>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="settings-group">
|
|
<h3>Security Features</h3>
|
|
<p class="setting-help" style="margin-bottom: 20px; color: #9ca3af;">
|
|
Advanced security features to protect your system from malicious downloads and suspicious content by analyzing download names and titles. Detection is based on filename patterns, not file contents.
|
|
</p>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_malicious_detection">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrmalicious-file-detection" class="info-icon" title="Enable malicious file detection" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Malicious File Detection:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_malicious_detection" ${
|
|
settings.malicious_file_detection === true
|
|
? "checked"
|
|
: ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Automatically detect and immediately remove downloads with malicious file types</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_malicious_extensions_input">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrmalicious-extensions" class="info-icon" title="File extensions to consider malicious" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Malicious File Extensions:
|
|
</label>
|
|
<div class="tag-input-container">
|
|
<div class="tag-list" id="swaparr_malicious_extensions_tags"></div>
|
|
<div class="tag-input-wrapper">
|
|
<input type="text" id="swaparr_malicious_extensions_input" placeholder="Type extension and press Enter (e.g. .lnk)" class="tag-input">
|
|
<button type="button" class="tag-add-btn" onclick="window.SettingsForms.addExtensionTag()">
|
|
<i class="fas fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<p class="setting-help">File extensions to block. Type extension and press Enter or click +. Examples: .lnk, .exe, .bat, .zipx</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_suspicious_patterns_input">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrsuspicious-patterns" class="info-icon" title="Suspicious filename patterns" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Suspicious Patterns:
|
|
</label>
|
|
<div class="tag-input-container">
|
|
<div class="tag-list" id="swaparr_suspicious_patterns_tags"></div>
|
|
<div class="tag-input-wrapper">
|
|
<input type="text" id="swaparr_suspicious_patterns_input" placeholder="Type pattern and press Enter (e.g. keygen)" class="tag-input">
|
|
<button type="button" class="tag-add-btn" onclick="window.SettingsForms.addPatternTag()">
|
|
<i class="fas fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<p class="setting-help">Filename patterns to block. Type pattern and press Enter or click +. Examples: password.txt, keygen, crack</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="settings-group">
|
|
<h3>Age-Based Cleanup</h3>
|
|
<p class="setting-help" style="margin-bottom: 20px; color: #9ca3af;">
|
|
Automatically remove downloads that have been stuck for too long, regardless of strike count.
|
|
</p>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_age_based_removal">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrage-based-removal" class="info-icon" title="Enable age-based removal" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Enable Age-Based Removal:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_age_based_removal" ${
|
|
settings.age_based_removal === true ? "checked" : ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Remove downloads that have been stuck longer than the specified age limit</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_max_age_days">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrmax-age-days" class="info-icon" title="Maximum age before removal" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Maximum Age (Days):
|
|
</label>
|
|
<input type="number" id="swaparr_max_age_days" min="1" max="30" value="${
|
|
settings.max_age_days || 7
|
|
}">
|
|
<p class="setting-help">Remove downloads older than this many days (default: 7 days)</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="settings-group">
|
|
<h3>Quality-Based Filtering</h3>
|
|
<p class="setting-help" style="margin-bottom: 20px; color: #9ca3af;">
|
|
Automatically remove downloads with poor or undesirable quality indicators in their names.
|
|
</p>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_quality_based_removal">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrquality-based-removal" class="info-icon" title="Enable quality-based filtering" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Enable Quality-Based Filtering:
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="swaparr_quality_based_removal" ${
|
|
settings.quality_based_removal === true
|
|
? "checked"
|
|
: ""
|
|
}>
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<p class="setting-help">Automatically remove downloads with blocked quality patterns in their names</p>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<label for="swaparr_quality_patterns_input">
|
|
<a href="https://plexguide.github.io/Huntarr.io/apps/index.html#swaparrblocked-quality-patterns" class="info-icon" title="Quality patterns to block" target="_blank" rel="noopener">
|
|
<i class="fas fa-info-circle"></i>
|
|
</a>
|
|
Blocked Quality Patterns:
|
|
</label>
|
|
<div class="tag-input-container">
|
|
<div class="tag-list" id="swaparr_quality_patterns_tags"></div>
|
|
<div class="tag-input-wrapper">
|
|
<input type="text" id="swaparr_quality_patterns_input" placeholder="Type quality pattern and press Enter (e.g. cam)" class="tag-input">
|
|
<button type="button" class="tag-add-btn" onclick="window.SettingsForms.addQualityTag()">
|
|
<i class="fas fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<p class="setting-help">Quality patterns to block. Type pattern and press Enter or click +. Examples: cam, ts, hdcam, workprint</p>
|
|
</div>
|
|
</div>
|
|
|
|
`;
|
|
|
|
container.innerHTML = html;
|
|
|
|
window.SettingsForms.loadSwaparrStarCount();
|
|
window.SettingsForms.initializeTagSystem(settings);
|
|
|
|
const swaparrEnabledToggle = container.querySelector("#swaparr_enabled");
|
|
if (swaparrEnabledToggle) {
|
|
swaparrEnabledToggle.addEventListener("change", () => {
|
|
if (window.huntarrUI && window.huntarrUI.originalSettings && window.huntarrUI.originalSettings.swaparr) {
|
|
window.huntarrUI.originalSettings.swaparr.enabled = swaparrEnabledToggle.checked;
|
|
}
|
|
|
|
try {
|
|
const cachedSettings = localStorage.getItem("huntarr-settings-cache");
|
|
if (cachedSettings) {
|
|
const settings = JSON.parse(cachedSettings);
|
|
if (!settings.swaparr) settings.swaparr = {};
|
|
settings.swaparr.enabled = swaparrEnabledToggle.checked;
|
|
localStorage.setItem("huntarr-settings-cache", JSON.stringify(settings));
|
|
}
|
|
} catch (e) {
|
|
console.warn("[SettingsForms] Failed to update cached settings:", e);
|
|
}
|
|
|
|
if (window.SettingsForms.updateSwaparrFieldsDisabledState) {
|
|
window.SettingsForms.updateSwaparrFieldsDisabledState();
|
|
}
|
|
});
|
|
|
|
setTimeout(() => {
|
|
if (window.SettingsForms.updateSwaparrFieldsDisabledState) {
|
|
window.SettingsForms.updateSwaparrFieldsDisabledState();
|
|
}
|
|
}, 100);
|
|
}
|
|
|
|
if (window.SettingsForms.setupSwaparrManualSave) {
|
|
window.SettingsForms.setupSwaparrManualSave(container, settings);
|
|
}
|
|
};
|
|
|
|
window.SettingsForms.loadSwaparrStarCount = function() {
|
|
const starsElement = document.getElementById("swaparr-stars-count");
|
|
if (!starsElement) return;
|
|
|
|
const cachedData = localStorage.getItem("swaparr-github-stars");
|
|
if (cachedData) {
|
|
try {
|
|
const parsed = JSON.parse(cachedData);
|
|
if (parsed.stars !== undefined) {
|
|
starsElement.textContent = parsed.stars.toLocaleString();
|
|
const cacheAge = Date.now() - (parsed.timestamp || 0);
|
|
if (cacheAge < 3600000) {
|
|
return;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.warn("Invalid cached Swaparr star data, will fetch fresh");
|
|
localStorage.removeItem("swaparr-github-stars");
|
|
}
|
|
}
|
|
|
|
starsElement.textContent = "Loading...";
|
|
|
|
const apiUrl = "https://api.github.com/repos/ThijmenGThN/swaparr";
|
|
|
|
HuntarrUtils.fetchWithTimeout(apiUrl)
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
throw new Error(`GitHub API error: ${response.status}`);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then((data) => {
|
|
if (data && data.stargazers_count !== undefined) {
|
|
const formattedStars = data.stargazers_count.toLocaleString();
|
|
starsElement.textContent = formattedStars;
|
|
|
|
const cacheData = {
|
|
stars: data.stargazers_count,
|
|
timestamp: Date.now(),
|
|
};
|
|
localStorage.setItem("swaparr-github-stars", JSON.stringify(cacheData));
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.warn("Failed to fetch Swaparr stars:", error);
|
|
if (starsElement.textContent === "Loading...") {
|
|
starsElement.textContent = "Unknown";
|
|
}
|
|
});
|
|
};
|
|
|
|
window.SettingsForms.initializeTagSystem = function(settings) {
|
|
const defaultExtensions = [".lnk", ".exe", ".bat", ".cmd", ".scr", ".pif", ".com", ".zipx", ".jar", ".vbs", ".js", ".jse", ".wsf", ".wsh"];
|
|
const extensions = settings.malicious_extensions || defaultExtensions;
|
|
window.SettingsForms.loadTags("swaparr_malicious_extensions_tags", extensions);
|
|
|
|
const defaultPatterns = ["password.txt", "readme.txt", "install.exe", "setup.exe", "keygen", "crack", "patch.exe", "activator"];
|
|
const patterns = settings.suspicious_patterns || defaultPatterns;
|
|
window.SettingsForms.loadTags("swaparr_suspicious_patterns_tags", patterns);
|
|
|
|
const defaultQualityPatterns = ["cam", "camrip", "hdcam", "ts", "telesync", "tc", "telecine", "r6", "dvdscr", "dvdscreener", "workprint", "wp"];
|
|
const qualityPatterns = settings.blocked_quality_patterns || defaultQualityPatterns;
|
|
window.SettingsForms.loadTags("swaparr_quality_patterns_tags", qualityPatterns);
|
|
|
|
const extensionInput = document.getElementById("swaparr_malicious_extensions_input");
|
|
const patternInput = document.getElementById("swaparr_suspicious_patterns_input");
|
|
const qualityInput = document.getElementById("swaparr_quality_patterns_input");
|
|
|
|
if (extensionInput) {
|
|
extensionInput.addEventListener("keypress", (e) => {
|
|
if (e.key === "Enter") {
|
|
e.preventDefault();
|
|
window.SettingsForms.addExtensionTag();
|
|
}
|
|
});
|
|
}
|
|
|
|
if (patternInput) {
|
|
patternInput.addEventListener("keypress", (e) => {
|
|
if (e.key === "Enter") {
|
|
e.preventDefault();
|
|
window.SettingsForms.addPatternTag();
|
|
}
|
|
});
|
|
}
|
|
|
|
if (qualityInput) {
|
|
qualityInput.addEventListener("keypress", (e) => {
|
|
if (e.key === "Enter") {
|
|
e.preventDefault();
|
|
window.SettingsForms.addQualityTag();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Expose helper functions globally if needed by inline onclicks, though we prefer window.SettingsForms
|
|
// The inline onclicks in HTML above use window.SettingsForms.add*Tag()
|
|
};
|
|
|
|
window.SettingsForms.loadTags = function(containerId, tags) {
|
|
const container = document.getElementById(containerId);
|
|
if (!container) return;
|
|
|
|
container.innerHTML = "";
|
|
tags.forEach((tag) => {
|
|
window.SettingsForms.createTagElement(container, tag);
|
|
});
|
|
};
|
|
|
|
window.SettingsForms.createTagElement = function(container, text) {
|
|
const tagDiv = document.createElement("div");
|
|
tagDiv.className = "tag-item";
|
|
tagDiv.innerHTML = `
|
|
<span class="tag-text">${text}</span>
|
|
<button type="button" class="tag-remove" onclick="this.parentElement.remove()">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
`;
|
|
container.appendChild(tagDiv);
|
|
};
|
|
|
|
window.SettingsForms.addExtensionTag = function() {
|
|
const input = document.getElementById("swaparr_malicious_extensions_input");
|
|
const container = document.getElementById("swaparr_malicious_extensions_tags");
|
|
|
|
if (!input || !container) return;
|
|
|
|
let value = input.value.trim();
|
|
if (!value) return;
|
|
|
|
if (!value.startsWith(".")) {
|
|
value = "." + value;
|
|
}
|
|
|
|
const existing = Array.from(container.querySelectorAll(".tag-text")).map((el) => el.textContent);
|
|
if (existing.includes(value)) {
|
|
input.value = "";
|
|
return;
|
|
}
|
|
|
|
window.SettingsForms.createTagElement(container, value);
|
|
input.value = "";
|
|
};
|
|
|
|
window.SettingsForms.addPatternTag = function() {
|
|
const input = document.getElementById("swaparr_suspicious_patterns_input");
|
|
const container = document.getElementById("swaparr_suspicious_patterns_tags");
|
|
|
|
if (!input || !container) return;
|
|
|
|
const value = input.value.trim();
|
|
if (!value) return;
|
|
|
|
const existing = Array.from(container.querySelectorAll(".tag-text")).map((el) => el.textContent);
|
|
if (existing.includes(value)) {
|
|
input.value = "";
|
|
return;
|
|
}
|
|
|
|
window.SettingsForms.createTagElement(container, value);
|
|
input.value = "";
|
|
};
|
|
|
|
window.SettingsForms.addQualityTag = function() {
|
|
const input = document.getElementById("swaparr_quality_patterns_input");
|
|
const container = document.getElementById("swaparr_quality_patterns_tags");
|
|
|
|
if (!input || !container) return;
|
|
|
|
const value = input.value.trim().toLowerCase();
|
|
if (!value) return;
|
|
|
|
const existing = Array.from(container.querySelectorAll(".tag-text")).map((el) => el.textContent.toLowerCase());
|
|
if (existing.includes(value)) {
|
|
input.value = "";
|
|
return;
|
|
}
|
|
|
|
window.SettingsForms.createTagElement(container, value);
|
|
input.value = "";
|
|
};
|
|
|
|
window.SettingsForms.setupSwaparrManualSave = function(container, originalSettings = {}) {
|
|
const saveButton = container.querySelector("#swaparr-save-button");
|
|
if (!saveButton) return;
|
|
|
|
saveButton.disabled = true;
|
|
saveButton.style.background = "#6b7280";
|
|
saveButton.style.color = "#9ca3af";
|
|
saveButton.style.borderColor = "#4b5563";
|
|
saveButton.style.cursor = "not-allowed";
|
|
|
|
let hasChanges = false;
|
|
window.swaparrUnsavedChanges = false;
|
|
if (window.SettingsForms.removeUnsavedChangesWarning) {
|
|
window.SettingsForms.removeUnsavedChangesWarning();
|
|
}
|
|
|
|
const updateSaveButtonState = (changesDetected) => {
|
|
hasChanges = changesDetected;
|
|
window.swaparrUnsavedChanges = changesDetected;
|
|
const btn = container.querySelector("#swaparr-save-button");
|
|
if (!btn) return;
|
|
|
|
if (hasChanges) {
|
|
btn.disabled = false;
|
|
btn.style.background = "#dc2626";
|
|
btn.style.color = "#ffffff";
|
|
btn.style.borderColor = "#dc2626";
|
|
btn.style.cursor = "pointer";
|
|
if (window.SettingsForms.addUnsavedChangesWarning) {
|
|
window.SettingsForms.addUnsavedChangesWarning();
|
|
}
|
|
} else {
|
|
btn.disabled = true;
|
|
btn.style.background = "#6b7280";
|
|
btn.style.color = "#9ca3af";
|
|
btn.style.borderColor = "#4b5563";
|
|
btn.style.cursor = "not-allowed";
|
|
if (window.SettingsForms.removeUnsavedChangesWarning) {
|
|
window.SettingsForms.removeUnsavedChangesWarning();
|
|
}
|
|
}
|
|
};
|
|
|
|
container.addEventListener('input', () => updateSaveButtonState(true));
|
|
container.addEventListener('change', () => updateSaveButtonState(true));
|
|
|
|
const newSaveButton = saveButton.cloneNode(true);
|
|
saveButton.parentNode.replaceChild(newSaveButton, saveButton);
|
|
|
|
newSaveButton.addEventListener("click", () => {
|
|
if (!hasChanges) return;
|
|
|
|
newSaveButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Saving...';
|
|
newSaveButton.disabled = true;
|
|
|
|
// Collect data
|
|
const settings = { ...originalSettings };
|
|
|
|
const enabled = document.getElementById("swaparr_enabled");
|
|
if (enabled) settings.enabled = enabled.checked;
|
|
|
|
const maxStrikes = document.getElementById("swaparr_max_strikes");
|
|
if (maxStrikes) settings.max_strikes = parseInt(maxStrikes.value);
|
|
|
|
const maxDownloadTime = document.getElementById("swaparr_max_download_time");
|
|
if (maxDownloadTime) settings.max_download_time = maxDownloadTime.value;
|
|
|
|
const ignoreAboveSize = document.getElementById("swaparr_ignore_above_size");
|
|
if (ignoreAboveSize) settings.ignore_above_size = ignoreAboveSize.value;
|
|
|
|
const removeFromClient = document.getElementById("swaparr_remove_from_client");
|
|
if (removeFromClient) settings.remove_from_client = removeFromClient.checked;
|
|
|
|
const researchRemoved = document.getElementById("swaparr_research_removed");
|
|
if (researchRemoved) settings.research_removed = researchRemoved.checked;
|
|
|
|
const failedImport = document.getElementById("swaparr_failed_import_detection");
|
|
if (failedImport) settings.failed_import_detection = failedImport.checked;
|
|
|
|
const dryRun = document.getElementById("swaparr_dry_run");
|
|
if (dryRun) settings.dry_run = dryRun.checked;
|
|
|
|
const ignoreUsenetQueued = document.getElementById("swaparr_ignore_usenet_queued");
|
|
if (ignoreUsenetQueued) settings.ignore_usenet_queued = ignoreUsenetQueued.checked;
|
|
|
|
const removeCompletedStalled = document.getElementById("swaparr_remove_completed_stalled");
|
|
if (removeCompletedStalled) settings.remove_completed_stalled = removeCompletedStalled.checked;
|
|
|
|
const sleepDuration = document.getElementById("swaparr_sleep_duration");
|
|
if (sleepDuration) settings.sleep_duration = parseInt(sleepDuration.value) * 60;
|
|
|
|
const malicious = document.getElementById("swaparr_malicious_detection");
|
|
if (malicious) settings.malicious_file_detection = malicious.checked;
|
|
|
|
const ageRemoval = document.getElementById("swaparr_age_based_removal");
|
|
if (ageRemoval) settings.age_based_removal = ageRemoval.checked;
|
|
|
|
const maxAge = document.getElementById("swaparr_max_age_days");
|
|
if (maxAge) settings.max_age_days = parseInt(maxAge.value);
|
|
|
|
const qualityRemoval = document.getElementById("swaparr_quality_based_removal");
|
|
if (qualityRemoval) settings.quality_based_removal = qualityRemoval.checked;
|
|
|
|
// Collect tags
|
|
const getTags = (id) => {
|
|
const container = document.getElementById(id);
|
|
if (!container) return [];
|
|
return Array.from(container.querySelectorAll(".tag-text")).map(el => el.textContent);
|
|
};
|
|
|
|
settings.malicious_extensions = getTags("swaparr_malicious_extensions_tags");
|
|
settings.suspicious_patterns = getTags("swaparr_suspicious_patterns_tags");
|
|
settings.blocked_quality_patterns = getTags("swaparr_quality_patterns_tags");
|
|
|
|
// Save
|
|
window.SettingsForms.saveAppSettings("swaparr", settings);
|
|
|
|
// Reset UI state
|
|
newSaveButton.innerHTML = '<i class="fas fa-save"></i> Save Changes';
|
|
updateSaveButtonState(false);
|
|
});
|
|
};
|
|
})();
|