61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
import requests
|
|
import urllib.parse
|
|
|
|
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.
|
|
"""
|
|
class NavidromeAPI:
|
|
username: str
|
|
password: str
|
|
base_url: str
|
|
|
|
auth_token: str
|
|
auth_header: dict = {}
|
|
|
|
def __init__(self, u: str, p: str, base_url: str):
|
|
self.username = u
|
|
self.password = p
|
|
self.base_url = base_url
|
|
|
|
self.auth_token = self._login()
|
|
self.auth_header['X-Nd-Authorization'] = f"Bearer {self.auth_token}"
|
|
|
|
def _encodePayload(self, payload: dict) -> str:
|
|
return urllib.parse.urlencode(payload, quote_via=urllib.parse.quote_plus)
|
|
|
|
def _login(self) -> str:
|
|
url = self.base_url + '/auth/login'
|
|
|
|
payload = {
|
|
'username': self.username,
|
|
'password': self.password
|
|
}
|
|
|
|
response = requests.post(url, json=payload)
|
|
|
|
j = response.json()
|
|
|
|
return j['token']
|
|
|
|
def getAllSongs(self, end: int, start: int, order: str = 'ASC', sort: str = 'title') -> list[SubSonic.Song]:
|
|
url = self.base_url + '/api/song?'
|
|
|
|
payload = {
|
|
"_end": end,
|
|
"_order": order,
|
|
"_sort": sort,
|
|
"_start": start
|
|
}
|
|
|
|
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()]
|
|
|
|
|