Got deserialization working properly
This commit is contained in:
@@ -17,7 +17,7 @@ def main():
|
|||||||
password=sys.argv[2])
|
password=sys.argv[2])
|
||||||
|
|
||||||
# print(server.ping())
|
# print(server.ping())
|
||||||
# print(server.get_license())
|
print(server.get_license())
|
||||||
print(server.get_music_folders())
|
print(server.get_music_folders())
|
||||||
# print(server.get_indexes())
|
# print(server.get_indexes())
|
||||||
# print()
|
# print()
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import inspect
|
import inspect
|
||||||
from typing import Dict, List, Any
|
import typing
|
||||||
|
from typing import Dict, List, Any, Type
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
|
|
||||||
@@ -9,25 +10,37 @@ def _from_json(cls, data):
|
|||||||
Approach for deserialization here:
|
Approach for deserialization here:
|
||||||
https://stackoverflow.com/a/40639688/2319844
|
https://stackoverflow.com/a/40639688/2319844
|
||||||
"""
|
"""
|
||||||
print(cls, data)
|
annotations: Dict[str, Type] = getattr(cls, '__annotations__', {})
|
||||||
annotations: Dict[str, Any] = getattr(cls, '__annotations__', {})
|
|
||||||
|
|
||||||
# Handle lists of objects.
|
# Handle lists of objects.
|
||||||
if cls == str:
|
if cls == str:
|
||||||
return data
|
instance = data
|
||||||
if issubclass(cls, List):
|
elif cls == int:
|
||||||
list_type = cls.__args__[0]
|
instance = int(data)
|
||||||
instance: List[list_type] = list()
|
elif cls == bool:
|
||||||
for value in data:
|
instance = bool(data)
|
||||||
instance.append(_from_json(list_type, value))
|
elif cls == datetime:
|
||||||
|
instance = parser.parse(data)
|
||||||
|
elif type(cls) == typing._GenericAlias:
|
||||||
|
# Having to use this because things changed in Python 3.7.
|
||||||
|
|
||||||
# Handle dictionaries of objects.
|
# No idea what the heck this is, but let's go with it.
|
||||||
elif issubclass(cls, Dict):
|
if cls._name == 'List':
|
||||||
key_type, val_type = cls.__args__
|
list_type = cls.__args__[0]
|
||||||
instance: Dict[key_type, val_type] = dict()
|
instance: List[list_type] = list()
|
||||||
for key, value in data.items():
|
for value in data:
|
||||||
instance.update(_from_json(key_type, key),
|
instance.append(_from_json(list_type, value))
|
||||||
_from_json(val_type, value))
|
|
||||||
|
elif cls._name == 'Dict':
|
||||||
|
key_type, val_type = cls.__args__
|
||||||
|
instance: Dict[key_type, val_type] = dict()
|
||||||
|
for key, value in data.items():
|
||||||
|
key = _from_json(key_type, key)
|
||||||
|
value = _from_json(val_type, value)
|
||||||
|
instance[key] = value
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
'Trying to deserialize an unsupported type: {cls._name}')
|
||||||
|
|
||||||
# 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.
|
||||||
@@ -35,11 +48,10 @@ def _from_json(cls, data):
|
|||||||
instance: cls = cls()
|
instance: cls = cls()
|
||||||
for name, value in data.items():
|
for name, value in data.items():
|
||||||
field_type = annotations.get(name)
|
field_type = annotations.get(name)
|
||||||
print('ohea', field_type, value)
|
|
||||||
if inspect.isclass(field_type):
|
# Sometimes there are extraneous values, ignore them.
|
||||||
|
if field_type:
|
||||||
setattr(instance, name, _from_json(field_type, value))
|
setattr(instance, name, _from_json(field_type, value))
|
||||||
else:
|
|
||||||
setattr(instance, name, value)
|
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
@@ -74,6 +86,7 @@ class License(APIObject):
|
|||||||
valid: bool
|
valid: bool
|
||||||
email: str
|
email: str
|
||||||
licenseExpires: datetime
|
licenseExpires: datetime
|
||||||
|
trialExpires: datetime
|
||||||
|
|
||||||
|
|
||||||
class MusicFolder(APIObject):
|
class MusicFolder(APIObject):
|
||||||
@@ -86,4 +99,4 @@ class SubsonicResponse(APIObject):
|
|||||||
version: str
|
version: str
|
||||||
license: License
|
license: License
|
||||||
error: SubsonicError
|
error: SubsonicError
|
||||||
musicFolders: List[MusicFolder]
|
musicFolders: Dict[str, List[MusicFolder]]
|
||||||
|
@@ -51,7 +51,9 @@ class Server:
|
|||||||
|
|
||||||
def get_music_folders(self):
|
def get_music_folders(self):
|
||||||
result = self._post(self._make_url('getMusicFolders'))
|
result = self._post(self._make_url('getMusicFolders'))
|
||||||
return result.musicFolders
|
# The Airsonic API implementation of this is dumb. It gives totally the
|
||||||
|
# wrong answer so we have to go in to the 'musicFolder' key here.
|
||||||
|
return result.musicFolders['musicFolder']
|
||||||
|
|
||||||
def get_indexes(self):
|
def get_indexes(self):
|
||||||
result = self._post(self._make_url('getIndexes'))
|
result = self._post(self._make_url('getIndexes'))
|
||||||
|
Reference in New Issue
Block a user