Got things to a good state that can be built off of
This commit is contained in:
3
Pipfile
3
Pipfile
@@ -11,7 +11,7 @@ flake8-comprehensions = "*"
|
|||||||
flake8-pep3101 = "*"
|
flake8-pep3101 = "*"
|
||||||
flake8-print = "*"
|
flake8-print = "*"
|
||||||
graphviz = "*"
|
graphviz = "*"
|
||||||
jedi = "*"
|
jedi = "<0.16"
|
||||||
lxml = "*"
|
lxml = "*"
|
||||||
mypy = "*"
|
mypy = "*"
|
||||||
pytest = "*"
|
pytest = "*"
|
||||||
@@ -19,7 +19,6 @@ pytest-cov = "*"
|
|||||||
rope = "*"
|
rope = "*"
|
||||||
rst2html5 = "*"
|
rst2html5 = "*"
|
||||||
sphinx = "*"
|
sphinx = "*"
|
||||||
sphinx-autodoc-typehints = "*"
|
|
||||||
sphinx-rtd-theme = "*"
|
sphinx-rtd-theme = "*"
|
||||||
termcolor = "*"
|
termcolor = "*"
|
||||||
yapf = "*"
|
yapf = "*"
|
||||||
|
16
Pipfile.lock
generated
16
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "1f998ec38046cff69f63ed51610a1ca33bef37635020695781f57684daa9da01"
|
"sha256": "ec62e729c70d9ce38576ae97cfdd88b0a006886cbca1fa4ff0160383e96453a6"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {
|
"requires": {
|
||||||
@@ -447,11 +447,11 @@
|
|||||||
},
|
},
|
||||||
"jedi": {
|
"jedi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:cd60c93b71944d628ccac47df9a60fec53150de53d42dc10a7fc4b5ba6aae798",
|
"sha256:1349c1e8c107095a55386628bb3b2a79422f3a2cab8381e34ce19909e0cf5064",
|
||||||
"sha256:df40c97641cb943661d2db4c33c2e1ff75d491189423249e989bcea4464f3030"
|
"sha256:e909527104a903606dd63bea6e8e888833f0ef087057829b89a18364a856f807"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.17.0"
|
"version": "==0.15.2"
|
||||||
},
|
},
|
||||||
"jinja2": {
|
"jinja2": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -694,14 +694,6 @@
|
|||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==3.0.3"
|
"version": "==3.0.3"
|
||||||
},
|
},
|
||||||
"sphinx-autodoc-typehints": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:27c9e6ef4f4451766ab8d08b2d8520933b97beb21c913f3df9ab2e59b56e6c6c",
|
|
||||||
"sha256:a6b3180167479aca2c4d1ed3b5cb044a70a76cccd6b38662d39288ebd9f0dff0"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==1.10.3"
|
|
||||||
},
|
|
||||||
"sphinx-rtd-theme": {
|
"sphinx-rtd-theme": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4",
|
"sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4",
|
||||||
|
@@ -286,6 +286,13 @@ def generate_class_for_type(type_name: str) -> str:
|
|||||||
indent_str = ' {}'
|
indent_str = ' {}'
|
||||||
if not has_properties:
|
if not has_properties:
|
||||||
code.append(indent_str.format('pass'))
|
code.append(indent_str.format('pass'))
|
||||||
|
else:
|
||||||
|
code.append('')
|
||||||
|
code.append(
|
||||||
|
indent_str.format(
|
||||||
|
'def get(self, key: str, default: Any = None) -> Any:'))
|
||||||
|
code.append(
|
||||||
|
indent_str.format(' return getattr(self, key, default)'))
|
||||||
|
|
||||||
return '\n'.join(code)
|
return '\n'.join(code)
|
||||||
|
|
||||||
@@ -304,7 +311,7 @@ with open(output_file, 'w+') as outfile:
|
|||||||
'from dataclasses import dataclass, field',
|
'from dataclasses import dataclass, field',
|
||||||
'from datetime import datetime',
|
'from datetime import datetime',
|
||||||
'from enum import Enum',
|
'from enum import Enum',
|
||||||
'from typing import List, Optional',
|
'from typing import Any, List, Optional',
|
||||||
'',
|
'',
|
||||||
'from sublime.server.api_object import APIObject',
|
'from sublime.server.api_object import APIObject',
|
||||||
*map(generate_class_for_type, output_order),
|
*map(generate_class_for_type, output_order),
|
||||||
|
@@ -34,7 +34,7 @@ release = f'v{sublime.__version__}'
|
|||||||
# ones.
|
# ones.
|
||||||
extensions = [
|
extensions = [
|
||||||
'sphinx.ext.autodoc',
|
'sphinx.ext.autodoc',
|
||||||
'sphinx_autodoc_typehints',
|
'sphinx.ext.autosectionlabel',
|
||||||
'sphinx.ext.intersphinx',
|
'sphinx.ext.intersphinx',
|
||||||
'sphinx.ext.mathjax',
|
'sphinx.ext.mathjax',
|
||||||
'sphinx.ext.viewcode',
|
'sphinx.ext.viewcode',
|
||||||
@@ -46,6 +46,10 @@ autodoc_default_options = {
|
|||||||
'show-inheritance': True,
|
'show-inheritance': True,
|
||||||
'special-members': '__init__',
|
'special-members': '__init__',
|
||||||
}
|
}
|
||||||
|
autosectionlabel_prefix_document = True
|
||||||
|
intersphinx_mapping = {
|
||||||
|
'python': ('https://docs.python.org/3', None),
|
||||||
|
}
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
ignore = E402, W503, ANN002, ANN003, ANN101, ANN102, ANN204
|
ignore = E402, W503, ANN002, ANN003, ANN101, ANN102, ANN204
|
||||||
exclude = .git,__pycache__,build,dist,flatpak
|
exclude = .git,__pycache__,build,dist,flatpak
|
||||||
suppress-none-returning = True
|
suppress-none-returning = True
|
||||||
|
suppress-dummy-args = True
|
||||||
application-import-names = sublime
|
application-import-names = sublime
|
||||||
import-order-style = edited
|
import-order-style = edited
|
||||||
|
|
||||||
|
@@ -451,7 +451,7 @@ class SublimeMusicApp(Gtk.Application):
|
|||||||
@dbus_propagate()
|
@dbus_propagate()
|
||||||
def on_refresh_window(
|
def on_refresh_window(
|
||||||
self,
|
self,
|
||||||
_: Any,
|
_,
|
||||||
state_updates: Dict[str, Any],
|
state_updates: Dict[str, Any],
|
||||||
force: bool = False,
|
force: bool = False,
|
||||||
):
|
):
|
||||||
@@ -686,7 +686,7 @@ class SublimeMusicApp(Gtk.Application):
|
|||||||
# Update the window according to the new server configuration.
|
# Update the window according to the new server configuration.
|
||||||
self.update_window()
|
self.update_window()
|
||||||
|
|
||||||
def on_stack_change(self, stack: Gtk.Stack, _: Any):
|
def on_stack_change(self, stack: Gtk.Stack, _):
|
||||||
self.app_config.state.current_tab = stack.get_visible_child_name()
|
self.app_config.state.current_tab = stack.get_visible_child_name()
|
||||||
self.update_window()
|
self.update_window()
|
||||||
|
|
||||||
@@ -815,7 +815,7 @@ class SublimeMusicApp(Gtk.Application):
|
|||||||
self.update_window()
|
self.update_window()
|
||||||
|
|
||||||
@dbus_propagate()
|
@dbus_propagate()
|
||||||
def on_volume_change(self, _: Any, value: float):
|
def on_volume_change(self, _, value: float):
|
||||||
self.app_config.state.volume = value
|
self.app_config.state.volume = value
|
||||||
self.player.volume = self.app_config.state.volume
|
self.player.volume = self.app_config.state.volume
|
||||||
self.update_window()
|
self.update_window()
|
||||||
|
@@ -368,7 +368,8 @@ class CacheManager(metaclass=Singleton):
|
|||||||
meta_json = json.load(f)
|
meta_json = json.load(f)
|
||||||
except json.decoder.JSONDecodeError:
|
except json.decoder.JSONDecodeError:
|
||||||
# Just continue with the default meta_json.
|
# Just continue with the default meta_json.
|
||||||
pass
|
logging.warning(
|
||||||
|
'Unable to load cache', stack_info=True)
|
||||||
|
|
||||||
cache_version = meta_json.get('version', 0)
|
cache_version = meta_json.get('version', 0)
|
||||||
|
|
||||||
@@ -411,7 +412,6 @@ class CacheManager(metaclass=Singleton):
|
|||||||
('artist_details', ArtistWithAlbumsID3, dict),
|
('artist_details', ArtistWithAlbumsID3, dict),
|
||||||
('artist_infos', ArtistInfo2, dict),
|
('artist_infos', ArtistInfo2, dict),
|
||||||
]
|
]
|
||||||
return
|
|
||||||
for name, type_name, default in cache_configs:
|
for name, type_name, default in cache_configs:
|
||||||
if default == list:
|
if default == list:
|
||||||
self.cache[name] = [
|
self.cache[name] = [
|
||||||
|
@@ -33,25 +33,29 @@ def from_json(template_type: Any, data: Any) -> Any:
|
|||||||
instance = None
|
instance = None
|
||||||
# Handle generics. List[*], Dict[*, *] in particular.
|
# Handle generics. List[*], Dict[*, *] in particular.
|
||||||
elif type(template_type) == typing._GenericAlias: # type: ignore
|
elif type(template_type) == typing._GenericAlias: # type: ignore
|
||||||
# Having to use this because things changed in Python 3.7.
|
if getattr(template_type, '__origin__') == typing.Union:
|
||||||
class_name = template_type._name
|
template_type = template_type.__args__[0]
|
||||||
|
instance = from_json(template_type, data)
|
||||||
# This is not very elegant since it doesn't allow things which sublass
|
|
||||||
# from List or Dict. For my purposes, this doesn't matter.
|
|
||||||
if class_name == 'List':
|
|
||||||
inner_type = template_type.__args__[0]
|
|
||||||
instance = [from_json(inner_type, value) for value in data]
|
|
||||||
|
|
||||||
elif class_name == 'Dict':
|
|
||||||
key_type, val_type = template_type.__args__
|
|
||||||
instance = {
|
|
||||||
from_json(key_type, key): from_json(val_type, value)
|
|
||||||
for key, value in data.items()
|
|
||||||
}
|
|
||||||
else:
|
else:
|
||||||
raise Exception(
|
# Having to use this because things changed in Python 3.7.
|
||||||
'Trying to deserialize an unsupported type: {}'.format(
|
class_name = template_type._name
|
||||||
template_type._name))
|
|
||||||
|
# This is not very elegant since it doesn't allow things which
|
||||||
|
# sublass from List or Dict. For my purposes, this doesn't matter.
|
||||||
|
if class_name == 'List':
|
||||||
|
inner_type = template_type.__args__[0]
|
||||||
|
instance = [from_json(inner_type, value) for value in data]
|
||||||
|
|
||||||
|
elif class_name == 'Dict':
|
||||||
|
key_type, val_type = template_type.__args__
|
||||||
|
instance = {
|
||||||
|
from_json(key_type, key): from_json(val_type, value)
|
||||||
|
for key, value in data.items()
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
'Trying to deserialize an unsupported type: {}'.format(
|
||||||
|
template_type._name))
|
||||||
elif template_type == str or issubclass(template_type, str):
|
elif template_type == str or issubclass(template_type, str):
|
||||||
instance = data
|
instance = data
|
||||||
elif template_type == int or issubclass(template_type, int):
|
elif template_type == int or issubclass(template_type, int):
|
||||||
@@ -72,9 +76,13 @@ def from_json(template_type: Any, data: Any) -> Any:
|
|||||||
# Handle everything else by first instantiating the class, then adding
|
# Handle everything else by first instantiating the class, then adding
|
||||||
# all of the sub-elements, recursively calling from_json on them.
|
# all of the sub-elements, recursively calling from_json on them.
|
||||||
else:
|
else:
|
||||||
instance = template_type()
|
# for field, field_type in annotations.items():
|
||||||
for field, field_type in annotations.items():
|
# value = data.get(field)
|
||||||
value = data.get(field)
|
# setattr(instance, field, from_json(field_type, value))
|
||||||
setattr(instance, field, from_json(field_type, value))
|
instance = template_type(
|
||||||
|
**{
|
||||||
|
field: from_json(field_type, data.get(field))
|
||||||
|
for field, field_type in annotations.items()
|
||||||
|
})
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
from dataclasses import Field, fields
|
# from dataclasses import Field, fields
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from sublime.from_json import from_json as _from_json
|
||||||
|
|
||||||
|
|
||||||
class APIObject:
|
class APIObject:
|
||||||
"""Defines the base class for objects coming from the Subsonic API."""
|
"""Defines the base class for objects coming from the Subsonic API."""
|
||||||
@@ -15,11 +17,4 @@ class APIObject:
|
|||||||
:param data: a Python dictionary representation of the data to
|
:param data: a Python dictionary representation of the data to
|
||||||
deserialize
|
deserialize
|
||||||
"""
|
"""
|
||||||
if data is None:
|
return _from_json(cls, data)
|
||||||
return data
|
|
||||||
print('=' * 80)
|
|
||||||
deserialized = cls.__call__(**data)
|
|
||||||
for field in fields(cls):
|
|
||||||
print(field)
|
|
||||||
value = getattr(deserialized, field.name)
|
|
||||||
print('ohea', value)
|
|
||||||
|
@@ -8,7 +8,7 @@ script or run it on a new API version.
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import List, Optional
|
from typing import Any, List, Optional
|
||||||
|
|
||||||
from sublime.server.api_object import APIObject
|
from sublime.server.api_object import APIObject
|
||||||
|
|
||||||
@@ -23,6 +23,9 @@ class AlbumInfo(APIObject):
|
|||||||
largeImageUrl: List[str] = field(default_factory=list)
|
largeImageUrl: List[str] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class AverageRating(APIObject, float):
|
class AverageRating(APIObject, float):
|
||||||
@@ -35,6 +38,9 @@ class MediaType(APIObject, Enum):
|
|||||||
AUDIOBOOK = 'audiobook'
|
AUDIOBOOK = 'audiobook'
|
||||||
VIDEO = 'video'
|
VIDEO = 'video'
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class UserRating(APIObject, int):
|
class UserRating(APIObject, int):
|
||||||
@@ -76,12 +82,18 @@ class Child(APIObject):
|
|||||||
originalWidth: Optional[int] = None
|
originalWidth: Optional[int] = None
|
||||||
originalHeight: Optional[int] = None
|
originalHeight: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class AlbumList(APIObject):
|
class AlbumList(APIObject):
|
||||||
album: List[Child] = field(default_factory=list)
|
album: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class AlbumID3(APIObject):
|
class AlbumID3(APIObject):
|
||||||
@@ -99,12 +111,18 @@ class AlbumID3(APIObject):
|
|||||||
year: Optional[int] = None
|
year: Optional[int] = None
|
||||||
genre: Optional[str] = None
|
genre: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class AlbumList2(APIObject):
|
class AlbumList2(APIObject):
|
||||||
album: List[AlbumID3] = field(default_factory=list)
|
album: List[AlbumID3] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class AlbumWithSongsID3(APIObject):
|
class AlbumWithSongsID3(APIObject):
|
||||||
@@ -123,6 +141,9 @@ class AlbumWithSongsID3(APIObject):
|
|||||||
year: Optional[int] = None
|
year: Optional[int] = None
|
||||||
genre: Optional[str] = None
|
genre: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Artist(APIObject):
|
class Artist(APIObject):
|
||||||
@@ -134,6 +155,9 @@ class Artist(APIObject):
|
|||||||
userRating: Optional[UserRating] = None
|
userRating: Optional[UserRating] = None
|
||||||
averageRating: Optional[AverageRating] = None
|
averageRating: Optional[AverageRating] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ArtistInfoBase(APIObject):
|
class ArtistInfoBase(APIObject):
|
||||||
@@ -145,6 +169,9 @@ class ArtistInfoBase(APIObject):
|
|||||||
largeImageUrl: List[str] = field(default_factory=list)
|
largeImageUrl: List[str] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ArtistInfo(APIObject):
|
class ArtistInfo(APIObject):
|
||||||
@@ -157,6 +184,9 @@ class ArtistInfo(APIObject):
|
|||||||
mediumImageUrl: List[str] = field(default_factory=list)
|
mediumImageUrl: List[str] = field(default_factory=list)
|
||||||
largeImageUrl: List[str] = field(default_factory=list)
|
largeImageUrl: List[str] = field(default_factory=list)
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ArtistID3(APIObject):
|
class ArtistID3(APIObject):
|
||||||
@@ -168,6 +198,9 @@ class ArtistID3(APIObject):
|
|||||||
artistImageUrl: Optional[str] = None
|
artistImageUrl: Optional[str] = None
|
||||||
starred: Optional[datetime] = None
|
starred: Optional[datetime] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ArtistInfo2(APIObject):
|
class ArtistInfo2(APIObject):
|
||||||
@@ -180,6 +213,9 @@ class ArtistInfo2(APIObject):
|
|||||||
mediumImageUrl: List[str] = field(default_factory=list)
|
mediumImageUrl: List[str] = field(default_factory=list)
|
||||||
largeImageUrl: List[str] = field(default_factory=list)
|
largeImageUrl: List[str] = field(default_factory=list)
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ArtistWithAlbumsID3(APIObject):
|
class ArtistWithAlbumsID3(APIObject):
|
||||||
@@ -192,6 +228,9 @@ class ArtistWithAlbumsID3(APIObject):
|
|||||||
artistImageUrl: Optional[str] = None
|
artistImageUrl: Optional[str] = None
|
||||||
starred: Optional[datetime] = None
|
starred: Optional[datetime] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class IndexID3(APIObject):
|
class IndexID3(APIObject):
|
||||||
@@ -199,6 +238,9 @@ class IndexID3(APIObject):
|
|||||||
artist: List[ArtistID3] = field(default_factory=list)
|
artist: List[ArtistID3] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ArtistsID3(APIObject):
|
class ArtistsID3(APIObject):
|
||||||
@@ -206,6 +248,9 @@ class ArtistsID3(APIObject):
|
|||||||
index: List[IndexID3] = field(default_factory=list)
|
index: List[IndexID3] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Bookmark(APIObject):
|
class Bookmark(APIObject):
|
||||||
@@ -217,12 +262,18 @@ class Bookmark(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
comment: Optional[str] = None
|
comment: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Bookmarks(APIObject):
|
class Bookmarks(APIObject):
|
||||||
bookmark: List[Bookmark] = field(default_factory=list)
|
bookmark: List[Bookmark] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ChatMessage(APIObject):
|
class ChatMessage(APIObject):
|
||||||
@@ -231,12 +282,18 @@ class ChatMessage(APIObject):
|
|||||||
message: str
|
message: str
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ChatMessages(APIObject):
|
class ChatMessages(APIObject):
|
||||||
chatMessage: List[ChatMessage] = field(default_factory=list)
|
chatMessage: List[ChatMessage] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Directory(APIObject):
|
class Directory(APIObject):
|
||||||
@@ -250,6 +307,9 @@ class Directory(APIObject):
|
|||||||
averageRating: Optional[AverageRating] = None
|
averageRating: Optional[AverageRating] = None
|
||||||
playCount: Optional[int] = None
|
playCount: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Error(APIObject):
|
class Error(APIObject):
|
||||||
@@ -257,6 +317,9 @@ class Error(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
message: Optional[str] = None
|
message: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Genre(APIObject):
|
class Genre(APIObject):
|
||||||
@@ -264,12 +327,18 @@ class Genre(APIObject):
|
|||||||
albumCount: int
|
albumCount: int
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Genres(APIObject):
|
class Genres(APIObject):
|
||||||
genre: List[Genre] = field(default_factory=list)
|
genre: List[Genre] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Index(APIObject):
|
class Index(APIObject):
|
||||||
@@ -277,6 +346,9 @@ class Index(APIObject):
|
|||||||
artist: List[Artist] = field(default_factory=list)
|
artist: List[Artist] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Indexes(APIObject):
|
class Indexes(APIObject):
|
||||||
@@ -287,6 +359,9 @@ class Indexes(APIObject):
|
|||||||
child: List[Child] = field(default_factory=list)
|
child: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class InternetRadioStation(APIObject):
|
class InternetRadioStation(APIObject):
|
||||||
@@ -296,12 +371,18 @@ class InternetRadioStation(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
homePageUrl: Optional[str] = None
|
homePageUrl: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class InternetRadioStations(APIObject):
|
class InternetRadioStations(APIObject):
|
||||||
internetRadioStation: List[InternetRadioStation] = field(default_factory=list)
|
internetRadioStation: List[InternetRadioStation] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class JukeboxStatus(APIObject):
|
class JukeboxStatus(APIObject):
|
||||||
@@ -311,6 +392,9 @@ class JukeboxStatus(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
position: Optional[int] = None
|
position: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class JukeboxPlaylist(APIObject):
|
class JukeboxPlaylist(APIObject):
|
||||||
@@ -321,6 +405,9 @@ class JukeboxPlaylist(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
position: Optional[int] = None
|
position: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class License(APIObject):
|
class License(APIObject):
|
||||||
@@ -330,6 +417,9 @@ class License(APIObject):
|
|||||||
licenseExpires: Optional[datetime] = None
|
licenseExpires: Optional[datetime] = None
|
||||||
trialExpires: Optional[datetime] = None
|
trialExpires: Optional[datetime] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Lyrics(APIObject):
|
class Lyrics(APIObject):
|
||||||
@@ -337,6 +427,9 @@ class Lyrics(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
title: Optional[str] = None
|
title: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class MusicFolder(APIObject):
|
class MusicFolder(APIObject):
|
||||||
@@ -344,12 +437,18 @@ class MusicFolder(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class MusicFolders(APIObject):
|
class MusicFolders(APIObject):
|
||||||
musicFolder: List[MusicFolder] = field(default_factory=list)
|
musicFolder: List[MusicFolder] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
class PodcastStatus(APIObject, Enum):
|
class PodcastStatus(APIObject, Enum):
|
||||||
NEW = 'new'
|
NEW = 'new'
|
||||||
@@ -359,6 +458,9 @@ class PodcastStatus(APIObject, Enum):
|
|||||||
DELETED = 'deleted'
|
DELETED = 'deleted'
|
||||||
SKIPPED = 'skipped'
|
SKIPPED = 'skipped'
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class PodcastEpisode(APIObject):
|
class PodcastEpisode(APIObject):
|
||||||
@@ -400,12 +502,18 @@ class PodcastEpisode(APIObject):
|
|||||||
originalWidth: Optional[int] = None
|
originalWidth: Optional[int] = None
|
||||||
originalHeight: Optional[int] = None
|
originalHeight: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class NewestPodcasts(APIObject):
|
class NewestPodcasts(APIObject):
|
||||||
episode: List[PodcastEpisode] = field(default_factory=list)
|
episode: List[PodcastEpisode] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class NowPlayingEntry(APIObject):
|
class NowPlayingEntry(APIObject):
|
||||||
@@ -446,12 +554,18 @@ class NowPlayingEntry(APIObject):
|
|||||||
originalWidth: Optional[int] = None
|
originalWidth: Optional[int] = None
|
||||||
originalHeight: Optional[int] = None
|
originalHeight: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class NowPlaying(APIObject):
|
class NowPlaying(APIObject):
|
||||||
entry: List[NowPlayingEntry] = field(default_factory=list)
|
entry: List[NowPlayingEntry] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class PlayQueue(APIObject):
|
class PlayQueue(APIObject):
|
||||||
@@ -463,6 +577,9 @@ class PlayQueue(APIObject):
|
|||||||
current: Optional[int] = None
|
current: Optional[int] = None
|
||||||
position: Optional[int] = None
|
position: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Playlist(APIObject):
|
class Playlist(APIObject):
|
||||||
@@ -479,6 +596,9 @@ class Playlist(APIObject):
|
|||||||
public: Optional[bool] = None
|
public: Optional[bool] = None
|
||||||
coverArt: Optional[str] = None
|
coverArt: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class PlaylistWithSongs(APIObject):
|
class PlaylistWithSongs(APIObject):
|
||||||
@@ -496,12 +616,18 @@ class PlaylistWithSongs(APIObject):
|
|||||||
public: Optional[bool] = None
|
public: Optional[bool] = None
|
||||||
coverArt: Optional[str] = None
|
coverArt: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Playlists(APIObject):
|
class Playlists(APIObject):
|
||||||
playlist: List[Playlist] = field(default_factory=list)
|
playlist: List[Playlist] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class PodcastChannel(APIObject):
|
class PodcastChannel(APIObject):
|
||||||
@@ -516,17 +642,26 @@ class PodcastChannel(APIObject):
|
|||||||
originalImageUrl: Optional[str] = None
|
originalImageUrl: Optional[str] = None
|
||||||
errorMessage: Optional[str] = None
|
errorMessage: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Podcasts(APIObject):
|
class Podcasts(APIObject):
|
||||||
channel: List[PodcastChannel] = field(default_factory=list)
|
channel: List[PodcastChannel] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
class ResponseStatus(APIObject, Enum):
|
class ResponseStatus(APIObject, Enum):
|
||||||
OK = 'ok'
|
OK = 'ok'
|
||||||
FAILED = 'failed'
|
FAILED = 'failed'
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ScanStatus(APIObject):
|
class ScanStatus(APIObject):
|
||||||
@@ -534,6 +669,9 @@ class ScanStatus(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
count: Optional[int] = None
|
count: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SearchResult(APIObject):
|
class SearchResult(APIObject):
|
||||||
@@ -542,6 +680,9 @@ class SearchResult(APIObject):
|
|||||||
match: List[Child] = field(default_factory=list)
|
match: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SearchResult2(APIObject):
|
class SearchResult2(APIObject):
|
||||||
@@ -550,6 +691,9 @@ class SearchResult2(APIObject):
|
|||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SearchResult3(APIObject):
|
class SearchResult3(APIObject):
|
||||||
@@ -558,6 +702,9 @@ class SearchResult3(APIObject):
|
|||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Share(APIObject):
|
class Share(APIObject):
|
||||||
@@ -572,30 +719,45 @@ class Share(APIObject):
|
|||||||
expires: Optional[datetime] = None
|
expires: Optional[datetime] = None
|
||||||
lastVisited: Optional[datetime] = None
|
lastVisited: Optional[datetime] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Shares(APIObject):
|
class Shares(APIObject):
|
||||||
share: List[Share] = field(default_factory=list)
|
share: List[Share] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SimilarSongs(APIObject):
|
class SimilarSongs(APIObject):
|
||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SimilarSongs2(APIObject):
|
class SimilarSongs2(APIObject):
|
||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Songs(APIObject):
|
class Songs(APIObject):
|
||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Starred(APIObject):
|
class Starred(APIObject):
|
||||||
@@ -604,6 +766,9 @@ class Starred(APIObject):
|
|||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Starred2(APIObject):
|
class Starred2(APIObject):
|
||||||
@@ -612,12 +777,18 @@ class Starred2(APIObject):
|
|||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class TopSongs(APIObject):
|
class TopSongs(APIObject):
|
||||||
song: List[Child] = field(default_factory=list)
|
song: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class User(APIObject):
|
class User(APIObject):
|
||||||
@@ -641,12 +812,18 @@ class User(APIObject):
|
|||||||
maxBitRate: Optional[int] = None
|
maxBitRate: Optional[int] = None
|
||||||
avatarLastChanged: Optional[datetime] = None
|
avatarLastChanged: Optional[datetime] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Users(APIObject):
|
class Users(APIObject):
|
||||||
user: List[User] = field(default_factory=list)
|
user: List[User] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Version(APIObject, str):
|
class Version(APIObject, str):
|
||||||
@@ -660,6 +837,9 @@ class AudioTrack(APIObject):
|
|||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
languageCode: Optional[str] = None
|
languageCode: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Captions(APIObject):
|
class Captions(APIObject):
|
||||||
@@ -667,6 +847,9 @@ class Captions(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class VideoConversion(APIObject):
|
class VideoConversion(APIObject):
|
||||||
@@ -675,6 +858,9 @@ class VideoConversion(APIObject):
|
|||||||
bitRate: Optional[int] = None
|
bitRate: Optional[int] = None
|
||||||
audioTrackId: Optional[int] = None
|
audioTrackId: Optional[int] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class VideoInfo(APIObject):
|
class VideoInfo(APIObject):
|
||||||
@@ -684,12 +870,18 @@ class VideoInfo(APIObject):
|
|||||||
conversion: List[VideoConversion] = field(default_factory=list)
|
conversion: List[VideoConversion] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Videos(APIObject):
|
class Videos(APIObject):
|
||||||
video: List[Child] = field(default_factory=list)
|
video: List[Child] = field(default_factory=list)
|
||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Response(APIObject):
|
class Response(APIObject):
|
||||||
@@ -739,3 +931,6 @@ class Response(APIObject):
|
|||||||
value: Optional[str] = None
|
value: Optional[str] = None
|
||||||
status: Optional[ResponseStatus] = None
|
status: Optional[ResponseStatus] = None
|
||||||
version: Optional[Version] = None
|
version: Optional[Version] = None
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
return getattr(self, key, default)
|
||||||
|
@@ -148,8 +148,7 @@ class Server:
|
|||||||
)
|
)
|
||||||
raise Exception(f'Subsonic API Error #{code}: {message}')
|
raise Exception(f'Subsonic API Error #{code}: {message}')
|
||||||
|
|
||||||
print(subsonic_response)
|
response = Response.from_json(subsonic_response)
|
||||||
response = Response.from_dict(subsonic_response)
|
|
||||||
|
|
||||||
# Check for an error and if it exists, raise it.
|
# Check for an error and if it exists, raise it.
|
||||||
if response.error:
|
if response.error:
|
||||||
|
@@ -66,6 +66,7 @@ class UIState:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def current_song(self) -> Optional[Child]:
|
def current_song(self) -> Optional[Child]:
|
||||||
|
from sublime.cache_manager import CacheManager
|
||||||
if (not self.play_queue or self.current_song_index < 0
|
if (not self.play_queue or self.current_song_index < 0
|
||||||
or not CacheManager.ready()):
|
or not CacheManager.ready()):
|
||||||
return None
|
return None
|
||||||
|
@@ -2,10 +2,12 @@ import pytest
|
|||||||
|
|
||||||
from sublime.adapters import Adapter, AdapterManager
|
from sublime.adapters import Adapter, AdapterManager
|
||||||
|
|
||||||
|
|
||||||
def test_adapter_manager_singleton():
|
def test_adapter_manager_singleton():
|
||||||
AdapterManager.reset()
|
AdapterManager.reset()
|
||||||
AdapterManager.get_playlists()
|
AdapterManager.get_playlists()
|
||||||
|
|
||||||
|
|
||||||
def test_functions_not_implemented():
|
def test_functions_not_implemented():
|
||||||
with pytest.raises(NotImplementedError):
|
with pytest.raises(NotImplementedError):
|
||||||
Adapter(None)
|
Adapter(None)
|
||||||
|
Reference in New Issue
Block a user