diff --git a/README.md b/README.md
index dd87995..3f424a0 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Current supported features are:
* starred tracks/albums and ratings
* [Last.FM][lastfm] scrobbling
-_Supysonic_ currently targets the version 1.8.0 of the _Subsonic_ API. For more
+_Supysonic_ currently targets the version 1.9.0 of the _Subsonic_ API. For more
details, go check the [API implementation status][docs-api].
[subsonic]: http://www.subsonic.org/
@@ -219,7 +219,7 @@ For more details on the command-line usage, take a look at the
The Subsonic API provides several authentication methods. One of them, known as
_token authentication_ was added with API version 1.13.0. As Supysonic currently
-targets API version 1.8.0, the token based method isn't supported. So if your
+targets API version 1.9.0, the token based method isn't supported. So if your
client offers you the option, you'll have to disable the token based
authentication for it to work.
diff --git a/docs/api.md b/docs/api.md
index 5887680..fcf2643 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.8.0.
+At the moment, the current target API version is 1.9.0.
The following information was gathered by _diff_-ing various snapshots of the
[Subsonic API page](http://www.subsonic.org/pages/api.jsp).
@@ -34,7 +34,7 @@ or with version 1.8.0.
| [`getMusicFolders`](#getmusicfolders) | | ✔️ |
| [`getIndexes`](#getindexes) | | ✔️ |
| [`getMusicDirectory`](#getmusicdirectory) | | ✔️ |
-| [`getGenres`](#getgenres) | 1.9.0 | 📅 |
+| [`getGenres`](#getgenres) | 1.9.0 | ✔️ |
| [`getArtists`](#getartists) | | ✔️ |
| [`getArtist`](#getartist) | | ✔️ |
| [`getAlbum`](#getalbum) | | ✔️ |
@@ -166,7 +166,7 @@ No parameter
| `id` | | ✔️ |
#### `getGenres`
-📅 1.9.0
+✔️ 1.9.0
No parameter
#### `getArtists`
diff --git a/supysonic/api/__init__.py b/supysonic/api/__init__.py
index 9fc13c7..ddf0896 100644
--- a/supysonic/api/__init__.py
+++ b/supysonic/api/__init__.py
@@ -7,7 +7,7 @@
#
# Distributed under terms of the GNU AGPLv3 license.
-API_VERSION = '1.8.0'
+API_VERSION = '1.9.0'
import binascii
import uuid
diff --git a/supysonic/api/browse.py b/supysonic/api/browse.py
index 5c36547..9da8a25 100644
--- a/supysonic/api/browse.py
+++ b/supysonic/api/browse.py
@@ -11,7 +11,7 @@ import string
import uuid
from flask import request
-from pony.orm import ObjectNotFound
+from pony.orm import ObjectNotFound, select
from ..db import Folder, Artist, Album, Track
from ..py23 import dict
@@ -93,6 +93,12 @@ def show_directory():
return request.formatter('directory', directory)
+@api.route('/getGenres.view', methods = [ 'GET', 'POST' ])
+def list_genres():
+ return request.formatter('genres', dict(
+ genre = [ dict(_value_ = genre) for genre in select(t.genre for t in Track if t.genre) ]
+ ))
+
@api.route('/getArtists.view', methods = [ 'GET', 'POST' ])
def list_artists():
# According to the API page, there are no parameters?
diff --git a/tests/api/apitestbase.py b/tests/api/apitestbase.py
index df6f2ff..38af4b0 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.8.0.xsd')
+ xsd = etree.parse('tests/assets/subsonic-rest-api-1.9.0.xsd')
self.schema = etree.XMLSchema(xsd)
def _find(self, xml, path):
@@ -68,7 +68,7 @@ class ApiTestBase(TestBase):
if tag and not isinstance(tag, strtype):
raise TypeError("'tag', expecting a str, got " + type(tag).__name__)
- args.update({ 'c': 'tests', 'v': '1.8.0' })
+ args.update({ 'c': 'tests', 'v': '1.9.0' })
if 'u' not in args:
args.update({ 'u': 'alice', 'p': 'Alic3' })
diff --git a/tests/api/test_transcoding.py b/tests/api/test_transcoding.py
index 0b3f959..e1adc4a 100644
--- a/tests/api/test_transcoding.py
+++ b/tests/api/test_transcoding.py
@@ -32,7 +32,7 @@ class TranscodingTestCase(ApiTestBase):
self.trackid = Track.get().id
def _stream(self, **kwargs):
- kwargs.update({ 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'v': '1.8.0', 'id': self.trackid })
+ kwargs.update({ 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'v': '1.9.0', 'id': self.trackid })
rv = self.client.get('/rest/stream.view', query_string = kwargs)
self.assertEqual(rv.status_code, 200)
diff --git a/tests/assets/subsonic-rest-api-1.8.0.xsd b/tests/assets/subsonic-rest-api-1.9.0.xsd
similarity index 89%
rename from tests/assets/subsonic-rest-api-1.8.0.xsd
rename to tests/assets/subsonic-rest-api-1.9.0.xsd
index ba404c5..1a80d96 100644
--- a/tests/assets/subsonic-rest-api-1.8.0.xsd
+++ b/tests/assets/subsonic-rest-api-1.9.0.xsd
@@ -4,7 +4,7 @@
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
- version="1.8.0">
+ version="1.9.0">
@@ -13,6 +13,7 @@
+
@@ -32,9 +33,12 @@
-
+
+
+
+
@@ -89,6 +93,12 @@
+
+
+
+
+
+
@@ -323,7 +333,7 @@
-
+
@@ -374,6 +384,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+