Fix some data ingestion bugs; #199 made most of the can_* functions dependent on the version
This commit is contained in:
1
setup.py
1
setup.py
@@ -63,6 +63,7 @@ setup(
|
|||||||
"python-Levenshtein",
|
"python-Levenshtein",
|
||||||
"python-mpv",
|
"python-mpv",
|
||||||
"requests",
|
"requests",
|
||||||
|
"semver",
|
||||||
],
|
],
|
||||||
extras_require={
|
extras_require={
|
||||||
"keyring": ["keyring"],
|
"keyring": ["keyring"],
|
||||||
|
@@ -572,7 +572,10 @@ class FilesystemAdapter(CachingAdapter):
|
|||||||
return_val = db_album
|
return_val = db_album
|
||||||
|
|
||||||
elif data_key == KEYS.ALBUMS:
|
elif data_key == KEYS.ALBUMS:
|
||||||
albums = [self._do_ingest_new_data(KEYS.ALBUM, a.id, a) for a in data]
|
albums = [
|
||||||
|
self._do_ingest_new_data(KEYS.ALBUM, a.id, a, partial=True)
|
||||||
|
for a in data
|
||||||
|
]
|
||||||
album_query_result, created = models.AlbumQueryResult.get_or_create(
|
album_query_result, created = models.AlbumQueryResult.get_or_create(
|
||||||
query_hash=param, defaults={"query_hash": param, "albums": albums}
|
query_hash=param, defaults={"query_hash": param, "albums": albums}
|
||||||
)
|
)
|
||||||
@@ -617,7 +620,7 @@ class FilesystemAdapter(CachingAdapter):
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
"albums": [
|
"albums": [
|
||||||
self._do_ingest_new_data(KEYS.ALBUM, a.id, a)
|
self._do_ingest_new_data(KEYS.ALBUM, a.id, a, partial=True)
|
||||||
for a in artist.albums or []
|
for a in artist.albums or []
|
||||||
],
|
],
|
||||||
"_artist_image_url": (
|
"_artist_image_url": (
|
||||||
|
@@ -24,6 +24,7 @@ from typing import (
|
|||||||
from urllib.parse import urlencode, urlparse
|
from urllib.parse import urlencode, urlparse
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
import semver
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
from .api_objects import Directory, Response
|
from .api_objects import Directory, Response
|
||||||
@@ -209,6 +210,7 @@ class SubsonicAdapter(Adapter):
|
|||||||
# TODO (#112): support XML?
|
# TODO (#112): support XML?
|
||||||
|
|
||||||
_ping_process: Optional[multiprocessing.Process] = None
|
_ping_process: Optional[multiprocessing.Process] = None
|
||||||
|
_version = multiprocessing.Array("c", 20)
|
||||||
_offline_mode = False
|
_offline_mode = False
|
||||||
|
|
||||||
def initial_sync(self):
|
def initial_sync(self):
|
||||||
@@ -265,24 +267,66 @@ class SubsonicAdapter(Adapter):
|
|||||||
# TODO (#199) make these way smarter
|
# TODO (#199) make these way smarter
|
||||||
can_get_playlists = True
|
can_get_playlists = True
|
||||||
can_get_playlist_details = True
|
can_get_playlist_details = True
|
||||||
can_create_playlist = True
|
|
||||||
can_update_playlist = True
|
|
||||||
can_delete_playlist = True
|
|
||||||
can_get_cover_art_uri = True
|
can_get_cover_art_uri = True
|
||||||
can_get_song_uri = True
|
can_get_song_uri = True
|
||||||
can_stream = True
|
can_stream = True
|
||||||
can_get_song_details = True
|
|
||||||
can_scrobble_song = True
|
|
||||||
can_get_artists = True
|
|
||||||
can_get_artist = True
|
|
||||||
can_get_ignored_articles = True
|
can_get_ignored_articles = True
|
||||||
can_get_albums = True
|
|
||||||
can_get_album = True
|
can_get_album = True
|
||||||
can_get_directory = True
|
can_get_directory = True
|
||||||
can_get_genres = True
|
|
||||||
can_get_play_queue = True
|
# TODO Consider just requiring the server to implement at least 1.8.0
|
||||||
can_save_play_queue = True
|
def version_at_least(self, version: str) -> bool:
|
||||||
can_search = True
|
if not self._version.value:
|
||||||
|
return False
|
||||||
|
return semver.VersionInfo.parse(self._version.value.decode()) >= version
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_create_playlist(self) -> bool:
|
||||||
|
return self.version_at_least("1.2.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_delete_playlist(self) -> bool:
|
||||||
|
return self.version_at_least("1.2.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_get_albums(self) -> bool:
|
||||||
|
return self.version_at_least("1.8.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_get_artists(self) -> bool:
|
||||||
|
return self.version_at_least("1.8.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_get_artist(self) -> bool:
|
||||||
|
return self.version_at_least("1.8.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_get_genres(self) -> bool:
|
||||||
|
return self.version_at_least("1.9.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_get_play_queue(self) -> bool:
|
||||||
|
return self.version_at_least("1.12.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_save_play_queue(self) -> bool:
|
||||||
|
return self.version_at_least("1.12.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_get_song_details(self) -> bool:
|
||||||
|
return self.version_at_least("1.8.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_scrobble_song(self) -> bool:
|
||||||
|
return self.version_at_least("1.5.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_search(self) -> bool:
|
||||||
|
return self.version_at_least("1.8.0")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_update_playlist(self) -> bool:
|
||||||
|
return self.version_at_least("1.8.0")
|
||||||
|
|
||||||
_schemes = None
|
_schemes = None
|
||||||
|
|
||||||
@@ -412,12 +456,14 @@ class SubsonicAdapter(Adapter):
|
|||||||
if not subsonic_response:
|
if not subsonic_response:
|
||||||
raise ServerError(500, f"{url} returned invalid JSON.")
|
raise ServerError(500, f"{url} returned invalid JSON.")
|
||||||
|
|
||||||
if subsonic_response["status"] == "failed":
|
if subsonic_response["status"] != "ok":
|
||||||
raise ServerError(
|
raise ServerError(
|
||||||
subsonic_response["error"].get("code"),
|
subsonic_response["error"].get("code"),
|
||||||
subsonic_response["error"].get("message"),
|
subsonic_response["error"].get("message"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._version.value = subsonic_response["version"].encode()
|
||||||
|
|
||||||
logging.debug(f"Response from {url}: {subsonic_response}")
|
logging.debug(f"Response from {url}: {subsonic_response}")
|
||||||
return Response.from_dict(subsonic_response)
|
return Response.from_dict(subsonic_response)
|
||||||
|
|
||||||
@@ -538,11 +584,14 @@ class SubsonicAdapter(Adapter):
|
|||||||
def get_artist(self, artist_id: str) -> API.Artist:
|
def get_artist(self, artist_id: str) -> API.Artist:
|
||||||
artist = self._get_json(self._make_url("getArtist"), id=artist_id).artist
|
artist = self._get_json(self._make_url("getArtist"), id=artist_id).artist
|
||||||
assert artist, f"Error getting artist {artist_id}"
|
assert artist, f"Error getting artist {artist_id}"
|
||||||
try:
|
if self.version_at_least("1.11.0"):
|
||||||
artist_info = self._get_json(self._make_url("getArtistInfo2"), id=artist_id)
|
try:
|
||||||
artist.augment_with_artist_info(artist_info.artist_info)
|
artist_info = self._get_json(
|
||||||
except Exception:
|
self._make_url("getArtistInfo2"), id=artist_id
|
||||||
pass
|
)
|
||||||
|
artist.augment_with_artist_info(artist_info.artist_info)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
return artist
|
return artist
|
||||||
|
|
||||||
def get_ignored_articles(self) -> Set[str]:
|
def get_ignored_articles(self) -> Set[str]:
|
||||||
|
Reference in New Issue
Block a user