mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-22 08:56:17 +00:00
Added method to list genres
This commit is contained in:
parent
9af8ee22e0
commit
ac306f2725
@ -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.
|
||||
|
||||
|
@ -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`
|
||||
|
@ -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
|
||||
|
@ -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?
|
||||
|
@ -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' })
|
||||
|
||||
|
@ -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)
|
||||
|
@ -4,7 +4,7 @@
|
||||
targetNamespace="http://subsonic.org/restapi"
|
||||
attributeFormDefault="unqualified"
|
||||
elementFormDefault="qualified"
|
||||
version="1.8.0">
|
||||
version="1.9.0">
|
||||
|
||||
<xs:element name="subsonic-response" type="sub:Response"/>
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
<xs:element name="musicFolders" type="sub:MusicFolders" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="indexes" type="sub:Indexes" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="directory" type="sub:Directory" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="genres" type="sub:Genres" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="artists" type="sub:ArtistsID3" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="artist" type="sub:ArtistWithAlbumsID3" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="album" type="sub:AlbumWithSongsID3" minOccurs="1" maxOccurs="1"/>
|
||||
@ -32,9 +33,12 @@
|
||||
<xs:element name="chatMessages" type="sub:ChatMessages" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="albumList" type="sub:AlbumList" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="albumList2" type="sub:AlbumList2" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="randomSongs" type="sub:RandomSongs" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="randomSongs" type="sub:Songs" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="songsByGenre" type="sub:Songs" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="lyrics" type="sub:Lyrics" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="podcasts" type="sub:Podcasts" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="internetRadioStations" type="sub:InternetRadioStations" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="bookmarks" type="sub:Bookmarks" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="shares" type="sub:Shares" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="starred" type="sub:Starred" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="starred2" type="sub:Starred2" minOccurs="1" maxOccurs="1"/>
|
||||
@ -89,6 +93,12 @@
|
||||
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="Genres">
|
||||
<xs:sequence>
|
||||
<xs:element name="genre" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="ArtistsID3">
|
||||
<xs:sequence>
|
||||
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
|
||||
@ -323,7 +333,7 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="RandomSongs">
|
||||
<xs:complexType name="Songs">
|
||||
<xs:sequence>
|
||||
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
@ -374,6 +384,36 @@
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:complexType name="InternetRadioStations">
|
||||
<xs:sequence>
|
||||
<xs:element name="internetRadioStation" type="sub:InternetRadioStation" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="InternetRadioStation">
|
||||
<xs:attribute name="id" type="xs:string" use="required"/>
|
||||
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||
<xs:attribute name="streamUrl" type="xs:string" use="required"/>
|
||||
<xs:attribute name="homePageUrl" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="Bookmarks">
|
||||
<xs:sequence>
|
||||
<xs:element name="bookmark" type="sub:Bookmark" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="Bookmark">
|
||||
<xs:sequence>
|
||||
<xs:element name="entry" type="sub:Child" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="position" type="xs:long" use="required"/> <!-- In milliseconds -->
|
||||
<xs:attribute name="username" type="xs:string" use="required"/>
|
||||
<xs:attribute name="comment" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="created" type="xs:dateTime" use="required"/>
|
||||
<xs:attribute name="changed" type="xs:dateTime" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="Shares">
|
||||
<xs:sequence>
|
||||
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
|
Loading…
Reference in New Issue
Block a user