|
|
|
@ -96,10 +96,10 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
title=album["name"], |
|
|
|
|
album=album["name"], |
|
|
|
|
artist=album["artistname"], |
|
|
|
|
coverArt=album["coverid"] |
|
|
|
|
coverArt=album["coverid"], |
|
|
|
|
playCount=album["plays"], |
|
|
|
|
#year=TODO |
|
|
|
|
# playCount="0" |
|
|
|
|
# created="2016-05-08T05:31:31.000Z"/>) |
|
|
|
|
#created="2016-05-08T05:31:31.000Z"/>) |
|
|
|
|
) |
|
|
|
|
response.add_child("album", _parent="albumList", **album_kw) |
|
|
|
|
return response |
|
|
|
@ -108,16 +108,26 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
@formatresponse |
|
|
|
|
def getMusicDirectory_view(self, id, **kwargs): |
|
|
|
|
""" |
|
|
|
|
List an artist dir |
|
|
|
|
List either and artist or album dir |
|
|
|
|
""" |
|
|
|
|
dir_id = int(id) |
|
|
|
|
dirtype, dirinfo, entity = self.library.db.get_subsonic_musicdir(dirid=dir_id) |
|
|
|
|
|
|
|
|
|
response = ApiResponse() |
|
|
|
|
response.add_child("directory") |
|
|
|
|
response.set_attrs(_path="directory", name=entity['name'], id=entity['id'], |
|
|
|
|
parent=dirinfo['parent'], playCount=420) |
|
|
|
|
|
|
|
|
|
# artists just need this |
|
|
|
|
response.add_child("directory", |
|
|
|
|
name=entity['name'], |
|
|
|
|
id=entity['id']) |
|
|
|
|
|
|
|
|
|
if dirtype == "album": |
|
|
|
|
# albums can also have |
|
|
|
|
# - parent (album dir id) |
|
|
|
|
# - playcount |
|
|
|
|
response.set_attrs(_path="directory", |
|
|
|
|
parent=dirinfo["parent"], |
|
|
|
|
playCount=entity["plays"]) |
|
|
|
|
#TODO Meeeeee |
|
|
|
|
for childtype, child in entity["children"]: |
|
|
|
|
# omit not dirs and media in browser |
|
|
|
|
# if not item["isdir"] and item["type"] not in MUSIC_TYPES: |
|
|
|
@ -229,6 +239,29 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose |
|
|
|
|
def getCoverArt_view(self, id, **kwargs): |
|
|
|
|
""" |
|
|
|
|
id is a string and if it's a number it's the album at for a...?? could be song or album either by id or directory id lol |
|
|
|
|
it could also be: |
|
|
|
|
pl-1234 - playlist |
|
|
|
|
|
|
|
|
|
for now, if the first character isn't a number, we error |
|
|
|
|
""" |
|
|
|
|
if id.startswith("pl-"): # get art from first track in playlist |
|
|
|
|
playlist_id = int(id[len("pl-"):]) |
|
|
|
|
_, songs = self.library.get_playlist(playlist_id) |
|
|
|
|
for song in songs: |
|
|
|
|
if song["albumcoverid"]: |
|
|
|
|
id = song["albumcoverid"] |
|
|
|
|
break |
|
|
|
|
else: |
|
|
|
|
raise cherrypy.HTTPError(404, message=f"no art for any of the {len(songs)} tracks in playlist {playlist_id}") |
|
|
|
|
elif id[0] not in "0123456789": |
|
|
|
|
#TODO |
|
|
|
|
print("TODO support getCoverArt id format", repr(id)) |
|
|
|
|
raise cherrypy.HTTPError(500, message=f"coverid format {repr(id)} not supported") |
|
|
|
|
else: |
|
|
|
|
id = int(id) |
|
|
|
|
|
|
|
|
|
cover = self.library.get_cover(id) |
|
|
|
|
fpath = cover["_fullpath"] |
|
|
|
|
type2ct = { |
|
|
|
@ -405,10 +438,10 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
title=album["name"], |
|
|
|
|
album=album["name"], |
|
|
|
|
artist=album["artistname"], |
|
|
|
|
coverArt=album["coverid"] |
|
|
|
|
coverArt=album["coverid"], |
|
|
|
|
playCount=album["plays"], |
|
|
|
|
#year=TODO |
|
|
|
|
# playCount="0" |
|
|
|
|
# created="2016-05-08T05:31:31.000Z"/>) |
|
|
|
|
#created="2016-05-08T05:31:31.000Z"/>) |
|
|
|
|
) |
|
|
|
|
albums += 1 |
|
|
|
|
if albums >= albumCount: |
|
|
|
@ -416,7 +449,7 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
|
|
|
|
|
# TODO make this more efficient |
|
|
|
|
songs = 0 |
|
|
|
|
for song in self.library.db.get_songs(): |
|
|
|
|
for song in self.library.db.get_songs(): #TODO Meeee too |
|
|
|
|
if query not in song["title"].lower(): |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
@ -436,7 +469,7 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
duration=song["length"], |
|
|
|
|
bitRate=song["bitrate"], |
|
|
|
|
path=song["file"], |
|
|
|
|
playCount=420, |
|
|
|
|
playCount=song["plays"], |
|
|
|
|
albumId=song["albumid"], |
|
|
|
|
type="music" |
|
|
|
|
# suffix="mp3" |
|
|
|
@ -457,11 +490,13 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose |
|
|
|
|
def savePlayQueue_view(self, id, current, position, **kwargs): |
|
|
|
|
print("TODO save playqueue with items {} current {} position {}".format(id, current, position)) |
|
|
|
|
|
|
|
|
|
song = self.library.get_song(int(current)) |
|
|
|
|
print("TODO save playqueue with items {} current {} position {}".format(id, repr(current), repr(position))) |
|
|
|
|
current = int(current) |
|
|
|
|
song = self.library.get_song(current) |
|
|
|
|
self.library.db.update_album_played(song['albumid'], time()) |
|
|
|
|
self.library.db.increment_album_plays(song['albumid']) |
|
|
|
|
if int(position) == 0: |
|
|
|
|
self.library.db.increment_track_plays(current) |
|
|
|
|
# TODO save playlist with items ['378', '386', '384', '380', '383'] current 383 position 4471 |
|
|
|
|
# id entries are strings! |
|
|
|
|
|
|
|
|
@ -493,7 +528,7 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
duration=420, |
|
|
|
|
# changed="2018-04-05T23:23:38.263Z" |
|
|
|
|
# created="2018-04-05T23:23:38.252Z" |
|
|
|
|
# coverArt="pl-1" |
|
|
|
|
coverArt="pl-{}".format(playlist["id"]) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return response |
|
|
|
@ -529,9 +564,9 @@ class PysonicSubsonicApi(object):
|
|
|
|
|
contentType=song["format"], |
|
|
|
|
# suffix="mp3" |
|
|
|
|
duration=song["length"], |
|
|
|
|
bitRate=song["bitrate"] / 1024, |
|
|
|
|
bitRate=song["bitrate"] / 1024 if song["bitrate"] else None, #TODO macro for this sort of logic |
|
|
|
|
path=song["file"], |
|
|
|
|
playCount="1", |
|
|
|
|
playCount=song["plays"], |
|
|
|
|
# created="2015-06-09T15:26:01.000Z" |
|
|
|
|
albumId=song["albumid"], |
|
|
|
|
artistId=song["artistid"], |
|
|
|
|