clear current downloads
This commit is contained in:
parent
2dc72a39b7
commit
698b1fa4f3
5 changed files with 93 additions and 0 deletions
|
|
@ -1187,6 +1187,33 @@ class SoulseekClient:
|
||||||
))
|
))
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
async def cancel_all_downloads(self) -> bool:
|
||||||
|
"""Cancel and remove ALL downloads (active + completed) from slskd.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if successful, False otherwise
|
||||||
|
"""
|
||||||
|
if not self.base_url:
|
||||||
|
logger.error("Soulseek client not configured")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
endpoint = 'transfers/downloads/all'
|
||||||
|
logger.debug(f"Cancelling all downloads with endpoint: {endpoint}")
|
||||||
|
response = await self._make_request('DELETE', endpoint)
|
||||||
|
success = response is not None
|
||||||
|
|
||||||
|
if success:
|
||||||
|
logger.info("Successfully cancelled all downloads from slskd")
|
||||||
|
else:
|
||||||
|
logger.error("Failed to cancel all downloads from slskd")
|
||||||
|
|
||||||
|
return success
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error cancelling all downloads: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
async def clear_all_completed_downloads(self) -> bool:
|
async def clear_all_completed_downloads(self) -> bool:
|
||||||
"""Clear all completed/finished downloads from slskd backend
|
"""Clear all completed/finished downloads from slskd backend
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4981,6 +4981,28 @@ def cancel_download():
|
||||||
print(f"Error cancelling download: {e}")
|
print(f"Error cancelling download: {e}")
|
||||||
return jsonify({"success": False, "error": str(e)}), 500
|
return jsonify({"success": False, "error": str(e)}), 500
|
||||||
|
|
||||||
|
@app.route('/api/downloads/cancel-all', methods=['POST'])
|
||||||
|
def cancel_all_downloads():
|
||||||
|
"""
|
||||||
|
Cancel all active downloads from slskd, then clear completed ones.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# First cancel all active downloads
|
||||||
|
cancel_success = run_async(soulseek_client.cancel_all_downloads())
|
||||||
|
if not cancel_success:
|
||||||
|
return jsonify({"success": False, "error": "Failed to cancel active downloads."}), 500
|
||||||
|
|
||||||
|
# Then clear the now-cancelled/completed downloads
|
||||||
|
clear_success = run_async(soulseek_client.clear_all_completed_downloads())
|
||||||
|
|
||||||
|
# Sweep empty directories
|
||||||
|
_sweep_empty_download_directories()
|
||||||
|
|
||||||
|
return jsonify({"success": True, "message": "All downloads cancelled and cleared."})
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error cancelling all downloads: {e}")
|
||||||
|
return jsonify({"success": False, "error": str(e)}), 500
|
||||||
|
|
||||||
@app.route('/api/downloads/clear-finished', methods=['POST'])
|
@app.route('/api/downloads/clear-finished', methods=['POST'])
|
||||||
def clear_finished_downloads():
|
def clear_finished_downloads():
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1718,6 +1718,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="controls-panel__actions">
|
<div class="controls-panel__actions">
|
||||||
<button class="controls-panel__clear-btn">🗑️ Clear Completed</button>
|
<button class="controls-panel__clear-btn">🗑️ Clear Completed</button>
|
||||||
|
<button class="controls-panel__cancel-all-btn">⛔ Clear Current</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9887,10 +9887,14 @@ async function loadDownloadsData() {
|
||||||
|
|
||||||
// Event listeners are already set up in initializeSearch() - don't duplicate them
|
// Event listeners are already set up in initializeSearch() - don't duplicate them
|
||||||
const clearButton = document.querySelector('.controls-panel__clear-btn');
|
const clearButton = document.querySelector('.controls-panel__clear-btn');
|
||||||
|
const cancelAllButton = document.querySelector('.controls-panel__cancel-all-btn');
|
||||||
|
|
||||||
if (clearButton) {
|
if (clearButton) {
|
||||||
clearButton.addEventListener('click', clearFinishedDownloads);
|
clearButton.addEventListener('click', clearFinishedDownloads);
|
||||||
}
|
}
|
||||||
|
if (cancelAllButton) {
|
||||||
|
cancelAllButton.addEventListener('click', cancelAllDownloads);
|
||||||
|
}
|
||||||
|
|
||||||
// Start sophisticated polling system (1-second interval like GUI)
|
// Start sophisticated polling system (1-second interval like GUI)
|
||||||
startDownloadPolling();
|
startDownloadPolling();
|
||||||
|
|
@ -10157,6 +10161,28 @@ async function clearFinishedDownloads() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function cancelAllDownloads() {
|
||||||
|
if (!confirm('Cancel ALL active downloads and clear the transfer list? This cannot be undone.')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/downloads/cancel-all', {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
showToast('All downloads cancelled and cleared', 'success');
|
||||||
|
} else {
|
||||||
|
showToast(`Failed to cancel: ${result.error}`, 'error');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error cancelling all downloads:', error);
|
||||||
|
showToast('Error cancelling downloads', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// REPLACE the old performDownloadsSearch function with this new one.
|
// REPLACE the old performDownloadsSearch function with this new one.
|
||||||
async function performDownloadsSearch() {
|
async function performDownloadsSearch() {
|
||||||
const query = document.getElementById('downloads-search-input').value.trim();
|
const query = document.getElementById('downloads-search-input').value.trim();
|
||||||
|
|
|
||||||
|
|
@ -2641,6 +2641,23 @@ body {
|
||||||
background: linear-gradient(to bottom, rgba(220, 53, 69, 0.5), rgba(220, 53, 69, 0.35));
|
background: linear-gradient(to bottom, rgba(220, 53, 69, 0.5), rgba(220, 53, 69, 0.35));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.controls-panel__cancel-all-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 28px;
|
||||||
|
margin-top: 4px;
|
||||||
|
background: linear-gradient(to bottom, rgba(255, 152, 0, 0.4), rgba(255, 152, 0, 0.25));
|
||||||
|
border: 1px solid rgba(255, 152, 0, 0.8);
|
||||||
|
color: #ff9800;
|
||||||
|
border-radius: 14px;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls-panel__cancel-all-btn:hover {
|
||||||
|
background: linear-gradient(to bottom, rgba(255, 152, 0, 0.5), rgba(255, 152, 0, 0.35));
|
||||||
|
}
|
||||||
|
|
||||||
/* Download Manager (Tabs & Queue) */
|
/* Download Manager (Tabs & Queue) */
|
||||||
.download-manager {
|
.download-manager {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue