From 1be526b8d2a73612a91b28d481239d4689eac7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alban=20F=C3=A9ron?= Date: Sun, 8 Nov 2020 18:00:36 +0100 Subject: [PATCH] Subsonic API 1.10.2 Except for changes required to comply to the XSD specification, this does not include any feature this version brings Closes #194 --- docs/api.md | 2 +- supysonic/api/__init__.py | 6 ++---- supysonic/api/browse.py | 17 +++++++++++----- tests/api/apitestbase.py | 2 +- tests/api/test_browse.py | 11 ++++++++-- ...1.9.0.xsd => subsonic-rest-api-1.10.2.xsd} | 20 +++++++++++++++---- 6 files changed, 41 insertions(+), 17 deletions(-) rename tests/assets/{subsonic-rest-api-1.9.0.xsd => subsonic-rest-api-1.10.2.xsd} (93%) diff --git a/docs/api.md b/docs/api.md index 0aa269d..96143fa 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4,7 +4,7 @@ This page lists all the API methods and their parameters up to the version 1.16.0 (Subsonic 6.1.2). Here you'll find details about which API features _Supysonic_ support, plan on supporting, or won't. -At the moment, the current target API version is 1.9.0. +At the moment, the current target API version is 1.10.2. The following information was gathered by _diff_-ing various snapshots of the [Subsonic API page](http://www.subsonic.org/pages/api.jsp). diff --git a/supysonic/api/__init__.py b/supysonic/api/__init__.py index c85831f..ac74d96 100644 --- a/supysonic/api/__init__.py +++ b/supysonic/api/__init__.py @@ -1,13 +1,11 @@ -# coding: utf-8 -# # This file is part of Supysonic. # Supysonic is a Python implementation of the Subsonic server API. # -# Copyright (C) 2013-2018 Alban 'spl0k' Féron +# Copyright (C) 2013-2020 Alban 'spl0k' Féron # # Distributed under terms of the GNU AGPLv3 license. -API_VERSION = "1.9.0" +API_VERSION = "1.10.2" import binascii import uuid diff --git a/supysonic/api/browse.py b/supysonic/api/browse.py index 3797884..a3cdebd 100644 --- a/supysonic/api/browse.py +++ b/supysonic/api/browse.py @@ -3,7 +3,7 @@ # This file is part of Supysonic. # Supysonic is a Python implementation of the Subsonic server API. # -# Copyright (C) 2013-2018 Alban 'spl0k' Féron +# Copyright (C) 2013-2020 Alban 'spl0k' Féron # # Distributed under terms of the GNU AGPLv3 license. @@ -11,7 +11,7 @@ import string import uuid from flask import request -from pony.orm import ObjectNotFound, select +from pony.orm import ObjectNotFound, select, count from ..db import Folder, Artist, Album, Track @@ -50,7 +50,9 @@ def list_indexes(): last_modif = max(map(lambda f: f.last_scan, folders)) if ifModifiedSince is not None and last_modif < ifModifiedSince: - return request.formatter("indexes", dict(lastModified=last_modif * 1000)) + return request.formatter( + "indexes", dict(lastModified=last_modif * 1000, ignoredArticles="") + ) # The XSD lies, we don't return artists but a directory structure artists = [] @@ -76,6 +78,7 @@ def list_indexes(): "indexes", dict( lastModified=last_modif * 1000, + ignoredArticles="", index=[ dict( name=k, @@ -121,7 +124,10 @@ def list_genres(): "genres", dict( genre=[ - dict(value=genre) for genre in select(t.genre for t in Track if t.genre) + dict(value=genre, songCount=sc, albumCount=ac) + for genre, sc, ac in select( + (t.genre, count(), count(t.album)) for t in Track if t.genre + ) ] ), ) @@ -146,6 +152,7 @@ def list_artists(): return request.formatter( "artists", dict( + ignoredArticles="", index=[ dict( name=k, @@ -155,7 +162,7 @@ def list_artists(): ], ) for k, v in sorted(indexes.items()) - ] + ], ), ) diff --git a/tests/api/apitestbase.py b/tests/api/apitestbase.py index 2269f18..fe0dd62 100644 --- a/tests/api/apitestbase.py +++ b/tests/api/apitestbase.py @@ -26,7 +26,7 @@ class ApiTestBase(TestBase): def setUp(self): super(ApiTestBase, self).setUp() - xsd = etree.parse("tests/assets/subsonic-rest-api-1.9.0.xsd") + xsd = etree.parse("tests/assets/subsonic-rest-api-1.10.2.xsd") self.schema = etree.XMLSchema(xsd) def _find(self, xml, path): diff --git a/tests/api/test_browse.py b/tests/api/test_browse.py index 395ead1..62d3648 100644 --- a/tests/api/test_browse.py +++ b/tests/api/test_browse.py @@ -1,10 +1,9 @@ #!/usr/bin/env python -# coding: utf-8 # # This file is part of Supysonic. # Supysonic is a Python implementation of the Subsonic server API. # -# Copyright (C) 2017 Alban 'spl0k' Féron +# Copyright (C) 2017-2020 Alban 'spl0k' Féron # # Distributed under terms of the GNU AGPLv3 license. @@ -53,6 +52,7 @@ class BrowseTestCase(ApiTestBase): duration=2, album=album, artist=artist, + genre="Music!", bitrate=320, path="tests/assets/{0}rtist/{0}{1}lbum/{2}".format( letter, lether, song @@ -201,6 +201,13 @@ class BrowseTestCase(ApiTestBase): def test_get_videos(self): self._make_request("getVideos", error=0) + def test_genres(self): + rv, child = self._make_request("getGenres", tag="genres") + self.assertEqual(len(child), 1) + self.assertEqual(child[0].text, "Music!") + self.assertEqual(child[0].get("songCount"), "18") + self.assertEqual(child[0].get("albumCount"), "6") + if __name__ == "__main__": unittest.main() diff --git a/tests/assets/subsonic-rest-api-1.9.0.xsd b/tests/assets/subsonic-rest-api-1.10.2.xsd similarity index 93% rename from tests/assets/subsonic-rest-api-1.9.0.xsd rename to tests/assets/subsonic-rest-api-1.10.2.xsd index 1a80d96..a409c45 100644 --- a/tests/assets/subsonic-rest-api-1.9.0.xsd +++ b/tests/assets/subsonic-rest-api-1.10.2.xsd @@ -4,7 +4,7 @@ targetNamespace="http://subsonic.org/restapi" attributeFormDefault="unqualified" elementFormDefault="qualified" - version="1.9.0"> + version="1.10.2"> @@ -68,8 +68,8 @@ - - + + @@ -79,6 +79,7 @@ + @@ -91,18 +92,25 @@ + - + + + + + + + @@ -140,6 +148,8 @@ + + @@ -165,6 +175,7 @@ + @@ -195,6 +206,7 @@ +