Fix Navidrome playlist sync truncation, clarify discovery label
Navidrome fix: - createPlaylist and other write operations now use POST instead of GET. Large playlists (161+ tracks) exceeded URL length limits when all songId params were in the query string, causing silent truncation (e.g., only 6 of 161 tracks added). POST sends params as form body with no size limit. - Write operation timeout bumped to 30s (was 10s) - _WRITE_ENDPOINTS set defines which Subsonic endpoints use POST UX fix: - Mirrored playlist cards now show "161/161 discovered on Spotify" instead of just "161/161 discovered" — clarifies that discovery means metadata matching, not library ownership
This commit is contained in:
parent
a98108b3ed
commit
8e41feaade
2 changed files with 20 additions and 3 deletions
|
|
@ -301,8 +301,19 @@ class NavidromeClient:
|
||||||
'f': 'json' # Response format
|
'f': 'json' # Response format
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Subsonic endpoints that modify data — use POST to avoid URL length limits
|
||||||
|
_WRITE_ENDPOINTS = frozenset({
|
||||||
|
'createPlaylist', 'updatePlaylist', 'deletePlaylist',
|
||||||
|
'star', 'unstar', 'scrobble', 'setRating',
|
||||||
|
'createShare', 'updateShare', 'deleteShare',
|
||||||
|
'createUser', 'updateUser', 'deleteUser',
|
||||||
|
'createBookmark', 'deleteBookmark',
|
||||||
|
'startScan',
|
||||||
|
})
|
||||||
|
|
||||||
def _make_request(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
|
def _make_request(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
|
||||||
"""Make authenticated request to Navidrome Subsonic API"""
|
"""Make authenticated request to Navidrome Subsonic API.
|
||||||
|
Uses POST for write operations (avoids URL length limits with large playlists)."""
|
||||||
if not self.base_url or not self.username:
|
if not self.base_url or not self.username:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -314,7 +325,12 @@ class NavidromeClient:
|
||||||
auth_params.update(params)
|
auth_params.update(params)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(url, params=auth_params, timeout=10)
|
# Use POST for write operations to avoid URL length limits
|
||||||
|
# (e.g., createPlaylist with 161 songId params would exceed GET URL limits)
|
||||||
|
if endpoint in self._WRITE_ENDPOINTS:
|
||||||
|
response = requests.post(url, data=auth_params, timeout=30)
|
||||||
|
else:
|
||||||
|
response = requests.get(url, params=auth_params, timeout=10)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
|
||||||
|
|
@ -57586,7 +57586,8 @@ function renderMirroredCard(p, container) {
|
||||||
let ratioHtml = '';
|
let ratioHtml = '';
|
||||||
if (disc > 0) {
|
if (disc > 0) {
|
||||||
const complete = disc >= tot;
|
const complete = disc >= tot;
|
||||||
ratioHtml = `<span class="discovery-ratio${complete ? ' complete' : ''}">${disc}/${tot} discovered</span>`;
|
const srcName = typeof currentMusicSourceName !== 'undefined' ? currentMusicSourceName : 'metadata';
|
||||||
|
ratioHtml = `<span class="discovery-ratio${complete ? ' complete' : ''}">${disc}/${tot} discovered on ${srcName}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue