Caching playlist detail retrieval

This commit is contained in:
Sumner Evans
2020-04-22 21:05:04 -06:00
parent 31ea3a51f8
commit 01e8e3c5dd
26 changed files with 7706 additions and 75 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,5 @@
flatpak/flatpak_build_dir/
flatpak/sublime-music.flatpak
sublime/adapters/subsonic/api_specs/
# Created by https://www.gitignore.io/api/python
# Edit at https://www.gitignore.io/?templates=python

View File

@@ -17,10 +17,9 @@ class MediaType(Enum):
class Song(abc.ABC):
id: str
title: str
value: Optional[str]
parent: Optional[str]
album: Optional[str]
artist: Optional[str]
parent: str
album: str
artist: str
track: Optional[int]
year: Optional[int]
genre: Optional[str]
@@ -30,7 +29,7 @@ class Song(abc.ABC):
suffix: Optional[str]
transcoded_content_type: Optional[str]
transcoded_suffix: Optional[str]
duration: Optional[int]
duration: Optional[timedelta]
bit_rate: Optional[int]
path: Optional[str]
is_video: Optional[bool]
@@ -43,10 +42,7 @@ class Song(abc.ABC):
album_id: Optional[str]
artist_id: Optional[str]
type: Optional[MediaType]
bookmark_position: Optional[int]
original_width: Optional[int]
original_height: Optional[int]
# TODO trim down
# TODO trim down, make another data structure for directory?
class Playlist(abc.ABC):

View File

@@ -115,14 +115,16 @@ class FilesystemAdapter(CachingAdapter):
# Handle the songs.
songs = []
for song_data in playlist_data['songs']:
for index, song_data in enumerate(playlist_data['songs']):
# args = dict(filter(lambda kv: kv[0] in f, song_data.items()))
song_data['index'] = index
song, song_created = models.Song.get_or_create(
id=song_data['id'], defaults=song_data)
keys = ('title', 'duration', 'path', 'index')
if not song_created:
song.title = song_data['title']
song.duration = song_data['duration']
for key in keys:
setattr(song, key, song_data[key])
song.save()
songs.append(song)

View File

@@ -1,19 +1,24 @@
from datetime import timedelta
from datetime import datetime, timedelta
from enum import Enum
from typing import Any, Optional
from typing import Any, Optional, Sequence, List
from peewee import (
ensure_tuple,
SelectQuery,
FieldAccessor,
Value,
ManyToManyFieldAccessor,
BooleanField,
ManyToManyField,
DateTimeField,
DoubleField,
Field,
SqliteDatabase,
ForeignKeyField,
IntegerField,
ManyToManyField,
ManyToManyQuery,
Model,
SqliteDatabase,
TextField,
)
from playhouse.sqliteq import SqliteQueueDatabase
from sublime.adapters.adapter_base import CachingAdapter
@@ -22,11 +27,11 @@ database = SqliteDatabase(None)
# Custom Fields
# =============================================================================
class DurationField(IntegerField):
def db_value(self, value: timedelta) -> Optional[int]:
class DurationField(DoubleField):
def db_value(self, value: timedelta) -> Optional[float]:
return value.total_seconds() if value else None
def python_value(self, value: Optional[int]) -> Optional[timedelta]:
def python_value(self, value: Optional[float]) -> Optional[timedelta]:
return timedelta(seconds=value) if value else None
@@ -38,6 +43,123 @@ class CacheConstantsField(TextField):
return CachingAdapter.FunctionNames(value)
class TzDateTimeField(TextField):
def db_value(self, value: Optional[datetime]) -> Optional[str]:
return value.isoformat() if value else None
def python_value(self, value: Optional[str]) -> Optional[datetime]:
return datetime.fromisoformat(value) if value else None
# Sorted M-N Association Field
# =============================================================================
class SortedManyToManyQuery(ManyToManyQuery):
def add(self, value: Sequence[Any], clear_existing: bool = False):
if clear_existing:
self.clear()
accessor = self._accessor
src_id = getattr(self._instance, self._src_attr)
if isinstance(value, SelectQuery):
print('TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT')
raise NotImplementedError()
# query = value.columns(Value(src_id), accessor.dest_fk.rel_field)
# accessor.through_model.insert_from(
# fields=[accessor.src_fk, accessor.dest_fk],
# query=query).execute()
else:
value = ensure_tuple(value)
if not value:
return
inserts = [
{
accessor.src_fk.name: src_id,
accessor.dest_fk.name: rel_id,
'position': i,
} for i, rel_id in enumerate(self._id_list(value))
]
accessor.through_model.insert_many(inserts).execute()
def remove(self, value: Any) -> Any:
print('RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR')
raise NotImplementedError()
# src_id = getattr(self._instance, self._src_attr)
# if isinstance(value, SelectQuery):
# column = getattr(value.model, self._dest_attr)
# subquery = value.columns(column)
# return (
# self._accessor.through_model.delete().where(
# (self._accessor.dest_fk << subquery)
# & (self._accessor.src_fk == src_id)).execute())
# else:
# value = ensure_tuple(value)
# if not value:
# return
# return (
# self._accessor.through_model.delete().where(
# (self._accessor.dest_fk << self._id_list(value))
# & (self._accessor.src_fk == src_id)).execute())
# def clear(self) -> Any:
# src_id = getattr(self._instance, self._src_attr)
# return (
# self._accessor.through_model.delete().where(
# self._accessor.src_fk == src_id).execute())
class SortedManyToManyFieldAccessor(ManyToManyFieldAccessor):
def __get__(
self,
instance: Model,
instance_type: Any = None,
force_query: bool = False,
):
if instance is not None:
if not force_query and self.src_fk.backref != '+':
backref = getattr(instance, self.src_fk.backref)
if isinstance(backref, list):
return [getattr(obj, self.dest_fk.name) for obj in backref]
src_id = getattr(instance, self.src_fk.rel_field.name)
return SortedManyToManyQuery(instance, self, self.rel_model) \
.join(self.through_model) \
.join(self.model) \
.where(self.src_fk == src_id) \
.order_by(self.through_model.position)
return self.field
def __set__(self, instance: Model, value: Sequence[Any]):
query = self.__get__(instance, force_query=True)
query.add(value, clear_existing=True)
class SortedManyToManyField(ManyToManyField):
accessor_class = SortedManyToManyFieldAccessor
def _create_through_model(self) -> type:
lhs, rhs = self.get_models()
tables = [model._meta.table_name for model in (lhs, rhs)]
class Meta:
database = self.model._meta.database
schema = self.model._meta.schema
table_name = '{}_{}_through'.format(*tables)
indexes = (((lhs._meta.name, rhs._meta.name), True), )
params = {'on_delete': self._on_delete, 'on_update': self._on_update}
attrs = {
lhs._meta.name: ForeignKeyField(lhs, **params),
rhs._meta.name: ForeignKeyField(rhs, **params),
'position': IntegerField(),
'Meta': Meta
}
klass_name = '{}{}Through'.format(lhs.__name__, rhs.__name__)
return type(klass_name, (Model, ), attrs)
# Models
# =============================================================================
class BaseModel(Model):
@@ -55,22 +177,21 @@ class Song(BaseModel):
id = TextField(unique=True, primary_key=True)
title = TextField()
duration = DurationField()
# parent: Optional[str] = None
# album: Optional[str] = None
# artist: Optional[str] = None
# track: Optional[int] = None
# year: Optional[int] = None
# genre: Optional[str] = None
# cover_art: Optional[str] = None
parent = TextField()
album = TextField()
artist = TextField()
track = IntegerField(null=True)
year = IntegerField(null=True)
genre = TextField(null=True)
cover_art = TextField(null=True)
# size: Optional[int] = None
# content_type: Optional[str] = None
# suffix: Optional[str] = None
# transcoded_content_type: Optional[str] = None
# transcoded_suffix: Optional[str] = None
# duration: Optional[int] = None
# duration= DurationField ()
# bit_rate: Optional[int] = None
# path: Optional[str] = None
path = TextField()
# is_video: Optional[bool] = None
# user_rating: Optional[int] = None
# average_rating: Optional[float] = None
@@ -80,7 +201,7 @@ class Song(BaseModel):
# starred: Optional[datetime] = None
# album_id: Optional[str] = None
# artist_id: Optional[str] = None
# type: Optional[SublimeAPI.MediaType] = None
# - type_: Optional[SublimeAPI.MediaType] = None
# bookmark_position: Optional[int] = None
# original_width: Optional[int] = None
# original_height: Optional[int] = None
@@ -88,7 +209,7 @@ class Song(BaseModel):
class CacheInfo(BaseModel):
query_name = CacheConstantsField(unique=True, primary_key=True)
last_ingestion_time = DateTimeField(null=False)
last_ingestion_time = TzDateTimeField(null=False)
class Playlist(BaseModel):
@@ -98,12 +219,12 @@ class Playlist(BaseModel):
owner = TextField(null=True)
song_count = IntegerField(null=True)
duration = DurationField(null=True)
created = DateTimeField(null=True)
changed = DateTimeField(null=True)
created = TzDateTimeField(null=True)
changed = TzDateTimeField(null=True)
public = BooleanField(null=True)
cover_art = TextField(null=True)
songs = ManyToManyField(Song, backref='playlists')
songs = SortedManyToManyField(Song, backref='playlists')
ALL_TABLES = (

View File

@@ -33,12 +33,12 @@ for type_, translation_function in extra_translation_map.items():
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class Child(SublimeAPI.Song):
class Song(SublimeAPI.Song):
id: str
title: str
parent: Optional[str] = None
album: Optional[str] = None
artist: Optional[str] = None
parent: str
album: str
artist: str
track: Optional[int] = None
year: Optional[int] = None
genre: Optional[str] = None
@@ -61,9 +61,6 @@ class Child(SublimeAPI.Song):
album_id: Optional[str] = None
artist_id: Optional[str] = None
type: Optional[SublimeAPI.MediaType] = None
bookmark_position: Optional[int] = None
original_width: Optional[int] = None
original_height: Optional[int] = None
@dataclass_json(letter_case=LetterCase.CAMEL)
@@ -86,7 +83,7 @@ class Playlist(SublimeAPI.Playlist):
class PlaylistWithSongs(SublimeAPI.PlaylistDetails):
id: str
name: str
songs: List[Child] = field(
songs: List[Song] = field(
default_factory=list, metadata=config(field_name='entry'))
song_count: int = field(default=0)
duration: timedelta = field(default=timedelta())
@@ -100,7 +97,9 @@ class PlaylistWithSongs(SublimeAPI.PlaylistDetails):
def __post_init__(self):
self.song_count = self.song_count or len(self.songs)
self.duration = self.duration or timedelta(
seconds=sum(s.duration.total_seconds() if s.duration else 0 for s in self.songs))
seconds=sum(
s.duration.total_seconds() if s.duration else 0
for s in self.songs))
@dataclass
@@ -113,6 +112,6 @@ class Response(DataClassJsonMixin):
"""
The base Subsonic response object.
"""
song: Optional[Child] = None
song: Optional[Song] = None
playlists: Optional[Playlists] = None
playlist: Optional[PlaylistWithSongs] = None

View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.sourceforge.net/restapi"
targetNamespace="http://subsonic.sourceforge.net/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.1.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
</xs:complexType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.1.1">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,500 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.10.2">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,548 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.11.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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"/>
<xs:element name="artistInfo" type="sub:ArtistInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo2" type="sub:ArtistInfo2" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs" type="sub:SimilarSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs2" type="sub:SimilarSongs2" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!--Added in 1.11.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfoBase">
<xs:sequence>
<xs:element name="biography" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfo">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ArtistInfo2">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SimilarSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SimilarSongs2">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,563 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.12.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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="playQueue" type="sub:PlayQueue" 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"/>
<xs:element name="artistInfo" type="sub:ArtistInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo2" type="sub:ArtistInfo2" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs" type="sub:SimilarSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs2" type="sub:SimilarSongs2" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!--Added in 1.11.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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="PlayQueue">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="current" type="xs:int" use="optional"/> <!-- ID of currently playing track -->
<xs:attribute name="position" type="xs:long" use="optional"/> <!-- Position in milliseconds of currently playing track -->
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="changed" type="xs:dateTime" use="required"/>
<xs:attribute name="changedBy" type="xs:string" use="required"/> <!-- Name of client app -->
</xs:complexType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfoBase">
<xs:sequence>
<xs:element name="biography" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfo">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ArtistInfo2">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SimilarSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SimilarSongs2">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="folder" type="xs:int" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.12.0 -->
</xs:sequence>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,588 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.13.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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="newestPodcasts" type="sub:NewestPodcasts" 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="playQueue" type="sub:PlayQueue" 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"/>
<xs:element name="artistInfo" type="sub:ArtistInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo2" type="sub:ArtistInfo2" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs" type="sub:SimilarSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs2" type="sub:SimilarSongs2" minOccurs="1" maxOccurs="1"/>
<xs:element name="topSongs" type="sub:TopSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
<xs:attribute name="originalWidth" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalHeight" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="changed" type="xs:dateTime" use="required"/> <!--Added in 1.13.0-->
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!--Added in 1.11.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalImageUrl" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NewestPodcasts">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="channelId" type="xs:string" use="required"/> <!-- Added in 1.13.0 -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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="PlayQueue">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="current" type="xs:int" use="optional"/> <!-- ID of currently playing track -->
<xs:attribute name="position" type="xs:long" use="optional"/> <!-- Position in milliseconds of currently playing track -->
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="changed" type="xs:dateTime" use="required"/>
<xs:attribute name="changedBy" type="xs:string" use="required"/> <!-- Name of client app -->
</xs:complexType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfoBase">
<xs:sequence>
<xs:element name="biography" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfo">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ArtistInfo2">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SimilarSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SimilarSongs2">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TopSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="licenseExpires" type="xs:dateTime" use="optional"/>
<xs:attribute name="trialExpires" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="folder" type="xs:int" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.12.0 -->
</xs:sequence>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="maxBitRate" type="xs:int" use="optional"/> <!-- In Kbps, added in 1.13.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,632 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.14.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="videoInfo" type="sub:VideoInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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="newestPodcasts" type="sub:NewestPodcasts" 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="playQueue" type="sub:PlayQueue" 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"/>
<xs:element name="albumInfo" type="sub:AlbumInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo" type="sub:ArtistInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo2" type="sub:ArtistInfo2" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs" type="sub:SimilarSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs2" type="sub:SimilarSongs2" minOccurs="1" maxOccurs="1"/>
<xs:element name="topSongs" type="sub:TopSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="VideoInfo">
<xs:sequence>
<xs:element name="captions" type="sub:Captions" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="audioTrack" type="sub:AudioTrack" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="conversion" type="sub:VideoConversion" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Captions">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="AudioTrack">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="languageCode" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="VideoConversion">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/> <!-- In Kbps -->
<xs:attribute name="audioTrackId" type="xs:int" use="optional"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
<xs:attribute name="originalWidth" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalHeight" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="changed" type="xs:dateTime" use="required"/> <!--Added in 1.13.0-->
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!--Added in 1.11.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalImageUrl" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NewestPodcasts">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="channelId" type="xs:string" use="required"/> <!-- Added in 1.13.0 -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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="PlayQueue">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="current" type="xs:int" use="optional"/> <!-- ID of currently playing track -->
<xs:attribute name="position" type="xs:long" use="optional"/> <!-- Position in milliseconds of currently playing track -->
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="changed" type="xs:dateTime" use="required"/>
<xs:attribute name="changedBy" type="xs:string" use="required"/> <!-- Name of client app -->
</xs:complexType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumInfo">
<xs:sequence>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfoBase">
<xs:sequence>
<xs:element name="biography" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfo">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ArtistInfo2">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SimilarSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SimilarSongs2">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TopSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="licenseExpires" type="xs:dateTime" use="optional"/>
<xs:attribute name="trialExpires" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="folder" type="xs:int" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.12.0 -->
</xs:sequence>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="maxBitRate" type="xs:int" use="optional"/> <!-- In Kbps, added in 1.13.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="videoConversionRole" type="xs:boolean" use="required"/> <!-- Added in 1.14.0 -->
<xs:attribute name="avatarLastChanged" type="xs:dateTime" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,638 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.15.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="videoInfo" type="sub:VideoInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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="newestPodcasts" type="sub:NewestPodcasts" 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="playQueue" type="sub:PlayQueue" 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"/>
<xs:element name="albumInfo" type="sub:AlbumInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo" type="sub:ArtistInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo2" type="sub:ArtistInfo2" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs" type="sub:SimilarSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs2" type="sub:SimilarSongs2" minOccurs="1" maxOccurs="1"/>
<xs:element name="topSongs" type="sub:TopSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="scanStatus" type="sub:ScanStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="VideoInfo">
<xs:sequence>
<xs:element name="captions" type="sub:Captions" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="audioTrack" type="sub:AudioTrack" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="conversion" type="sub:VideoConversion" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Captions">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="AudioTrack">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="languageCode" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="VideoConversion">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/> <!-- In Kbps -->
<xs:attribute name="audioTrackId" type="xs:int" use="optional"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
<xs:attribute name="originalWidth" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalHeight" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="changed" type="xs:dateTime" use="required"/> <!--Added in 1.13.0-->
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!--Added in 1.11.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalImageUrl" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NewestPodcasts">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="channelId" type="xs:string" use="required"/> <!-- Added in 1.13.0 -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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="PlayQueue">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="current" type="xs:int" use="optional"/> <!-- ID of currently playing track -->
<xs:attribute name="position" type="xs:long" use="optional"/> <!-- Position in milliseconds of currently playing track -->
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="changed" type="xs:dateTime" use="required"/>
<xs:attribute name="changedBy" type="xs:string" use="required"/> <!-- Name of client app -->
</xs:complexType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumInfo">
<xs:sequence>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfoBase">
<xs:sequence>
<xs:element name="biography" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfo">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ArtistInfo2">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SimilarSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SimilarSongs2">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TopSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="licenseExpires" type="xs:dateTime" use="optional"/>
<xs:attribute name="trialExpires" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ScanStatus">
<xs:attribute name="scanning" type="xs:boolean" use="required"/>
<xs:attribute name="count" type="xs:long" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="folder" type="xs:int" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.12.0 -->
</xs:sequence>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="maxBitRate" type="xs:int" use="optional"/> <!-- In Kbps, added in 1.13.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="videoConversionRole" type="xs:boolean" use="required"/> <!-- Added in 1.14.0 -->
<xs:attribute name="avatarLastChanged" type="xs:dateTime" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,638 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.16.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="videoInfo" type="sub:VideoInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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="newestPodcasts" type="sub:NewestPodcasts" 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="playQueue" type="sub:PlayQueue" 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"/>
<xs:element name="albumInfo" type="sub:AlbumInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo" type="sub:ArtistInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo2" type="sub:ArtistInfo2" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs" type="sub:SimilarSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs2" type="sub:SimilarSongs2" minOccurs="1" maxOccurs="1"/>
<xs:element name="topSongs" type="sub:TopSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="scanStatus" type="sub:ScanStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="VideoInfo">
<xs:sequence>
<xs:element name="captions" type="sub:Captions" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="audioTrack" type="sub:AudioTrack" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="conversion" type="sub:VideoConversion" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Captions">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="AudioTrack">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="languageCode" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="VideoConversion">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/> <!-- In Kbps -->
<xs:attribute name="audioTrackId" type="xs:int" use="optional"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
<xs:attribute name="originalWidth" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalHeight" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="changed" type="xs:dateTime" use="required"/> <!--Added in 1.13.0-->
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!--Added in 1.11.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalImageUrl" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NewestPodcasts">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="channelId" type="xs:string" use="required"/> <!-- Added in 1.13.0 -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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="PlayQueue">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="current" type="xs:int" use="optional"/> <!-- ID of currently playing track -->
<xs:attribute name="position" type="xs:long" use="optional"/> <!-- Position in milliseconds of currently playing track -->
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="changed" type="xs:dateTime" use="required"/>
<xs:attribute name="changedBy" type="xs:string" use="required"/> <!-- Name of client app -->
</xs:complexType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumInfo">
<xs:sequence>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfoBase">
<xs:sequence>
<xs:element name="biography" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfo">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ArtistInfo2">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SimilarSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SimilarSongs2">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TopSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="licenseExpires" type="xs:dateTime" use="optional"/>
<xs:attribute name="trialExpires" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ScanStatus">
<xs:attribute name="scanning" type="xs:boolean" use="required"/>
<xs:attribute name="count" type="xs:long" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="folder" type="xs:int" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.12.0 -->
</xs:sequence>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="maxBitRate" type="xs:int" use="optional"/> <!-- In Kbps, added in 1.13.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="videoConversionRole" type="xs:boolean" use="required"/> <!-- Added in 1.14.0 -->
<xs:attribute name="avatarLastChanged" type="xs:dateTime" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,640 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.16.1">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="videoInfo" type="sub:VideoInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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="newestPodcasts" type="sub:NewestPodcasts" 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="playQueue" type="sub:PlayQueue" 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"/>
<xs:element name="albumInfo" type="sub:AlbumInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo" type="sub:ArtistInfo" minOccurs="1" maxOccurs="1"/>
<xs:element name="artistInfo2" type="sub:ArtistInfo2" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs" type="sub:SimilarSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="similarSongs2" type="sub:SimilarSongs2" minOccurs="1" maxOccurs="1"/>
<xs:element name="topSongs" type="sub:TopSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="scanStatus" type="sub:ScanStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artistImageUrl" type="xs:string" use="optional"/> <!-- Added in 1.16.1 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:complexType name="Genres">
<xs:sequence>
<xs:element name="genre" type="sub:Genre" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Genre" mixed="true">
<xs:attribute name="songCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/> <!-- Added in 1.10.2 -->
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ignoredArticles" type="xs:string" use="required"/> <!-- Added in 1.10.0 -->
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="artistImageUrl" type="xs:string" use="optional"/> <!-- Added in 1.16.1 -->
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="genre" type="xs:string" use="optional"/> <!-- Added in 1.10.1 -->
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="VideoInfo">
<xs:sequence>
<xs:element name="captions" type="sub:Captions" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="audioTrack" type="sub:AudioTrack" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="conversion" type="sub:VideoConversion" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Captions">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="AudioTrack">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="languageCode" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="VideoConversion">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/> <!-- In Kbps -->
<xs:attribute name="audioTrackId" type="xs:int" use="optional"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.10.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="playCount" type="xs:long" use="optional"/> <!-- Added in 1.14.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="bookmarkPosition" type="xs:long" use="optional"/> <!-- In millis. Added in 1.10.1 -->
<xs:attribute name="originalWidth" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalHeight" type="xs:int" use="optional"/> <!-- Added in 1.13.0 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="changed" type="xs:dateTime" use="required"/> <!--Added in 1.13.0-->
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!--Added in 1.11.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="originalImageUrl" type="xs:string" use="optional"/> <!-- Added in 1.13.0 -->
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NewestPodcasts">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="channelId" type="xs:string" use="required"/> <!-- Added in 1.13.0 -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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="PlayQueue">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="current" type="xs:int" use="optional"/> <!-- ID of currently playing track -->
<xs:attribute name="position" type="xs:long" use="optional"/> <!-- Position in milliseconds of currently playing track -->
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="changed" type="xs:dateTime" use="required"/>
<xs:attribute name="changedBy" type="xs:string" use="required"/> <!-- Name of client app -->
</xs:complexType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumInfo">
<xs:sequence>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfoBase">
<xs:sequence>
<xs:element name="biography" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="musicBrainzId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="lastFmUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="smallImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="mediumImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="largeImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArtistInfo">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ArtistInfo2">
<xs:complexContent>
<xs:extension base="sub:ArtistInfoBase">
<xs:sequence>
<xs:element name="similarArtist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SimilarSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SimilarSongs2">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TopSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="licenseExpires" type="xs:dateTime" use="optional"/>
<xs:attribute name="trialExpires" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ScanStatus">
<xs:attribute name="scanning" type="xs:boolean" use="required"/>
<xs:attribute name="count" type="xs:long" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="folder" type="xs:int" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.12.0 -->
</xs:sequence>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="maxBitRate" type="xs:int" use="optional"/> <!-- In Kbps, added in 1.13.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="videoConversionRole" type="xs:boolean" use="required"/> <!-- Added in 1.14.0 -->
<xs:attribute name="avatarLastChanged" type="xs:dateTime" use="optional"/> <!-- Added in 1.14.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.2">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<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="randomSongs" type="sub:RandomSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="lyrics" type="sub:Lyrics" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RandomSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.3.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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="randomSongs" type="sub:RandomSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="lyrics" type="sub:Lyrics" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RandomSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.4.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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="randomSongs" type="sub:RandomSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="lyrics" type="sub:Lyrics" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="required"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RandomSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,227 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.5.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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="randomSongs" type="sub:RandomSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="lyrics" type="sub:Lyrics" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="required"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
</xs:complexType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RandomSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,306 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.6.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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="randomSongs" type="sub:RandomSongs" 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="shares" type="sub:Shares" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="required"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
</xs:complexType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RandomSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,319 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.7.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:Playlist" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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="randomSongs" type="sub:RandomSongs" 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="shares" type="sub:Shares" minOccurs="1" maxOccurs="1"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
</xs:complexType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:PlaylistIdAndName" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PlaylistIdAndName">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:complexContent>
<xs:extension base="sub:PlaylistIdAndName">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RandomSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,448 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.8.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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="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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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="lyrics" type="sub:Lyrics" minOccurs="1" maxOccurs="1"/>
<xs:element name="podcasts" type="sub:Podcasts" 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"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistsID3">
<xs:sequence>
<xs:element name="index" type="sub:IndexID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RandomSongs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="Shares">
<xs:sequence>
<xs:element name="share" type="sub:Share" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -0,0 +1,488 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="http://subsonic.org/restapi"
targetNamespace="http://subsonic.org/restapi"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
version="1.9.0">
<xs:element name="subsonic-response" type="sub:Response"/>
<xs:complexType name="Response">
<xs:choice minOccurs="0" maxOccurs="1">
<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"/>
<xs:element name="song" type="sub:Child" minOccurs="1" maxOccurs="1"/>
<xs:element name="videos" type="sub:Videos" minOccurs="1" maxOccurs="1"/>
<xs:element name="nowPlaying" type="sub:NowPlaying" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult" type="sub:SearchResult" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult2" type="sub:SearchResult2" minOccurs="1" maxOccurs="1"/>
<xs:element name="searchResult3" type="sub:SearchResult3" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlists" type="sub:Playlists" minOccurs="1" maxOccurs="1"/>
<xs:element name="playlist" type="sub:PlaylistWithSongs" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxStatus" type="sub:JukeboxStatus" minOccurs="1" maxOccurs="1"/>
<xs:element name="jukeboxPlaylist" type="sub:JukeboxPlaylist" minOccurs="1" maxOccurs="1"/>
<xs:element name="license" type="sub:License" minOccurs="1" maxOccurs="1"/>
<xs:element name="users" type="sub:Users" minOccurs="1" maxOccurs="1"/>
<xs:element name="user" type="sub:User" minOccurs="1" maxOccurs="1"/>
<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: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"/>
<xs:element name="error" type="sub:Error" minOccurs="1" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="status" type="sub:ResponseStatus" use="required"/>
<xs:attribute name="version" type="sub:Version" use="required"/>
</xs:complexType>
<xs:simpleType name="ResponseStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="ok"/>
<xs:enumeration value="failed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Version">
<xs:restriction base="xs:string">
<xs:pattern value="\d+\.\d+\.\d+"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MusicFolders">
<xs:sequence>
<xs:element name="musicFolder" type="sub:MusicFolder" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MusicFolder">
<xs:attribute name="id" type="xs:int" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Indexes">
<xs:sequence>
<xs:element name="shortcut" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="index" type="sub:Index" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/> <!-- Added in 1.7.0 -->
</xs:sequence>
<xs:attribute name="lastModified" type="xs:long" use="required"/>
</xs:complexType>
<xs:complexType name="Index">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Artist">
<xs:attribute name="id" type="xs:string" use="required"/>
<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"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="IndexID3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="ArtistID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="albumCount" type="xs:int" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="ArtistWithAlbumsID3">
<xs:complexContent>
<xs:extension base="sub:ArtistID3">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AlbumID3">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="artistId" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="songCount" type="xs:int" use="required"/>
<xs:attribute name="duration" type="xs:int" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="starred" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="AlbumWithSongsID3">
<xs:complexContent>
<xs:extension base="sub:AlbumID3">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Videos">
<xs:sequence>
<xs:element name="video" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Directory">
<xs:sequence>
<xs:element name="child" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="Child">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="parent" type="xs:string" use="optional"/>
<xs:attribute name="isDir" type="xs:boolean" use="required"/>
<xs:attribute name="title" type="xs:string" use="required"/>
<xs:attribute name="album" type="xs:string" use="optional"/>
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="track" type="xs:int" use="optional"/>
<xs:attribute name="year" type="xs:int" use="optional"/>
<xs:attribute name="genre" type="xs:string" use="optional"/>
<xs:attribute name="coverArt" type="xs:string" use="optional"/>
<xs:attribute name="size" type="xs:long" use="optional"/>
<xs:attribute name="contentType" type="xs:string" use="optional"/>
<xs:attribute name="suffix" type="xs:string" use="optional"/>
<xs:attribute name="transcodedContentType" type="xs:string" use="optional"/>
<xs:attribute name="transcodedSuffix" type="xs:string" use="optional"/>
<xs:attribute name="duration" type="xs:int" use="optional"/>
<xs:attribute name="bitRate" type="xs:int" use="optional"/>
<xs:attribute name="path" type="xs:string" use="optional"/>
<xs:attribute name="isVideo" type="xs:boolean" use="optional"/> <!-- Added in 1.4.1 -->
<xs:attribute name="userRating" type="sub:UserRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="averageRating" type="sub:AverageRating" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="discNumber" type="xs:int" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="created" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="starred" type="xs:dateTime" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="albumId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="artistId" type="xs:string" use="optional"/> <!-- Added in 1.8.0 -->
<xs:attribute name="type" type="sub:MediaType" use="optional"/> <!-- Added in 1.8.0 -->
</xs:complexType>
<xs:simpleType name="MediaType">
<xs:restriction base="xs:string">
<xs:enumeration value="music"/>
<xs:enumeration value="podcast"/>
<xs:enumeration value="audiobook"/>
<xs:enumeration value="video"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserRating">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AverageRating">
<xs:restriction base="xs:double">
<xs:minInclusive value="1.0"/>
<xs:maxInclusive value="5.0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="NowPlaying">
<xs:sequence>
<xs:element name="entry" type="sub:NowPlayingEntry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NowPlayingEntry">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="minutesAgo" type="xs:int" use="required"/>
<xs:attribute name="playerId" type="xs:int" use="required"/>
<xs:attribute name="playerName" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--Deprecated-->
<xs:complexType name="SearchResult">
<xs:sequence>
<xs:element name="match" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="offset" type="xs:int" use="required"/>
<xs:attribute name="totalHits" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="SearchResult2">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SearchResult3">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlists">
<xs:sequence>
<xs:element name="playlist" type="sub:Playlist" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Playlist">
<xs:sequence>
<xs:element name="allowedUser" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <!--Added in 1.8.0-->
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="comment" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="owner" type="xs:string" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="public" type="xs:boolean" use="optional"/> <!--Added in 1.8.0-->
<xs:attribute name="songCount" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="duration" type="xs:int" use="required"/> <!--Added in 1.8.0-->
<xs:attribute name="created" type="xs:dateTime" use="required"/> <!--Added in 1.8.0-->
</xs:complexType>
<xs:complexType name="PlaylistWithSongs">
<xs:complexContent>
<xs:extension base="sub:Playlist">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="JukeboxStatus">
<xs:attribute name="currentIndex" type="xs:int" use="required"/>
<xs:attribute name="playing" type="xs:boolean" use="required"/>
<xs:attribute name="gain" type="xs:float" use="required"/>
<xs:attribute name="position" type="xs:int" use="optional"/> <!--Added in 1.7.0-->
</xs:complexType>
<xs:complexType name="JukeboxPlaylist">
<xs:complexContent>
<xs:extension base="sub:JukeboxStatus">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ChatMessages">
<xs:sequence>
<xs:element name="chatMessage" type="sub:ChatMessage" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChatMessage">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="time" type="xs:long" use="required"/>
<xs:attribute name="message" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="AlbumList">
<xs:sequence>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AlbumList2">
<xs:sequence>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Songs">
<xs:sequence>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Lyrics" mixed="true">
<xs:attribute name="artist" type="xs:string" use="optional"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="Podcasts">
<xs:sequence>
<xs:element name="channel" type="sub:PodcastChannel" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PodcastChannel">
<xs:sequence>
<xs:element name="episode" type="sub:PodcastEpisode" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="title" type="xs:string" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="errorMessage" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="PodcastEpisode">
<xs:complexContent>
<xs:extension base="sub:Child">
<xs:attribute name="streamId" type="xs:string" use="optional"/> <!-- Use this ID for streaming the podcast. -->
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="status" type="sub:PodcastStatus" use="required"/>
<xs:attribute name="publishDate" type="xs:dateTime" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="PodcastStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="new"/>
<xs:enumeration value="downloading"/>
<xs:enumeration value="completed"/>
<xs:enumeration value="error"/>
<xs:enumeration value="deleted"/>
<xs:enumeration value="skipped"/>
</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"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Share">
<xs:sequence>
<xs:element name="entry" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="url" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="created" type="xs:dateTime" use="required"/>
<xs:attribute name="expires" type="xs:dateTime" use="optional"/>
<xs:attribute name="lastVisited" type="xs:dateTime" use="optional"/>
<xs:attribute name="visitCount" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="Starred">
<xs:sequence>
<xs:element name="artist" type="sub:Artist" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Starred2">
<xs:sequence>
<xs:element name="artist" type="sub:ArtistID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="album" type="sub:AlbumID3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="song" type="sub:Child" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="License">
<xs:attribute name="valid" type="xs:boolean" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/>
<xs:attribute name="key" type="xs:string" use="optional"/>
<xs:attribute name="date" type="xs:dateTime" use="optional"/>
</xs:complexType>
<xs:complexType name="Users">
<xs:sequence>
<xs:element name="user" type="sub:User" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="User">
<xs:attribute name="username" type="xs:string" use="required"/>
<xs:attribute name="email" type="xs:string" use="optional"/> <!-- Added in 1.6.0 -->
<xs:attribute name="scrobblingEnabled" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
<xs:attribute name="adminRole" type="xs:boolean" use="required"/>
<xs:attribute name="settingsRole" type="xs:boolean" use="required"/>
<xs:attribute name="downloadRole" type="xs:boolean" use="required"/>
<xs:attribute name="uploadRole" type="xs:boolean" use="required"/>
<xs:attribute name="playlistRole" type="xs:boolean" use="required"/>
<xs:attribute name="coverArtRole" type="xs:boolean" use="required"/>
<xs:attribute name="commentRole" type="xs:boolean" use="required"/>
<xs:attribute name="podcastRole" type="xs:boolean" use="required"/>
<xs:attribute name="streamRole" type="xs:boolean" use="required"/>
<xs:attribute name="jukeboxRole" type="xs:boolean" use="required"/>
<xs:attribute name="shareRole" type="xs:boolean" use="required"/> <!-- Added in 1.7.0 -->
</xs:complexType>
<xs:complexType name="Error">
<xs:attribute name="code" type="xs:int" use="required"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>

View File

@@ -15,7 +15,7 @@ from sublime.config import AppConfiguration
from sublime.server.api_objects import Playlist
def format_song_duration(duration_secs: Optional[int]) -> str:
def format_song_duration(duration_secs: Union[int, timedelta, None]) -> str:
"""
Formats the song duration as mins:seconds with the seconds being
zero-padded if necessary.
@@ -25,6 +25,8 @@ def format_song_duration(duration_secs: Optional[int]) -> str:
>>> format_song_duration(62)
'1:02'
"""
if isinstance(duration_secs, timedelta):
duration_secs = round(duration_secs.total_seconds())
if not duration_secs:
return '-:--'

View File

@@ -2,6 +2,7 @@ import json
from time import sleep
import logging
import re
from dataclasses import asdict
from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Any, Dict, Generator, Optional, Tuple
@@ -96,20 +97,31 @@ def test_caching_get_playlist_details(
with pytest.raises(CacheMissError):
cache_adapter.get_playlist_details('1')
# Create the playlist
# Simulate the playlist being retrieved from Subsonic.
songs = [
SubsonicAPI.Song(
'2',
'Song 2',
parent='foo',
album='foo',
artist='foo',
duration=timedelta(seconds=20.8),
path='/foo/song2.mp3',
),
SubsonicAPI.Song(
'1',
'Song 1',
parent='foo',
album='foo',
artist='foo',
duration=timedelta(seconds=10.2),
path='/foo/song1.mp3',
),
]
cache_adapter.ingest_new_data(
FilesystemAdapter.FunctionNames.GET_PLAYLIST_DETAILS,
('1', ),
SubsonicAPI.PlaylistWithSongs(
'1',
'test1',
songs=[
SubsonicAPI.Child(
'1', 'Song 1', duration=timedelta(seconds=10.2)),
SubsonicAPI.Child(
'2', 'Song 2', duration=timedelta(seconds=20.8)),
],
),
SubsonicAPI.PlaylistWithSongs('1', 'test1', songs=songs),
)
playlist = cache_adapter.get_playlist_details('1')
@@ -117,32 +129,45 @@ def test_caching_get_playlist_details(
assert playlist.name == 'test1'
assert playlist.song_count == 2
assert playlist.duration == timedelta(seconds=31)
assert (playlist.songs[0].id, playlist.songs[0].title) == ('1', 'Song 1')
assert (playlist.songs[1].id, playlist.songs[1].title) == ('2', 'Song 2')
for actual, song in zip(playlist.songs, songs):
for k, v in asdict(song).items():
assert getattr(actual, k, None) == v
# "Force refresh" the playlist
songs = [
SubsonicAPI.Song(
'1',
'Song 1',
parent='foo',
album='foo',
artist='foo',
duration=timedelta(seconds=10.2),
path='/foo/song1.mp3',
),
SubsonicAPI.Song(
'3',
'Song 3',
parent='foo',
album='foo',
artist='foo',
duration=timedelta(seconds=21.8),
path='/foo/song3.mp3',
),
]
cache_adapter.ingest_new_data(
FilesystemAdapter.FunctionNames.GET_PLAYLIST_DETAILS,
('1', ),
SubsonicAPI.PlaylistWithSongs(
'1',
'foo',
songs=[
SubsonicAPI.Child(
'1', 'Song 1', duration=timedelta(seconds=10.2)),
SubsonicAPI.Child(
'3', 'Song 3', duration=timedelta(seconds=20.8)),
],
),
SubsonicAPI.PlaylistWithSongs('1', 'foo', songs=songs),
)
playlist = cache_adapter.get_playlist_details('1')
assert playlist.id == '1'
assert playlist.name == 'foo'
assert playlist.song_count == 2
assert playlist.duration == timedelta(seconds=31)
assert (playlist.songs[0].id, playlist.songs[0].title) == ('1', 'Song 1')
assert (playlist.songs[1].id, playlist.songs[1].title) == ('3', 'Song 3')
assert playlist.duration == timedelta(seconds=32)
for actual, song in zip(playlist.songs, songs):
for k, v in asdict(song).items():
assert getattr(actual, k, None) == v
with pytest.raises(CacheMissError):
cache_adapter.get_playlist_details('2')

View File

@@ -144,7 +144,7 @@ def test_get_playlist_details(adapter: SubsonicAdapter):
assert playlist_details.duration == timedelta(seconds=470)
# Make sure that at least the first song got decoded properly.
assert playlist_details.songs[0] == SubsonicAPI.Child(
assert playlist_details.songs[0] == SubsonicAPI.Song(
id='202',
parent='318',
title='What a Beautiful Name',