fix
This commit is contained in:
parent
96a0bc4b43
commit
f647df1ebe
5 changed files with 733 additions and 238 deletions
Binary file not shown.
|
|
@ -294,7 +294,7 @@ class SoulseekClient:
|
|||
logger.error(f"Error in progress callback: {e}")
|
||||
|
||||
# Early termination if we have enough results
|
||||
if len(all_results) >= 100: # Stop after 100 results for better performance
|
||||
if len(all_results) >= 45: # Stop after 45 results for better performance (3 pages of 15)
|
||||
logger.info(f"Early termination: Found {len(all_results)} results, stopping search")
|
||||
break
|
||||
elif len(all_results) > 0:
|
||||
|
|
|
|||
345
logs/app.log
345
logs/app.log
|
|
@ -5568,3 +5568,348 @@
|
|||
2025-07-10 08:02:53 - newmusic.soulseek_client - [92mINFO[0m - search:288 - Found 418 new results (total: 418) at 15.0s
|
||||
2025-07-10 08:02:53 - newmusic.soulseek_client - [92mINFO[0m - search:298 - Early termination: Found 418 results, stopping search
|
||||
2025-07-10 08:02:53 - newmusic.soulseek_client - [92mINFO[0m - search:309 - Search completed. Found 418 total results for query: Virtual Mage
|
||||
2025-07-10 08:27:25 - newmusic.main - [92mINFO[0m - closeEvent:152 - Closing application...
|
||||
2025-07-10 08:27:25 - newmusic.main - [92mINFO[0m - closeEvent:157 - Cleaning up Downloads page threads...
|
||||
2025-07-10 08:27:25 - newmusic.main - [92mINFO[0m - closeEvent:162 - Stopping status monitoring thread...
|
||||
2025-07-10 08:27:26 - newmusic.main - [92mINFO[0m - closeEvent:167 - Closing Soulseek client...
|
||||
2025-07-10 08:27:26 - newmusic.main - [92mINFO[0m - closeEvent:173 - Application closed successfully
|
||||
2025-07-10 08:27:30 - newmusic - [92mINFO[0m - setup_logging:57 - Logging initialized with level: DEBUG
|
||||
2025-07-10 08:27:30 - newmusic.main - [92mINFO[0m - main:187 - Starting NewMusic application
|
||||
2025-07-10 08:27:30 - newmusic.spotify_client - [92mINFO[0m - _setup_client:84 - Successfully authenticated with Spotify as broquethomas
|
||||
2025-07-10 08:27:31 - newmusic.plex_client - [92mINFO[0m - _find_music_library:98 - Found music library: Music
|
||||
2025-07-10 08:27:31 - newmusic.plex_client - [92mINFO[0m - _setup_client:84 - Successfully connected to Plex server: PLEX-MACHINE
|
||||
2025-07-10 08:27:31 - newmusic.soulseek_client - [92mINFO[0m - _setup_client:87 - Soulseek client configured with slskd at http://localhost:5030
|
||||
2025-07-10 08:27:32 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: dashboard
|
||||
2025-07-10 08:27:32 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Aether
|
||||
2025-07-10 08:27:32 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Favorite Artists
|
||||
2025-07-10 08:27:35 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Brittnea
|
||||
2025-07-10 08:27:37 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Baleigh
|
||||
2025-07-10 08:27:39 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Extra Music
|
||||
2025-07-10 08:27:39 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Maggi Main
|
||||
2025-07-10 08:27:45 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Broque Main
|
||||
2025-07-10 08:27:53 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:113 - Retrieved 7 playlists
|
||||
2025-07-10 08:27:55 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: downloads
|
||||
2025-07-10 08:28:03 - newmusic.soulseek_client - [92mINFO[0m - search:243 - Starting search for: 'virtual mage'
|
||||
2025-07-10 08:28:03 - newmusic.soulseek_client - [94mDEBUG[0m - search:253 - Search data: {'searchText': 'virtual mage', 'timeout': 30000, 'filterResponses': True, 'minimumResponseFileCount': 1, 'minimumPeerUploadSpeed': 0}
|
||||
2025-07-10 08:28:03 - newmusic.soulseek_client - [94mDEBUG[0m - search:254 - Making POST request to: http://localhost:5030/api/v0/searches
|
||||
2025-07-10 08:28:03 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making POST request to: http://localhost:5030/api/v0/searches
|
||||
2025-07-10 08:28:03 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:03 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:112 - JSON payload: {'searchText': 'virtual mage', 'timeout': 30000, 'filterResponses': True, 'minimumResponseFileCount': 1, 'minimumPeerUploadSpeed': 0}
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: {"fileCount":0,"id":"ced78c9d-f1b4-491a-9595-d2c9ec9c3509","isComplete":false,"lockedFileCount":0,"responseCount":0,"responses":[],"searchText":"virtual mage","startedAt":"2025-07-10T15:28:04.1760975Z","state":"InProgress","token":136}...
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [92mINFO[0m - search:267 - Search initiated with ID: ced78c9d-f1b4-491a-9595-d2c9ec9c3509
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 1/20) - elapsed: 0.0s
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:04 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:06 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 2/20) - elapsed: 1.5s
|
||||
2025-07-10 08:28:06 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:06 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:06 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:06 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:07 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 3/20) - elapsed: 3.0s
|
||||
2025-07-10 08:28:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:08 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:08 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:09 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 4/20) - elapsed: 4.5s
|
||||
2025-07-10 08:28:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:11 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 5/20) - elapsed: 6.0s
|
||||
2025-07-10 08:28:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:13 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 6/20) - elapsed: 7.5s
|
||||
2025-07-10 08:28:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:15 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 7/20) - elapsed: 9.0s
|
||||
2025-07-10 08:28:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:16 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 8/20) - elapsed: 10.5s
|
||||
2025-07-10 08:28:16 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:16 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:18 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 9/20) - elapsed: 12.0s
|
||||
2025-07-10 08:28:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:19 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:19 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:20 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 10/20) - elapsed: 13.5s
|
||||
2025-07-10 08:28:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 11/20) - elapsed: 15.0s
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/ced78c9d-f1b4-491a-9595-d2c9ec9c3509/responses
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: [{"fileCount":3,"files":[{"bitRate":183,"code":1,"extension":"","filename":"Music\\Vaporwave\\Vapor Vault\\virtual-internet-prison-vhs-wkvbyn\\BOSEBY - Virtual Internet Prison (VHS) - 02 Temple Vision.vhs Featuring Wave Mage.mp3","isVariableBitRate":true,"length":186,"size":4348704,"isLocked":false},{"bitRate":172,"code":1,"extension":"","filename":"Music\\Vaporwave\\Vapor Vault\\virtual-internet-prison-vhs-wkvbyn\\BOSEBY - Virtual Internet Prison (VHS) - 05 SD.vhs Featuring PKSkyler, CentaurSap...
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:208 - Processing 24 user responses
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User koalabeer has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Ultravod has 9 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Letham has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Kaya-Sem has 1 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User raspberry2 has 10 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Satani-Vitales has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User RuuqoHoosk has 346 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User soulshookt has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User buk4 has 1 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User zeroscan has 2 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User exsanguinidraculae has 2 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User nightmare_dronemk12 has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User wonko1987 has 2 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User KindaRatchet has 1 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User HomotopicCensorship has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User belthane has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Shooby has 6 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User aajzugikamlzcr has 1 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User ruszok has 1 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User leonardoclk has 3 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Dax_VR has 10 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User thinkibettergo has 1 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User FixxAlish has 1 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User ofoijacussa has 0 files
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [92mINFO[0m - search:288 - Found 418 new results (total: 418) at 15.0s
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [92mINFO[0m - search:298 - Early termination: Found 418 results, stopping search
|
||||
2025-07-10 08:28:22 - newmusic.soulseek_client - [92mINFO[0m - search:309 - Search completed. Found 418 total results for query: virtual mage
|
||||
2025-07-10 08:30:59 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: artists
|
||||
2025-07-10 08:30:59 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: downloads
|
||||
2025-07-10 08:35:14 - newmusic.main - [92mINFO[0m - closeEvent:152 - Closing application...
|
||||
2025-07-10 08:35:14 - newmusic.main - [92mINFO[0m - closeEvent:157 - Cleaning up Downloads page threads...
|
||||
2025-07-10 08:35:14 - newmusic.main - [92mINFO[0m - closeEvent:162 - Stopping status monitoring thread...
|
||||
2025-07-10 08:35:15 - newmusic.main - [92mINFO[0m - closeEvent:167 - Closing Soulseek client...
|
||||
2025-07-10 08:35:15 - newmusic.main - [92mINFO[0m - closeEvent:173 - Application closed successfully
|
||||
2025-07-10 08:35:54 - newmusic - [92mINFO[0m - setup_logging:57 - Logging initialized with level: DEBUG
|
||||
2025-07-10 08:35:54 - newmusic.main - [92mINFO[0m - main:187 - Starting NewMusic application
|
||||
2025-07-10 08:35:54 - newmusic.spotify_client - [92mINFO[0m - _setup_client:84 - Successfully authenticated with Spotify as broquethomas
|
||||
2025-07-10 08:35:54 - newmusic.plex_client - [92mINFO[0m - _find_music_library:98 - Found music library: Music
|
||||
2025-07-10 08:35:54 - newmusic.plex_client - [92mINFO[0m - _setup_client:84 - Successfully connected to Plex server: PLEX-MACHINE
|
||||
2025-07-10 08:35:54 - newmusic.soulseek_client - [92mINFO[0m - _setup_client:87 - Soulseek client configured with slskd at http://localhost:5030
|
||||
2025-07-10 08:35:55 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: dashboard
|
||||
2025-07-10 08:35:56 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Aether
|
||||
2025-07-10 08:35:56 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Favorite Artists
|
||||
2025-07-10 08:35:59 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Brittnea
|
||||
2025-07-10 08:36:00 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Baleigh
|
||||
2025-07-10 08:36:02 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: downloads
|
||||
2025-07-10 08:36:02 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Extra Music
|
||||
2025-07-10 08:36:03 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Maggi Main
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [92mINFO[0m - search:243 - Starting search for: 'virtual mage'
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - search:253 - Search data: {'searchText': 'virtual mage', 'timeout': 30000, 'filterResponses': True, 'minimumResponseFileCount': 1, 'minimumPeerUploadSpeed': 0}
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - search:254 - Making POST request to: http://localhost:5030/api/v0/searches
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making POST request to: http://localhost:5030/api/v0/searches
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:112 - JSON payload: {'searchText': 'virtual mage', 'timeout': 30000, 'filterResponses': True, 'minimumResponseFileCount': 1, 'minimumPeerUploadSpeed': 0}
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: {"fileCount":0,"id":"98191a41-4791-4d60-a8dc-29016f6a8f2f","isComplete":false,"lockedFileCount":0,"responseCount":0,"responses":[],"searchText":"virtual mage","startedAt":"2025-07-10T15:36:05.6834182Z","state":"InProgress","token":137}...
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [92mINFO[0m - search:267 - Search initiated with ID: 98191a41-4791-4d60-a8dc-29016f6a8f2f
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 1/20) - elapsed: 0.0s
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:05 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:06 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:06 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:07 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 2/20) - elapsed: 1.5s
|
||||
2025-07-10 08:36:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:09 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Broque Main
|
||||
2025-07-10 08:36:09 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 3/20) - elapsed: 3.0s
|
||||
2025-07-10 08:36:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:11 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 4/20) - elapsed: 4.5s
|
||||
2025-07-10 08:36:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:13 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 5/20) - elapsed: 6.0s
|
||||
2025-07-10 08:36:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:14 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 6/20) - elapsed: 7.5s
|
||||
2025-07-10 08:36:14 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:14 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:16 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 7/20) - elapsed: 9.0s
|
||||
2025-07-10 08:36:16 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:16 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:17 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:113 - Retrieved 7 playlists
|
||||
2025-07-10 08:36:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:18 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 8/20) - elapsed: 10.5s
|
||||
2025-07-10 08:36:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:20 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 9/20) - elapsed: 12.0s
|
||||
2025-07-10 08:36:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:22 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 10/20) - elapsed: 13.5s
|
||||
2025-07-10 08:36:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 11/20) - elapsed: 15.0s
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/98191a41-4791-4d60-a8dc-29016f6a8f2f/responses
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: [{"fileCount":1,"files":[{"bitRate":128,"code":1,"extension":"","filename":"Shared\\Virtual Mage\\Refraction 1191940288\\Virtual Mage - Virtual Mage.mp3","isVariableBitRate":false,"length":154,"size":2476160,"isLocked":false}],"hasFreeUploadSlot":true,"lockedFileCount":0,"lockedFiles":[],"queueLength":9,"token":137,"uploadSpeed":518299,"username":"KindaRatchet"},{"fileCount":2,"files":[{"bitRate":160,"code":1,"extension":"","filename":"Music\\aofd3\\Mallsoft & Shopping Mall Ambience\\03 - Virtua...
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:208 - Processing 24 user responses
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User KindaRatchet has 1 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User zeroscan has 2 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User buk4 has 1 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User HomotopicCensorship has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User exsanguinidraculae has 2 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Letham has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User belthane has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User RuuqoHoosk has 346 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User aajzugikamlzcr has 1 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User leonardoclk has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Dax_VR has 10 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Satani-Vitales has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User ruszok has 1 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User FixxAlish has 1 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User wonko1987 has 2 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User thinkibettergo has 1 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User soulshookt has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User ofoijacussa has 0 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User koalabeer has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User raspberry2 has 10 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User nightmare_dronemk12 has 3 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Ultravod has 9 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Kaya-Sem has 1 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Shooby has 6 files
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [92mINFO[0m - search:288 - Found 418 new results (total: 418) at 15.0s
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [92mINFO[0m - search:298 - Early termination: Found 418 results, stopping search
|
||||
2025-07-10 08:36:24 - newmusic.soulseek_client - [92mINFO[0m - search:309 - Search completed. Found 418 total results for query: virtual mage
|
||||
2025-07-10 08:57:35 - newmusic.main - [92mINFO[0m - closeEvent:152 - Closing application...
|
||||
2025-07-10 08:57:35 - newmusic.main - [92mINFO[0m - closeEvent:157 - Cleaning up Downloads page threads...
|
||||
2025-07-10 08:57:35 - newmusic.main - [92mINFO[0m - closeEvent:162 - Stopping status monitoring thread...
|
||||
2025-07-10 08:57:35 - newmusic.main - [92mINFO[0m - closeEvent:167 - Closing Soulseek client...
|
||||
2025-07-10 08:57:35 - newmusic.main - [92mINFO[0m - closeEvent:173 - Application closed successfully
|
||||
2025-07-10 08:57:40 - newmusic - [92mINFO[0m - setup_logging:57 - Logging initialized with level: DEBUG
|
||||
2025-07-10 08:57:40 - newmusic.main - [92mINFO[0m - main:187 - Starting NewMusic application
|
||||
2025-07-10 08:57:40 - newmusic.spotify_client - [92mINFO[0m - _setup_client:84 - Successfully authenticated with Spotify as broquethomas
|
||||
2025-07-10 08:57:40 - newmusic.plex_client - [92mINFO[0m - _find_music_library:98 - Found music library: Music
|
||||
2025-07-10 08:57:40 - newmusic.plex_client - [92mINFO[0m - _setup_client:84 - Successfully connected to Plex server: PLEX-MACHINE
|
||||
2025-07-10 08:57:40 - newmusic.soulseek_client - [92mINFO[0m - _setup_client:87 - Soulseek client configured with slskd at http://localhost:5030
|
||||
2025-07-10 08:57:41 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: dashboard
|
||||
2025-07-10 08:57:41 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Aether
|
||||
2025-07-10 08:57:42 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Favorite Artists
|
||||
2025-07-10 08:57:45 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Brittnea
|
||||
2025-07-10 08:57:46 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Baleigh
|
||||
2025-07-10 08:57:48 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Extra Music
|
||||
2025-07-10 08:57:49 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Maggi Main
|
||||
2025-07-10 08:57:55 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:106 - Fetching tracks for playlist: Broque Main
|
||||
2025-07-10 08:58:03 - newmusic.spotify_client - [92mINFO[0m - get_user_playlists:113 - Retrieved 7 playlists
|
||||
2025-07-10 08:58:04 - newmusic.main - [92mINFO[0m - change_page:139 - Changed to page: downloads
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [92mINFO[0m - search:243 - Starting search for: 'virtual mage'
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - search:253 - Search data: {'searchText': 'virtual mage', 'timeout': 30000, 'filterResponses': True, 'minimumResponseFileCount': 1, 'minimumPeerUploadSpeed': 0}
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - search:254 - Making POST request to: http://localhost:5030/api/v0/searches
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making POST request to: http://localhost:5030/api/v0/searches
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:112 - JSON payload: {'searchText': 'virtual mage', 'timeout': 30000, 'filterResponses': True, 'minimumResponseFileCount': 1, 'minimumPeerUploadSpeed': 0}
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: {"fileCount":0,"id":"809820d8-2d3b-4cee-9dc2-7b7a2398cfbd","isComplete":false,"lockedFileCount":0,"responseCount":0,"responses":[],"searchText":"virtual mage","startedAt":"2025-07-10T15:58:07.8291392Z","state":"InProgress","token":138}...
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [92mINFO[0m - search:267 - Search initiated with ID: 809820d8-2d3b-4cee-9dc2-7b7a2398cfbd
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 1/20) - elapsed: 0.0s
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:07 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:08 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:08 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:09 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 2/20) - elapsed: 1.5s
|
||||
2025-07-10 08:58:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:09 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:10 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:10 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:11 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 3/20) - elapsed: 3.0s
|
||||
2025-07-10 08:58:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:11 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:13 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 4/20) - elapsed: 4.5s
|
||||
2025-07-10 08:58:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:13 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:15 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 5/20) - elapsed: 6.0s
|
||||
2025-07-10 08:58:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:15 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:17 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 6/20) - elapsed: 7.5s
|
||||
2025-07-10 08:58:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:17 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:18 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 7/20) - elapsed: 9.0s
|
||||
2025-07-10 08:58:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:18 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:19 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:19 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:20 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 8/20) - elapsed: 10.5s
|
||||
2025-07-10 08:58:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:20 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:22 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 9/20) - elapsed: 12.0s
|
||||
2025-07-10 08:58:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:22 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:24 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 10/20) - elapsed: 13.5s
|
||||
2025-07-10 08:58:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:24 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:26 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 11/20) - elapsed: 15.0s
|
||||
2025-07-10 08:58:26 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:26 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:26 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:26 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: []...
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - search:275 - Polling for results (attempt 12/20) - elapsed: 16.5s
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:109 - Making GET request to: http://localhost:5030/api/v0/searches/809820d8-2d3b-4cee-9dc2-7b7a2398cfbd/responses
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:110 - Headers: {'Content-Type': 'application/json', 'X-API-Key': '1234567891234567'}
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:121 - Response status: 200
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _make_request:122 - Response text: [{"fileCount":3,"files":[{"bitRate":183,"code":1,"extension":"","filename":"Music\\Vaporwave\\Vapor Vault\\virtual-internet-prison-vhs-wkvbyn\\BOSEBY - Virtual Internet Prison (VHS) - 02 Temple Vision.vhs Featuring Wave Mage.mp3","isVariableBitRate":true,"length":186,"size":4348704,"isLocked":false},{"bitRate":172,"code":1,"extension":"","filename":"Music\\Vaporwave\\Vapor Vault\\virtual-internet-prison-vhs-wkvbyn\\BOSEBY - Virtual Internet Prison (VHS) - 05 SD.vhs Featuring PKSkyler, CentaurSap...
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:208 - Processing 23 user responses
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User koalabeer has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Letham has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User raspberry2 has 10 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Kaya-Sem has 1 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Satani-Vitales has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User aajzugikamlzcr has 1 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User zeroscan has 2 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User RuuqoHoosk has 346 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User buk4 has 1 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Ultravod has 9 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User HomotopicCensorship has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User belthane has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User wonko1987 has 2 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User exsanguinidraculae has 2 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User Shooby has 6 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User leonardoclk has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User soulshookt has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User FixxAlish has 1 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User thinkibettergo has 1 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User ruszok has 1 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User ofoijacussa has 0 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User KindaRatchet has 1 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [94mDEBUG[0m - _process_search_responses:213 - User nightmare_dronemk12 has 3 files
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [92mINFO[0m - search:288 - Found 408 new results (total: 408) at 16.5s
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [92mINFO[0m - search:298 - Early termination: Found 408 results, stopping search
|
||||
2025-07-10 08:58:28 - newmusic.soulseek_client - [92mINFO[0m - search:309 - Search completed. Found 408 total results for query: virtual mage
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -243,15 +243,27 @@ class SearchThread(QThread):
|
|||
|
||||
class SearchResultItem(QFrame):
|
||||
download_requested = pyqtSignal(object) # SearchResult object
|
||||
expansion_requested = pyqtSignal(object) # Signal when this item wants to expand
|
||||
|
||||
def __init__(self, search_result, parent=None):
|
||||
super().__init__(parent)
|
||||
self.search_result = search_result
|
||||
self.is_downloading = False
|
||||
self.is_expanded = False
|
||||
self.setup_ui()
|
||||
|
||||
def setup_ui(self):
|
||||
self.setFixedHeight(90) # Professional height to prevent overflow
|
||||
# Dynamic height based on state (compact: 60px, expanded: 180px for better content fit)
|
||||
self.compact_height = 60
|
||||
self.expanded_height = 180 # Increased from 140px to fit content properly
|
||||
self.setFixedHeight(self.compact_height)
|
||||
|
||||
# Ensure consistent sizing and layout behavior
|
||||
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
|
||||
# Enable mouse tracking for click detection
|
||||
self.setMouseTracking(True)
|
||||
|
||||
self.setStyleSheet("""
|
||||
SearchResultItem {
|
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
|
|
@ -259,122 +271,53 @@ class SearchResultItem(QFrame):
|
|||
stop:1 rgba(32, 32, 32, 0.95));
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(64, 64, 64, 0.4);
|
||||
margin: 6px 4px;
|
||||
margin: 4px 2px;
|
||||
}
|
||||
SearchResultItem:hover {
|
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
stop:0 rgba(50, 50, 50, 0.95),
|
||||
stop:1 rgba(40, 40, 40, 0.98));
|
||||
border: 1px solid rgba(29, 185, 84, 0.7);
|
||||
cursor: pointer;
|
||||
}
|
||||
""")
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(16, 12, 16, 12) # Professional padding
|
||||
layout.setSpacing(16) # Consistent spacing
|
||||
layout.setContentsMargins(12, 8, 12, 8) # Tighter padding for compact view
|
||||
layout.setSpacing(12)
|
||||
|
||||
# Compact album art
|
||||
album_art = QLabel()
|
||||
album_art.setFixedSize(56, 56)
|
||||
album_art.setStyleSheet("""
|
||||
# Left section: Music icon + filename
|
||||
left_section = QHBoxLayout()
|
||||
left_section.setSpacing(8)
|
||||
|
||||
# Compact music icon
|
||||
music_icon = QLabel("🎵")
|
||||
music_icon.setFixedSize(32, 32)
|
||||
music_icon.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
music_icon.setStyleSheet("""
|
||||
QLabel {
|
||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
|
||||
stop:0 rgba(29, 185, 84, 0.25),
|
||||
stop:1 rgba(29, 185, 84, 0.08));
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(29, 185, 84, 0.3);
|
||||
stop:0 rgba(29, 185, 84, 0.3),
|
||||
stop:1 rgba(29, 185, 84, 0.1));
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(29, 185, 84, 0.4);
|
||||
font-size: 14px;
|
||||
}
|
||||
""")
|
||||
album_art.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
album_art.setText("🎵")
|
||||
album_art.setFont(QFont("Arial", 18))
|
||||
|
||||
# Efficient content layout - single column
|
||||
content_layout = QVBoxLayout()
|
||||
content_layout.setSpacing(2)
|
||||
content_layout.setContentsMargins(0, 0, 0, 0)
|
||||
# Content area that will change based on expanded state
|
||||
self.content_widget = QWidget()
|
||||
self.content_layout = QVBoxLayout(self.content_widget)
|
||||
self.content_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.content_layout.setSpacing(3) # Tighter spacing for better content density
|
||||
|
||||
# Extract song info
|
||||
primary_info = self._extract_song_info()
|
||||
|
||||
# Top row: Song title + quality badge
|
||||
top_row = QHBoxLayout()
|
||||
top_row.setSpacing(8)
|
||||
# Create both compact and expanded content but show only one
|
||||
self.create_persistent_content(primary_info)
|
||||
|
||||
song_title = QLabel(primary_info['title'])
|
||||
song_title.setFont(QFont("Arial", 12, QFont.Weight.Bold))
|
||||
song_title.setStyleSheet("color: #ffffff;")
|
||||
song_title.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
|
||||
|
||||
quality_badge = self._create_compact_quality_badge()
|
||||
|
||||
top_row.addWidget(song_title)
|
||||
top_row.addWidget(quality_badge)
|
||||
|
||||
# Middle row: Artist + file size + duration
|
||||
middle_row = QHBoxLayout()
|
||||
middle_row.setSpacing(12)
|
||||
|
||||
artist_info = QLabel(primary_info['artist'])
|
||||
artist_info.setFont(QFont("Arial", 10, QFont.Weight.Normal))
|
||||
artist_info.setStyleSheet("color: rgba(179, 179, 179, 0.9);")
|
||||
artist_info.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
|
||||
|
||||
# File details (compact)
|
||||
details = []
|
||||
size_mb = self.search_result.size // (1024*1024)
|
||||
details.append(f"{size_mb}MB")
|
||||
|
||||
if self.search_result.duration:
|
||||
duration_mins = self.search_result.duration // 60
|
||||
duration_secs = self.search_result.duration % 60
|
||||
details.append(f"{duration_mins}:{duration_secs:02d}")
|
||||
|
||||
file_details = QLabel(" • ".join(details))
|
||||
file_details.setFont(QFont("Arial", 9))
|
||||
file_details.setStyleSheet("color: rgba(136, 136, 136, 0.8);")
|
||||
|
||||
middle_row.addWidget(artist_info)
|
||||
middle_row.addWidget(file_details)
|
||||
|
||||
# Bottom row: User info + speed indicator
|
||||
bottom_row = QHBoxLayout()
|
||||
bottom_row.setSpacing(8)
|
||||
|
||||
user_info = QLabel(f"👤 {self.search_result.username}")
|
||||
user_info.setFont(QFont("Arial", 9, QFont.Weight.Medium))
|
||||
user_info.setStyleSheet("color: rgba(29, 185, 84, 0.8);")
|
||||
|
||||
speed_indicator = self._create_compact_speed_indicator()
|
||||
|
||||
bottom_row.addWidget(user_info)
|
||||
bottom_row.addWidget(speed_indicator)
|
||||
bottom_row.addStretch()
|
||||
|
||||
content_layout.addLayout(top_row)
|
||||
content_layout.addLayout(middle_row)
|
||||
content_layout.addLayout(bottom_row)
|
||||
|
||||
# Compact action area
|
||||
action_layout = QVBoxLayout()
|
||||
action_layout.setSpacing(4)
|
||||
action_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
action_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# Compact quality score
|
||||
quality_score = QLabel(f"★{self.search_result.quality_score:.1f}")
|
||||
quality_score.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
quality_score.setFont(QFont("Arial", 9, QFont.Weight.Bold))
|
||||
quality_score.setFixedSize(36, 18)
|
||||
|
||||
if self.search_result.quality_score >= 0.9:
|
||||
quality_score.setStyleSheet("color: #1db954; background: rgba(29, 185, 84, 0.15); border-radius: 9px;")
|
||||
elif self.search_result.quality_score >= 0.7:
|
||||
quality_score.setStyleSheet("color: #ffa500; background: rgba(255, 165, 0, 0.15); border-radius: 9px;")
|
||||
else:
|
||||
quality_score.setStyleSheet("color: #e22134; background: rgba(226, 33, 52, 0.15); border-radius: 9px;")
|
||||
|
||||
# Compact download button
|
||||
# Right section: Always-visible download button
|
||||
self.download_btn = QPushButton("⬇️")
|
||||
self.download_btn.setFixedSize(36, 36)
|
||||
self.download_btn.clicked.connect(self.request_download)
|
||||
|
|
@ -401,12 +344,197 @@ class SearchResultItem(QFrame):
|
|||
}
|
||||
""")
|
||||
|
||||
action_layout.addWidget(quality_score)
|
||||
action_layout.addWidget(self.download_btn)
|
||||
# Assemble the layout
|
||||
left_section.addWidget(music_icon)
|
||||
left_section.addWidget(self.content_widget, 1)
|
||||
|
||||
layout.addWidget(album_art)
|
||||
layout.addLayout(content_layout, 1) # Take most space
|
||||
layout.addLayout(action_layout)
|
||||
layout.addLayout(left_section, 1)
|
||||
layout.addWidget(self.download_btn)
|
||||
|
||||
def create_persistent_content(self, primary_info):
|
||||
"""Create both compact and expanded content with visibility control"""
|
||||
# Title row (always visible) with character limit and ellipsis
|
||||
title_text = primary_info['title']
|
||||
if len(title_text) > 50: # Character limit for long titles
|
||||
title_text = title_text[:47] + "..."
|
||||
|
||||
self.title_label = QLabel(title_text)
|
||||
self.title_label.setFont(QFont("Arial", 11, QFont.Weight.Bold)) # Reduced from 13px to 11px
|
||||
self.title_label.setStyleSheet("color: #ffffff;")
|
||||
self.title_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
|
||||
# Ensure text doesn't overflow the label
|
||||
self.title_label.setWordWrap(False)
|
||||
self.title_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
|
||||
|
||||
# Expand indicator
|
||||
self.expand_indicator = QLabel("⏵")
|
||||
self.expand_indicator.setFixedSize(16, 16)
|
||||
self.expand_indicator.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.expand_indicator.setStyleSheet("color: rgba(255, 255, 255, 0.6); font-size: 12px;")
|
||||
|
||||
# Quality badge (only visible when expanded)
|
||||
self.quality_badge = self._create_compact_quality_badge()
|
||||
self.quality_badge.hide() # Initially hidden
|
||||
|
||||
title_row = QHBoxLayout()
|
||||
title_row.setContentsMargins(0, 0, 0, 0)
|
||||
title_row.addWidget(self.title_label)
|
||||
title_row.addWidget(self.quality_badge)
|
||||
title_row.addWidget(self.expand_indicator)
|
||||
|
||||
# Expanded content (initially hidden)
|
||||
self.expanded_content = QWidget()
|
||||
expanded_layout = QVBoxLayout(self.expanded_content)
|
||||
expanded_layout.setContentsMargins(0, 0, 0, 0)
|
||||
expanded_layout.setSpacing(2) # Very tight spacing for dense layout
|
||||
|
||||
# Artist info
|
||||
self.artist_info = QLabel(primary_info['artist'])
|
||||
self.artist_info.setFont(QFont("Arial", 10, QFont.Weight.Normal)) # Slightly smaller font
|
||||
self.artist_info.setStyleSheet("color: rgba(179, 179, 179, 0.9);")
|
||||
|
||||
# File details
|
||||
details = []
|
||||
size_mb = self.search_result.size // (1024*1024)
|
||||
details.append(f"{size_mb}MB")
|
||||
|
||||
if self.search_result.duration:
|
||||
duration_mins = self.search_result.duration // 60
|
||||
duration_secs = self.search_result.duration % 60
|
||||
details.append(f"{duration_mins}:{duration_secs:02d}")
|
||||
|
||||
self.file_details = QLabel(" • ".join(details))
|
||||
self.file_details.setFont(QFont("Arial", 9)) # Smaller font for compactness
|
||||
self.file_details.setStyleSheet("color: rgba(136, 136, 136, 0.8);")
|
||||
|
||||
# User info and quality score in one compact row
|
||||
bottom_row = QHBoxLayout()
|
||||
bottom_row.setContentsMargins(0, 0, 0, 0)
|
||||
bottom_row.setSpacing(8)
|
||||
|
||||
self.user_info = QLabel(f"👤 {self.search_result.username}")
|
||||
self.user_info.setFont(QFont("Arial", 9, QFont.Weight.Medium)) # Smaller font
|
||||
self.user_info.setStyleSheet("color: rgba(29, 185, 84, 0.8);")
|
||||
|
||||
self.speed_indicator = self._create_compact_speed_indicator()
|
||||
|
||||
self.quality_score = QLabel(f"★{self.search_result.quality_score:.1f}")
|
||||
self.quality_score.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.quality_score.setFont(QFont("Arial", 8, QFont.Weight.Bold)) # Smaller font
|
||||
self.quality_score.setFixedSize(32, 16) # Smaller size
|
||||
|
||||
if self.search_result.quality_score >= 0.9:
|
||||
self.quality_score.setStyleSheet("color: #1db954; background: rgba(29, 185, 84, 0.15); border-radius: 8px;")
|
||||
elif self.search_result.quality_score >= 0.7:
|
||||
self.quality_score.setStyleSheet("color: #ffa500; background: rgba(255, 165, 0, 0.15); border-radius: 8px;")
|
||||
else:
|
||||
self.quality_score.setStyleSheet("color: #e22134; background: rgba(226, 33, 52, 0.15); border-radius: 8px;")
|
||||
|
||||
bottom_row.addWidget(self.user_info)
|
||||
bottom_row.addWidget(self.speed_indicator)
|
||||
bottom_row.addStretch()
|
||||
bottom_row.addWidget(self.quality_score)
|
||||
|
||||
# Add all expanded content
|
||||
expanded_layout.addWidget(self.artist_info)
|
||||
expanded_layout.addWidget(self.file_details)
|
||||
expanded_layout.addLayout(bottom_row)
|
||||
|
||||
# Initially hide expanded content
|
||||
self.expanded_content.hide()
|
||||
|
||||
# Add to main layout
|
||||
self.content_layout.addLayout(title_row)
|
||||
self.content_layout.addWidget(self.expanded_content)
|
||||
|
||||
def update_expanded_state(self):
|
||||
"""Update UI based on expanded state without recreating widgets"""
|
||||
if self.is_expanded:
|
||||
self.expand_indicator.setText("⏷")
|
||||
self.quality_badge.show()
|
||||
self.expanded_content.show()
|
||||
else:
|
||||
self.expand_indicator.setText("⏵")
|
||||
self.quality_badge.hide()
|
||||
self.expanded_content.hide()
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
"""Handle mouse clicks to toggle expand/collapse"""
|
||||
# Only respond to left clicks and avoid clicks on the download button
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
# Check if click is on download button (more precise detection)
|
||||
button_rect = self.download_btn.geometry()
|
||||
# Add some padding to the button area to be more forgiving
|
||||
button_rect.adjust(-5, -5, 5, 5)
|
||||
if not button_rect.contains(event.pos()):
|
||||
# Emit signal to parent to handle accordion behavior
|
||||
self.expansion_requested.emit(self)
|
||||
super().mousePressEvent(event)
|
||||
|
||||
def set_expanded(self, expanded, animate=True):
|
||||
"""Set expanded state externally (called by parent for accordion behavior)"""
|
||||
if self.is_expanded == expanded:
|
||||
return # No change needed
|
||||
|
||||
self.is_expanded = expanded
|
||||
|
||||
if animate:
|
||||
self._animate_to_state()
|
||||
else:
|
||||
# Immediate state change without animation
|
||||
if self.is_expanded:
|
||||
self.setFixedHeight(self.expanded_height)
|
||||
else:
|
||||
self.setFixedHeight(self.compact_height)
|
||||
self.update_expanded_state()
|
||||
|
||||
def toggle_expanded(self):
|
||||
"""Toggle between compact and expanded states with animation"""
|
||||
self.set_expanded(not self.is_expanded, animate=True)
|
||||
|
||||
def _animate_to_state(self):
|
||||
"""Animate to the current expanded state"""
|
||||
from PyQt6.QtCore import QPropertyAnimation, QEasingCurve
|
||||
|
||||
# Start height animation first
|
||||
self.animation = QPropertyAnimation(self, b"minimumHeight")
|
||||
self.animation.setDuration(200) # Slightly faster animation for better responsiveness
|
||||
self.animation.setEasingCurve(QEasingCurve.Type.OutCubic)
|
||||
|
||||
if self.is_expanded:
|
||||
# Expand animation
|
||||
self.animation.setStartValue(self.compact_height)
|
||||
self.animation.setEndValue(self.expanded_height)
|
||||
# Show content immediately for expand (feels more responsive)
|
||||
self.update_expanded_state()
|
||||
else:
|
||||
# Collapse animation
|
||||
self.animation.setStartValue(self.expanded_height)
|
||||
self.animation.setEndValue(self.compact_height)
|
||||
# Hide content immediately for collapse (cleaner look)
|
||||
self.update_expanded_state()
|
||||
|
||||
# Update fixed height when animation completes
|
||||
self.animation.finished.connect(self._finalize_height)
|
||||
self.animation.start()
|
||||
|
||||
def _finalize_height(self):
|
||||
"""Set final height after animation completes"""
|
||||
if self.is_expanded:
|
||||
self.setFixedHeight(self.expanded_height)
|
||||
else:
|
||||
self.setFixedHeight(self.compact_height)
|
||||
|
||||
# Force parent layout update to ensure proper spacing
|
||||
if self.parent():
|
||||
self.parent().updateGeometry()
|
||||
|
||||
def sizeHint(self):
|
||||
"""Provide consistent size hint for layout calculations"""
|
||||
if self.is_expanded:
|
||||
return self.size().expandedTo(self.minimumSize()).boundedTo(self.maximumSize())
|
||||
else:
|
||||
return self.size().expandedTo(self.minimumSize()).boundedTo(self.maximumSize())
|
||||
|
||||
def _extract_song_info(self):
|
||||
"""Extract song title and artist from filename"""
|
||||
|
|
@ -800,25 +928,26 @@ class DownloadQueue(QFrame):
|
|||
""")
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(16, 12, 16, 16) # Professional spacing - less top padding
|
||||
layout.setSpacing(12) # Reduced spacing for tighter layout
|
||||
layout.setContentsMargins(16, 8, 16, 16) # Reduced top padding
|
||||
layout.setSpacing(8) # Tighter spacing for more compact layout
|
||||
|
||||
# Header
|
||||
header_layout = QHBoxLayout()
|
||||
header_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
title_label = QLabel("Download Queue")
|
||||
title_label.setFont(QFont("Segoe UI", 14, QFont.Weight.Bold))
|
||||
title_label.setStyleSheet("""
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
font-weight: 600;
|
||||
padding: 4px 0;
|
||||
padding: 0;
|
||||
""")
|
||||
|
||||
queue_count = QLabel("Empty")
|
||||
queue_count.setFont(QFont("Segoe UI", 10))
|
||||
queue_count.setStyleSheet("""
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
padding: 4px 0;
|
||||
padding: 0;
|
||||
""")
|
||||
|
||||
header_layout.addWidget(title_label)
|
||||
|
|
@ -926,15 +1055,15 @@ class DownloadsPage(QWidget):
|
|||
self.search_results = []
|
||||
self.download_items = [] # Track download items for the queue
|
||||
self.displayed_results = 0 # Track how many results are currently displayed
|
||||
self.results_per_page = 20 # Show 20 results at a time
|
||||
self.results_per_page = 15 # Show 15 results at a time
|
||||
self.is_loading_more = False # Prevent multiple simultaneous loads
|
||||
self.currently_expanded_item = None # Track which item is currently expanded
|
||||
|
||||
# Download status polling timer
|
||||
self.download_status_timer = QTimer()
|
||||
self.download_status_timer.timeout.connect(self.update_download_status)
|
||||
self.download_status_timer.start(2000) # Poll every 2 seconds
|
||||
|
||||
# Initialize load more button (will be added to layout in setup_ui)
|
||||
self.load_more_btn = None
|
||||
|
||||
self.setup_ui()
|
||||
|
||||
|
|
@ -948,26 +1077,35 @@ class DownloadsPage(QWidget):
|
|||
""")
|
||||
|
||||
main_layout = QVBoxLayout(self)
|
||||
main_layout.setContentsMargins(24, 16, 24, 20) # Professional spacing using 8px grid
|
||||
main_layout.setSpacing(16)
|
||||
# Responsive margins that adapt to window size
|
||||
main_layout.setContentsMargins(16, 12, 16, 16) # Reduced for tighter responsive feel
|
||||
main_layout.setSpacing(12) # Consistent 12px spacing
|
||||
|
||||
# Elegant Header
|
||||
header = self.create_elegant_header()
|
||||
main_layout.addWidget(header)
|
||||
|
||||
# Main Content Area - Prioritize Search Results
|
||||
content_splitter = QHBoxLayout()
|
||||
content_splitter.setSpacing(16)
|
||||
# Main Content Area with responsive splitter
|
||||
content_splitter = QSplitter(Qt.Orientation.Horizontal)
|
||||
content_splitter.setChildrenCollapsible(False) # Prevent panels from collapsing completely
|
||||
|
||||
# LEFT: Search & Results (70% of space)
|
||||
# LEFT: Search & Results section
|
||||
search_and_results = self.create_search_and_results_section()
|
||||
content_splitter.addWidget(search_and_results, 7)
|
||||
search_and_results.setMinimumWidth(400) # Minimum width for usability
|
||||
content_splitter.addWidget(search_and_results)
|
||||
|
||||
# RIGHT: Collapsible Controls Panel (30% of space)
|
||||
# RIGHT: Controls Panel
|
||||
controls_panel = self.create_collapsible_controls_panel()
|
||||
content_splitter.addWidget(controls_panel, 3)
|
||||
controls_panel.setMinimumWidth(280) # Minimum width for controls
|
||||
controls_panel.setMaximumWidth(400) # Maximum width to prevent overgrowth
|
||||
content_splitter.addWidget(controls_panel)
|
||||
|
||||
main_layout.addLayout(content_splitter)
|
||||
# Set initial splitter proportions (roughly 70/30)
|
||||
content_splitter.setSizes([700, 300])
|
||||
content_splitter.setStretchFactor(0, 1) # Search results gets priority for extra space
|
||||
content_splitter.setStretchFactor(1, 0) # Controls panel stays fixed width when possible
|
||||
|
||||
main_layout.addWidget(content_splitter)
|
||||
|
||||
# Optional: Compact status bar at bottom
|
||||
status_bar = self.create_compact_status_bar()
|
||||
|
|
@ -976,7 +1114,9 @@ class DownloadsPage(QWidget):
|
|||
def create_elegant_header(self):
|
||||
"""Create an elegant, minimal header"""
|
||||
header = QFrame()
|
||||
header.setFixedHeight(100) # Increased height to prevent text clipping
|
||||
header.setMinimumHeight(80) # Minimum height, can grow if needed
|
||||
header.setMaximumHeight(120) # Maximum to prevent overgrowth
|
||||
header.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
|
||||
header.setStyleSheet("""
|
||||
QFrame {
|
||||
background: transparent;
|
||||
|
|
@ -985,8 +1125,8 @@ class DownloadsPage(QWidget):
|
|||
""")
|
||||
|
||||
layout = QHBoxLayout(header)
|
||||
layout.setContentsMargins(24, 20, 24, 20) # More balanced padding
|
||||
layout.setSpacing(16)
|
||||
layout.setContentsMargins(16, 12, 16, 12) # Responsive padding consistent with main layout
|
||||
layout.setSpacing(12) # Consistent spacing
|
||||
|
||||
# Icon and Title
|
||||
title_section = QVBoxLayout()
|
||||
|
|
@ -1031,8 +1171,8 @@ class DownloadsPage(QWidget):
|
|||
""")
|
||||
|
||||
layout = QVBoxLayout(section)
|
||||
layout.setContentsMargins(24, 20, 24, 20) # Professional spacing consistent with main layout
|
||||
layout.setSpacing(16)
|
||||
layout.setContentsMargins(16, 12, 16, 12) # Responsive spacing consistent with main layout
|
||||
layout.setSpacing(12) # Consistent 12px spacing
|
||||
|
||||
# Elegant Search Bar
|
||||
search_container = self.create_elegant_search_bar()
|
||||
|
|
@ -1063,8 +1203,8 @@ class DownloadsPage(QWidget):
|
|||
""")
|
||||
|
||||
results_layout = QVBoxLayout(results_container)
|
||||
results_layout.setContentsMargins(16, 12, 16, 16) # Consistent with card padding
|
||||
results_layout.setSpacing(8)
|
||||
results_layout.setContentsMargins(12, 8, 12, 12) # Tighter responsive spacing
|
||||
results_layout.setSpacing(8) # Consistent small spacing for tight layout
|
||||
|
||||
# Results header
|
||||
results_header = QLabel("Search Results")
|
||||
|
|
@ -1112,6 +1252,10 @@ class DownloadsPage(QWidget):
|
|||
self.search_results_layout.addStretch()
|
||||
self.search_results_scroll.setWidget(self.search_results_widget)
|
||||
|
||||
# Connect scroll detection for automatic loading
|
||||
scroll_bar = self.search_results_scroll.verticalScrollBar()
|
||||
scroll_bar.valueChanged.connect(self.on_scroll_changed)
|
||||
|
||||
results_layout.addWidget(self.search_results_scroll)
|
||||
layout.addWidget(results_container, 1) # This takes all remaining space
|
||||
|
||||
|
|
@ -1132,13 +1276,14 @@ class DownloadsPage(QWidget):
|
|||
""")
|
||||
|
||||
layout = QHBoxLayout(container)
|
||||
layout.setContentsMargins(24, 16, 24, 16) # Professional spacing using 8px grid
|
||||
layout.setSpacing(12)
|
||||
layout.setContentsMargins(16, 12, 16, 12) # Consistent responsive spacing
|
||||
layout.setSpacing(12) # Consistent spacing throughout
|
||||
|
||||
# Search input with enhanced styling
|
||||
self.search_input = QLineEdit()
|
||||
self.search_input.setPlaceholderText("Search for music... (e.g., 'Virtual Mage', 'Queen Bohemian Rhapsody')")
|
||||
self.search_input.setFixedHeight(40)
|
||||
self.search_input.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) # Responsive width
|
||||
self.search_input.returnPressed.connect(self.perform_search)
|
||||
self.search_input.setStyleSheet("""
|
||||
QLineEdit {
|
||||
|
|
@ -1209,8 +1354,8 @@ class DownloadsPage(QWidget):
|
|||
""")
|
||||
|
||||
layout = QVBoxLayout(panel)
|
||||
layout.setContentsMargins(16, 16, 16, 16)
|
||||
layout.setSpacing(12)
|
||||
layout.setContentsMargins(12, 12, 12, 12) # Consistent responsive spacing
|
||||
layout.setSpacing(12) # Consistent spacing throughout
|
||||
|
||||
# Panel header
|
||||
header = QLabel("Download Manager")
|
||||
|
|
@ -1418,31 +1563,7 @@ class DownloadsPage(QWidget):
|
|||
self.search_results_layout = QVBoxLayout(self.search_results_widget)
|
||||
self.search_results_layout.setSpacing(5)
|
||||
|
||||
# Create Load More button and add to search results layout
|
||||
self.load_more_btn = QPushButton("📚 Load More Results")
|
||||
self.load_more_btn.setFixedHeight(40)
|
||||
self.load_more_btn.clicked.connect(self.show_more_results)
|
||||
self.load_more_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
stop:0 rgba(29, 185, 84, 0.8),
|
||||
stop:1 rgba(25, 160, 75, 0.9));
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
color: #000000;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin: 8px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
stop:0 rgba(30, 215, 96, 0.9),
|
||||
stop:1 rgba(25, 180, 80, 1.0));
|
||||
}
|
||||
""")
|
||||
self.load_more_btn.hide() # Initially hidden
|
||||
|
||||
self.search_results_layout.addWidget(self.load_more_btn)
|
||||
# Just add stretch - no load more button needed with auto-scroll
|
||||
self.search_results_layout.addStretch()
|
||||
self.search_results_scroll.setWidget(self.search_results_widget)
|
||||
|
||||
|
|
@ -1473,8 +1594,8 @@ class DownloadsPage(QWidget):
|
|||
# Clear previous results and reset state
|
||||
self.clear_search_results()
|
||||
self.displayed_results = 0
|
||||
if self.load_more_btn:
|
||||
self.load_more_btn.hide()
|
||||
self.is_loading_more = False
|
||||
self.currently_expanded_item = None # Reset expanded state
|
||||
|
||||
# Enhanced searching state with animation
|
||||
self.search_btn.setText("🔍 Searching...")
|
||||
|
|
@ -1536,70 +1657,79 @@ class DownloadsPage(QWidget):
|
|||
|
||||
def on_search_results_partial(self, new_results, total_count):
|
||||
"""Handle progressive search results as they come in"""
|
||||
# Sort new results by quality score
|
||||
# Sort new results by quality score and add to master list
|
||||
new_results.sort(key=lambda x: x.quality_score, reverse=True)
|
||||
|
||||
# Add new result items to UI immediately
|
||||
for result in new_results:
|
||||
result_item = SearchResultItem(result)
|
||||
result_item.download_requested.connect(self.start_download)
|
||||
# Insert before the Load More button (which is before the stretch)
|
||||
insert_position = self.search_results_layout.count() - 2
|
||||
self.search_results_layout.insertWidget(insert_position, result_item)
|
||||
# Add to master search results list (don't display all immediately)
|
||||
if not hasattr(self, '_temp_search_results'):
|
||||
self._temp_search_results = []
|
||||
|
||||
# Update displayed count
|
||||
self.displayed_results += len(new_results)
|
||||
self._temp_search_results.extend(new_results)
|
||||
|
||||
# Only display up to the current page limit
|
||||
remaining_slots = self.results_per_page - self.displayed_results
|
||||
if remaining_slots > 0:
|
||||
results_to_show = new_results[:remaining_slots]
|
||||
|
||||
# Temporarily disable layout updates for smoother batch loading
|
||||
self.search_results_widget.setUpdatesEnabled(False)
|
||||
|
||||
for result in results_to_show:
|
||||
result_item = SearchResultItem(result)
|
||||
result_item.download_requested.connect(self.start_download)
|
||||
result_item.expansion_requested.connect(self.handle_expansion_request)
|
||||
# Insert before the stretch
|
||||
insert_position = self.search_results_layout.count() - 1
|
||||
self.search_results_layout.insertWidget(insert_position, result_item)
|
||||
|
||||
# Re-enable updates and force layout refresh
|
||||
self.search_results_widget.setUpdatesEnabled(True)
|
||||
self.search_results_widget.updateGeometry()
|
||||
self.search_results_layout.update()
|
||||
self.search_results_scroll.updateGeometry()
|
||||
|
||||
self.displayed_results += len(results_to_show)
|
||||
|
||||
# Update status message with real-time feedback
|
||||
self.update_search_status(f"✨ Found {total_count} results so far • Still searching...", "#1db954")
|
||||
|
||||
# If we have enough results, show the Load More button
|
||||
if total_count >= self.results_per_page and self.load_more_btn:
|
||||
# Don't show Load More yet during live search - wait for completion
|
||||
pass
|
||||
if self.displayed_results < self.results_per_page:
|
||||
self.update_search_status(f"✨ Found {total_count} results so far • Showing first {self.displayed_results}", "#1db954")
|
||||
else:
|
||||
self.update_search_status(f"✨ Found {total_count} results so far • Showing first {self.results_per_page} (scroll for more)", "#1db954")
|
||||
|
||||
def on_search_completed(self, results):
|
||||
self.search_btn.setText("🔍 Search")
|
||||
self.search_btn.setEnabled(True)
|
||||
|
||||
if not results:
|
||||
# Only show no results if we haven't already displayed some via progressive loading
|
||||
# Use temp results from progressive loading if available, otherwise use results
|
||||
if hasattr(self, '_temp_search_results') and self._temp_search_results:
|
||||
self.search_results = self._temp_search_results
|
||||
del self._temp_search_results # Clean up temp storage
|
||||
else:
|
||||
self.search_results = results or []
|
||||
|
||||
total_results = len(self.search_results)
|
||||
|
||||
if total_results == 0:
|
||||
if self.displayed_results == 0:
|
||||
self.update_search_status("😔 No results found • Try a different search term or artist name", "#ffa500")
|
||||
else:
|
||||
# Search completed with some results already shown
|
||||
self.update_search_status(f"✨ Search completed • Found {self.displayed_results} total results", "#1db954")
|
||||
return
|
||||
|
||||
# Store all results for pagination
|
||||
self.search_results = results
|
||||
|
||||
# If we already have results from progressive loading, just finalize the status
|
||||
if self.displayed_results > 0:
|
||||
total_results = len(results)
|
||||
# Update status based on whether there are more results to load
|
||||
if self.displayed_results < total_results:
|
||||
remaining = total_results - self.displayed_results
|
||||
|
||||
if remaining > 0:
|
||||
# Show Load More button for remaining results
|
||||
self.update_search_status(f"✨ Showing {self.displayed_results} of {total_results} results • {remaining} more available", "#1db954")
|
||||
if self.load_more_btn:
|
||||
self.load_more_btn.show()
|
||||
self.load_more_btn.setText(f"📚 Load {min(remaining, self.results_per_page)} More Results")
|
||||
else:
|
||||
# All results already displayed
|
||||
self.update_search_status(f"✨ Showing all {total_results} results", "#1db954")
|
||||
if self.load_more_btn:
|
||||
self.load_more_btn.hide()
|
||||
self.update_search_status(f"✨ Found {total_results} results • Showing first {self.displayed_results} (scroll down for {remaining} more)", "#1db954")
|
||||
else:
|
||||
# Fallback: No progressive results, show first page normally
|
||||
self.search_results.sort(key=lambda x: x.quality_score, reverse=True)
|
||||
self.clear_search_results()
|
||||
self.displayed_results = 0
|
||||
self.show_more_results()
|
||||
self.update_search_status(f"✨ Search completed • Showing all {total_results} results", "#1db954")
|
||||
|
||||
# If we have no displayed results yet, show the first batch
|
||||
if self.displayed_results == 0 and total_results > 0:
|
||||
self.load_more_results()
|
||||
|
||||
def clear_search_results(self):
|
||||
"""Clear all search result items from the layout"""
|
||||
# Remove all SearchResultItem widgets (but keep Load More button and stretch)
|
||||
# Remove all SearchResultItem widgets (but keep stretch)
|
||||
items_to_remove = []
|
||||
for i in range(self.search_results_layout.count()):
|
||||
item = self.search_results_layout.itemAt(i)
|
||||
|
|
@ -1610,60 +1740,80 @@ class DownloadsPage(QWidget):
|
|||
self.search_results_layout.removeWidget(widget)
|
||||
widget.deleteLater()
|
||||
|
||||
def show_more_results(self):
|
||||
"""Show the next batch of search results"""
|
||||
if not self.search_results:
|
||||
def on_scroll_changed(self, value):
|
||||
"""Handle scroll changes to implement lazy loading"""
|
||||
if self.is_loading_more or not self.search_results:
|
||||
return
|
||||
|
||||
scroll_bar = self.search_results_scroll.verticalScrollBar()
|
||||
|
||||
# Check if we're near the bottom (90% scrolled)
|
||||
if scroll_bar.maximum() > 0:
|
||||
scroll_percentage = value / scroll_bar.maximum()
|
||||
|
||||
if scroll_percentage >= 0.9 and self.displayed_results < len(self.search_results):
|
||||
self.load_more_results()
|
||||
|
||||
def load_more_results(self):
|
||||
"""Load the next batch of search results"""
|
||||
if self.is_loading_more or not self.search_results:
|
||||
return
|
||||
|
||||
self.is_loading_more = True
|
||||
|
||||
# Calculate how many more results to show
|
||||
start_index = self.displayed_results
|
||||
end_index = min(start_index + self.results_per_page, len(self.search_results))
|
||||
|
||||
# Only add results that haven't been displayed yet
|
||||
# (Progressive loading may have already shown some results)
|
||||
currently_displayed = self.count_displayed_results()
|
||||
# Temporarily disable layout updates for smoother batch loading
|
||||
self.search_results_widget.setUpdatesEnabled(False)
|
||||
|
||||
# Add result items to UI
|
||||
for i in range(max(start_index, currently_displayed), end_index):
|
||||
if i < len(self.search_results):
|
||||
result = self.search_results[i]
|
||||
result_item = SearchResultItem(result)
|
||||
result_item.download_requested.connect(self.start_download)
|
||||
# Insert before the Load More button (which is before the stretch)
|
||||
insert_position = self.search_results_layout.count() - 2
|
||||
self.search_results_layout.insertWidget(insert_position, result_item)
|
||||
for i in range(start_index, end_index):
|
||||
result = self.search_results[i]
|
||||
result_item = SearchResultItem(result)
|
||||
result_item.download_requested.connect(self.start_download)
|
||||
result_item.expansion_requested.connect(self.handle_expansion_request)
|
||||
# Insert before the stretch (which is always last)
|
||||
insert_position = self.search_results_layout.count() - 1
|
||||
self.search_results_layout.insertWidget(insert_position, result_item)
|
||||
|
||||
# Re-enable updates and force layout refresh
|
||||
self.search_results_widget.setUpdatesEnabled(True)
|
||||
self.search_results_widget.updateGeometry()
|
||||
self.search_results_layout.update()
|
||||
|
||||
# Force scroll area to recognize new content size
|
||||
self.search_results_scroll.updateGeometry()
|
||||
|
||||
# Update displayed count
|
||||
self.displayed_results = end_index
|
||||
|
||||
# Update status and Load More button
|
||||
self.update_load_more_status()
|
||||
|
||||
def count_displayed_results(self):
|
||||
"""Count how many SearchResultItem widgets are currently displayed"""
|
||||
count = 0
|
||||
for i in range(self.search_results_layout.count()):
|
||||
item = self.search_results_layout.itemAt(i)
|
||||
if item and item.widget() and isinstance(item.widget(), SearchResultItem):
|
||||
count += 1
|
||||
return count
|
||||
|
||||
def update_load_more_status(self):
|
||||
"""Update status message and Load More button based on current state"""
|
||||
if not self.search_results:
|
||||
return
|
||||
|
||||
# Update status
|
||||
total_results = len(self.search_results)
|
||||
if self.displayed_results >= total_results:
|
||||
self.update_search_status(f"✨ Showing all {total_results} results by quality", "#1db954")
|
||||
if self.load_more_btn:
|
||||
self.load_more_btn.hide()
|
||||
self.update_search_status(f"✨ Showing all {total_results} results", "#1db954")
|
||||
else:
|
||||
remaining = total_results - self.displayed_results
|
||||
self.update_search_status(f"✨ Showing {self.displayed_results} of {total_results} results • {remaining} more available", "#1db954")
|
||||
if self.load_more_btn:
|
||||
self.load_more_btn.show()
|
||||
self.load_more_btn.setText(f"📚 Load {min(remaining, self.results_per_page)} More Results")
|
||||
self.update_search_status(f"✨ Showing {self.displayed_results} of {total_results} results (scroll for {remaining} more)", "#1db954")
|
||||
|
||||
self.is_loading_more = False
|
||||
|
||||
def handle_expansion_request(self, requesting_item):
|
||||
"""Handle accordion-style expansion where only one item can be expanded at a time"""
|
||||
# If there's a currently expanded item and it's not the requesting item, collapse it
|
||||
if self.currently_expanded_item and self.currently_expanded_item != requesting_item:
|
||||
self.currently_expanded_item.set_expanded(False, animate=True)
|
||||
|
||||
# Toggle the requesting item
|
||||
new_expanded_state = not requesting_item.is_expanded
|
||||
requesting_item.set_expanded(new_expanded_state, animate=True)
|
||||
|
||||
# Update tracking
|
||||
if new_expanded_state:
|
||||
self.currently_expanded_item = requesting_item
|
||||
else:
|
||||
self.currently_expanded_item = None
|
||||
|
||||
def on_search_failed(self, error_msg):
|
||||
self.search_btn.setText("🔍 Search")
|
||||
|
|
|
|||
Loading…
Reference in a new issue