This commit is contained in:
Broque Thomas 2025-07-15 16:24:51 -07:00
parent 5a67a808fd
commit f77c023e10
6 changed files with 3841 additions and 1 deletions

View file

@ -1 +1 @@
{"access_token": "BQA46b0RlEdvS0gRj7PaBXvXHPWy0toM2vJeP4trcib5KSm7puoZAs-uTn5Bjqe1v8SZ8cMPGugxho1LE0yyHhmWs3x7eoNGlDshBLhKfT5bC-Yj6TK5WWAjYxsF1EPiHRgVVWu7jB9IoN2vFkR3xD6BvMvwQnxBhfFI8LrTFLEuXk-xwK3X8R9-_ctDOa5h1tAemIAj2GKtR3FJu1PpLXKWiGYpWj97V-aXfZELF9XjFhZ0MBbuNo4LCRBjZf4b", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1752618762, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"}
{"access_token": "BQCGCKAi71DX7yLnaLjQflWesuh4QmplWwUV3ZouqyFfFhTAyAulBmId5rKt6hpYiPEfEwXger63PgX9BeC5RdH5AjCI_qFOyA5I9nCj1mCE5MDG-SdOGJGSeDPKO0GVOWpilKItspumZEyeOubFAsgqmdHjOTb_CGIYV_Dhl0VPsl1wtG-ce_IKp9SkRqNys61IhcG2Mxc2YJ5PNfCwkOfX9XlbXMQjFMAlXXbv9Rdp1xmPKfx4zqOVGwl5uD5w", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1752623133, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"}

View file

@ -872,6 +872,41 @@ class SoulseekClient:
logger.error(f"Error cancelling download: {e}")
return False
async def signal_download_completion(self, download_id: str, username: str, remove: bool = True) -> bool:
"""Signal the Soulseek API that a download has completed or been cancelled
Args:
download_id: The ID of the download
username: The uploader username
remove: True to remove from transfer list (completion), False to just cancel
Returns:
bool: True if signal was successful, False otherwise
"""
if not self.base_url:
logger.error("Soulseek client not configured")
return False
try:
# Use the API endpoint format: /transfers/downloads/{username}/{download_id}?remove={true/false}
endpoint = f'transfers/downloads/{username}/{download_id}?remove={str(remove).lower()}'
action = "Signaling completion" if remove else "Signaling cancellation"
logger.debug(f"{action} for download {download_id} from {username}")
response = await self._make_request('DELETE', endpoint)
success = response is not None
if success:
logger.info(f"Successfully signaled download {action.lower()}: {download_id}")
else:
logger.warning(f"Failed to signal download {action.lower()}: {download_id}")
return success
except Exception as e:
logger.error(f"Error signaling download completion: {e}")
return False
async def clear_all_completed_downloads(self) -> bool:
"""Clear all completed/finished downloads from slskd backend

File diff suppressed because it is too large Load diff

View file

@ -1867,6 +1867,29 @@ class StreamingThread(QThread):
self.streaming_finished.emit(f"Stream ready: {os.path.basename(found_file)}", self.search_result)
self.temp_file_path = stream_path
print(f"✓ Stream file ready for playback: {stream_path}")
# Signal API that download is complete
try:
download_id = transfer.get('id', '')
if download_id and target_username:
import asyncio
from services.service_manager import service_manager
soulseek_client = service_manager.get_soulseek_client()
if soulseek_client:
# Run the async API call
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
success = loop.run_until_complete(
soulseek_client.signal_download_completion(download_id, target_username, remove=True)
)
loop.close()
if success:
print(f"✓ Successfully signaled completion for download {download_id}")
else:
print(f"⚠️ Failed to signal completion for download {download_id}")
except Exception as e:
print(f"⚠️ Error signaling download completion: {e}")
break # Exit main polling loop
except Exception as e:
@ -4460,6 +4483,32 @@ class TabbedDownloadManager(QTabWidget):
)
print(f"[DEBUG] Finished queue now has {len(self.finished_queue.download_items)} items")
# Signal API that download is complete (only for completed downloads)
# Note: Cancelled downloads already have their API signal sent by cancel_download()
try:
if (download_item.status == 'completed' and
download_item.download_id and download_item.username and download_item.soulseek_client):
import asyncio
# Run the async API call to signal completion
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
success = loop.run_until_complete(
download_item.soulseek_client.signal_download_completion(
download_item.download_id,
download_item.username,
remove=True # Remove completed downloads from transfer list
)
)
loop.close()
if success:
print(f"✓ Successfully signaled completion for download {download_item.download_id}")
else:
print(f"⚠️ Failed to signal completion for download {download_item.download_id}")
except Exception as e:
print(f"⚠️ Error signaling download completion: {e}")
self.update_tab_counts()
return finished_item
return None