New SongView, UV & More (#6)

Honestly, I don't remember everything I've done in this branch.

Important things:
 - Started using UV for dependency / python version management
 - Fixed the stupid queue skipping bug (still can't believe it was a race condition)
 - New SongView widget that multiple screens share
 - New features on most views with songs!
   - Songs can be shared
   - Songs can be added to playlists
   - Songs can be rated
 - Upgraded my Navidrome server version & had to change some stuff for it

Co-authored-by: Jackson Hodge <jackson.d.hodge@jbhunt.com>
Reviewed-on: #6
This commit is contained in:
0x01FEandJackson Hodge committed 2026-03-04 11:30:52 -06:00
1 parent d3de6ee914
commit 2295af7b56
10 files changed
+763 -201

No files matched your search

+24 -3
View File
@@ -1,4 +1,5 @@
import requests
import logging
import urllib.parse
import SubSonic
@@ -7,7 +8,7 @@ import SubSonic
"""
Navidrome has some API endpoints that are not included in the SubSonic or OpenSubSonic standards.
Nor are they documented anywhere I can find, the NavidromeAPI class is a collection of methods to interact with this hidden API.
The endpoints are reverse engineered from observing requests made by the Navidrome WebUI.
The endpoints are reverse engineered from observing requests made by the Navidrome server webUI.
"""
class NavidromeAPI:
username: str
@@ -53,7 +54,6 @@ class NavidromeAPI:
}
response = requests.get(url + self._encodePayload(payload), headers=self.auth_header)
print(len(response.content))
return [SubSonic.Song(song_d) for song_d in response.json()]
@@ -94,4 +94,25 @@ class NavidromeAPI:
def isSongStarred(self, id: str) -> bool:
info = self.getSong(id)
return info[0]['starred']
logging.info(info)
return info[0].get('starred') if info[0].get('starred') else False
"""
A strange one. Used for reordering tracks on a playlist, since it's not a native SubSonic thing.
playlist_id (str): Id of the playlist you're updating
song_index (int): Track you want to move
insert_before_index (int): For example, if you want to move a track to the start of a playlist, this is 1.
RETURNS: index of the editting song (song_index)
"""
def playlistInsertTrackBefore(self, playlist_id: str, song_index: int, insert_before_index: int) -> int:
url = self.base_url + f'/api/playlist/{playlist_id}/tracks/{song_index}'
payload = {
"insert_before" : str(insert_before_index)
}
response = requests.put(url, headers=self.auth_header, json=payload)
return response['id']