Finished implementing server
This commit is contained in:
@@ -17,6 +17,6 @@ def main():
|
|||||||
|
|
||||||
print(server.ping())
|
print(server.ping())
|
||||||
# print(server.search2('The Band Perry'))
|
# print(server.search2('The Band Perry'))
|
||||||
stream = server.stream(740)
|
stream = server.download(740)
|
||||||
# app = LibremsonicApp()
|
# app = LibremsonicApp()
|
||||||
# app.run(sys.argv)
|
# app.run(sys.argv)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import math
|
import math
|
||||||
from deprecated import deprecated
|
from deprecated import deprecated
|
||||||
from typing import Any, Optional, Dict, List, Union, Iterator
|
from typing import Any, Optional, Dict, List, Union, Iterator, cast
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
@@ -13,31 +13,48 @@ from .api_objects import (
|
|||||||
ArtistInfo,
|
ArtistInfo,
|
||||||
ArtistsID3,
|
ArtistsID3,
|
||||||
ArtistWithAlbumsID3,
|
ArtistWithAlbumsID3,
|
||||||
|
Bookmarks,
|
||||||
Child,
|
Child,
|
||||||
Directory,
|
Directory,
|
||||||
Genres,
|
Genres,
|
||||||
Indexes,
|
Indexes,
|
||||||
|
InternetRadioStations,
|
||||||
License,
|
License,
|
||||||
|
Lyrics,
|
||||||
MusicFolders,
|
MusicFolders,
|
||||||
NowPlaying,
|
NowPlaying,
|
||||||
Playlists,
|
Playlists,
|
||||||
PlaylistWithSongs,
|
PlaylistWithSongs,
|
||||||
|
PlayQueue,
|
||||||
Response,
|
Response,
|
||||||
|
ScanStatus,
|
||||||
SearchResult,
|
SearchResult,
|
||||||
SearchResult2,
|
SearchResult2,
|
||||||
SearchResult3,
|
SearchResult3,
|
||||||
|
Shares,
|
||||||
Starred,
|
Starred,
|
||||||
Starred2,
|
Starred2,
|
||||||
Songs,
|
Songs,
|
||||||
|
User,
|
||||||
|
Users,
|
||||||
VideoInfo,
|
VideoInfo,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
"""Defines a *Sonic server."""
|
"""
|
||||||
|
Defines a *Sonic server.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* The ``hls`` endpoint is not supported.
|
||||||
|
* The ``getCaptions`` endpoint is not supported
|
||||||
|
* None of the podcast endpoints are supported.
|
||||||
|
* The ``jukeboxControl`` endpoint is not supported.
|
||||||
|
* None of the chat message endpoints are supported.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str, hostname: str, username: str, password: str):
|
def __init__(self, name: str, hostname: str, username: str, password: str):
|
||||||
# TODO handle these optionals better.
|
|
||||||
self.name: str = name
|
self.name: str = name
|
||||||
self.hostname: str = hostname
|
self.hostname: str = hostname
|
||||||
self.username: str = username
|
self.username: str = username
|
||||||
@@ -59,7 +76,11 @@ class Server:
|
|||||||
def _subsonic_error_to_exception(self, error):
|
def _subsonic_error_to_exception(self, error):
|
||||||
return Exception(f'{error.code}: {error.message}')
|
return Exception(f'{error.code}: {error.message}')
|
||||||
|
|
||||||
def _post(self, url, **params) -> Response:
|
def _post(
|
||||||
|
self,
|
||||||
|
url: str,
|
||||||
|
**params: Union[None, str, datetime, int, List[int]],
|
||||||
|
) -> Response:
|
||||||
"""
|
"""
|
||||||
Make a post to a *Sonic REST API. Handle all types of errors including
|
Make a post to a *Sonic REST API. Handle all types of errors including
|
||||||
*Sonic ``<error>`` responses.
|
*Sonic ``<error>`` responses.
|
||||||
@@ -69,6 +90,12 @@ class Server:
|
|||||||
:raises Exception: needs some work TODO
|
:raises Exception: needs some work TODO
|
||||||
"""
|
"""
|
||||||
params = {**self._get_params(), **params}
|
params = {**self._get_params(), **params}
|
||||||
|
|
||||||
|
# Deal with datetime parameters (convert to milliseconds since 1970)
|
||||||
|
for k, v in params.items():
|
||||||
|
if type(v) == datetime:
|
||||||
|
params[k] = int(cast(datetime, v).timestamp() * 1000)
|
||||||
|
|
||||||
result = requests.post(url, data=params)
|
result = requests.post(url, data=params)
|
||||||
# TODO make better
|
# TODO make better
|
||||||
if result.status_code != 200:
|
if result.status_code != 200:
|
||||||
@@ -148,8 +175,7 @@ class Server:
|
|||||||
:param music_folder_id: If specified, only return artists in the music
|
:param music_folder_id: If specified, only return artists in the music
|
||||||
folder with the given ID. See ``getMusicFolders``.
|
folder with the given ID. See ``getMusicFolders``.
|
||||||
:param if_modified_since: If specified, only return a result if the
|
:param if_modified_since: If specified, only return a result if the
|
||||||
artist collection has changed since the given time (in milliseconds
|
artist collection has changed since the given time.
|
||||||
since 1 Jan 1970).
|
|
||||||
"""
|
"""
|
||||||
result = self._post(self._make_url('getIndexes'),
|
result = self._post(self._make_url('getIndexes'),
|
||||||
musicFolderId=music_folder_id,
|
musicFolderId=music_folder_id,
|
||||||
@@ -711,10 +737,10 @@ class Server:
|
|||||||
:param comment: The playlist comment.
|
:param comment: The playlist comment.
|
||||||
:param public: ``true`` if the playlist should be visible to all users,
|
:param public: ``true`` if the playlist should be visible to all users,
|
||||||
``false`` otherwise.
|
``false`` otherwise.
|
||||||
:param song_id_to_add: Add this song with this ID to the playlist.
|
:param song_id_to_add: Add this song with this/these ID(s) to the
|
||||||
Multiple parameters allowed.
|
playlist. Can be a single ID or a list of IDs.
|
||||||
:param song_id_to_remove: Remove the song at this position in the
|
:param song_id_to_remove: Remove the song at this/these position(s) in
|
||||||
playlist. Multiple parameters allowed.
|
the playlist. Can be a single ID or a list of IDs.
|
||||||
"""
|
"""
|
||||||
return self._post(
|
return self._post(
|
||||||
self._make_url('updatePlaylist'),
|
self._make_url('updatePlaylist'),
|
||||||
@@ -791,4 +817,540 @@ class Server:
|
|||||||
Obtained by calls to ``getMusicDirectory``.
|
Obtained by calls to ``getMusicDirectory``.
|
||||||
"""
|
"""
|
||||||
# TODO make this a decent object
|
# TODO make this a decent object
|
||||||
return self._post(self._make_url('stream'), id=id)
|
return self._post(self._make_url('download'), id=id)
|
||||||
|
|
||||||
|
def get_cover_art(self, id: int, size: str = None):
|
||||||
|
"""
|
||||||
|
Returns the cover art image in binary form.
|
||||||
|
|
||||||
|
:param id: The ID of a song, album or artist.
|
||||||
|
:param size: If specified, scale image to this size.
|
||||||
|
"""
|
||||||
|
return self._post(self._make_url('getCoverArt'), id=id, size=size)
|
||||||
|
|
||||||
|
def get_lyrics(self, artist: str = None, title: str = None) -> Lyrics:
|
||||||
|
"""
|
||||||
|
Searches for and returns lyrics for a given song.
|
||||||
|
|
||||||
|
:param artist: The artist name.
|
||||||
|
:param title: The song title.
|
||||||
|
"""
|
||||||
|
result = self._post(
|
||||||
|
self._make_url('getLyrics'),
|
||||||
|
artist=artist,
|
||||||
|
title=title,
|
||||||
|
)
|
||||||
|
return result.lyrics
|
||||||
|
|
||||||
|
def get_avatar(self, username: str):
|
||||||
|
"""
|
||||||
|
Returns the avatar (personal image) for a user.
|
||||||
|
|
||||||
|
:param username: the user in question.
|
||||||
|
"""
|
||||||
|
return self._post(self._make_url('getAvatar'), username=username)
|
||||||
|
|
||||||
|
def star(
|
||||||
|
self,
|
||||||
|
id: Union[int, List[int]] = None,
|
||||||
|
album_id: Union[int, List[int]] = None,
|
||||||
|
artist_id: Union[int, List[int]] = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Attaches a star to a song, album or artist.
|
||||||
|
|
||||||
|
:param id: The ID(s) of the file(s) (song(s)) or folder(s)
|
||||||
|
(album(s)/artist(s)) to star. Can be a single ID or a list of IDs.
|
||||||
|
:param album_id: The ID(s) of an album/albums to star. Use this rather
|
||||||
|
than ``id`` if the client accesses the media collection according
|
||||||
|
to ID3 tags rather than file structure. Can be a single ID or a
|
||||||
|
list of IDs.
|
||||||
|
:param artist_id: The ID(s) of an artist/artists to star. Use this
|
||||||
|
rather than ``id`` if the client accesses the media collection
|
||||||
|
according to ID3 tags rather than file structure. Can be a single
|
||||||
|
ID or a list of IDs.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('star'),
|
||||||
|
id=id,
|
||||||
|
albumId=album_id,
|
||||||
|
artistId=artist_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
def unstar(
|
||||||
|
self,
|
||||||
|
id: Union[int, List[int]] = None,
|
||||||
|
album_id: Union[int, List[int]] = None,
|
||||||
|
artist_id: Union[int, List[int]] = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Removes the star from a song, album or artist.
|
||||||
|
|
||||||
|
:param id: The ID(s) of the file(s) (song(s)) or folder(s)
|
||||||
|
(album(s)/artist(s)) to star. Can be a single ID or a list of IDs.
|
||||||
|
:param album_id: The ID(s) of an album/albums to star. Use this rather
|
||||||
|
than ``id`` if the client accesses the media collection according
|
||||||
|
to ID3 tags rather than file structure. Can be a single ID or a
|
||||||
|
list of IDs.
|
||||||
|
:param artist_id: The ID(s) of an artist/artists to star. Use this
|
||||||
|
rather than ``id`` if the client accesses the media collection
|
||||||
|
according to ID3 tags rather than file structure. Can be a single
|
||||||
|
ID or a list of IDs.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('unstar'),
|
||||||
|
id=id,
|
||||||
|
albumId=album_id,
|
||||||
|
artistId=artist_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_rating(self, id: int, rating: int) -> Response:
|
||||||
|
"""
|
||||||
|
Sets the rating for a music file.
|
||||||
|
|
||||||
|
:param id: A string which uniquely identifies the file (song) or folder
|
||||||
|
(album/artist) to rate.
|
||||||
|
:param rating: The rating between 1 and 5 (inclusive), or 0 to remove
|
||||||
|
the rating.
|
||||||
|
"""
|
||||||
|
return self._post(self._make_url('setRating'), id=id, rating=rating)
|
||||||
|
|
||||||
|
def scrobble(
|
||||||
|
self,
|
||||||
|
id: int,
|
||||||
|
time: datetime = None,
|
||||||
|
submission: bool = True,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Registers the local playback of one or more media files. Typically used
|
||||||
|
when playing media that is cached on the client. This operation
|
||||||
|
includes the following:
|
||||||
|
|
||||||
|
* "Scrobbles" the media files on last.fm if the user has configured
|
||||||
|
his/her last.fm credentials on the Subsonic server (Settings >
|
||||||
|
Personal).
|
||||||
|
* Updates the play count and last played timestamp for the media
|
||||||
|
files. (Since 1.11.0)
|
||||||
|
* Makes the media files appear in the "Now playing" page in the web
|
||||||
|
app, and appear in the list of songs returned by
|
||||||
|
``getNowPlaying`` (Since 1.11.0)
|
||||||
|
|
||||||
|
Since 1.8.0 you may specify multiple id (and optionally time)
|
||||||
|
parameters to scrobble multiple files.
|
||||||
|
|
||||||
|
:param id: The ID of the file to scrobble.
|
||||||
|
:param time: (Since 1.8.0) The time at which the song was listened to.
|
||||||
|
:param submission: Whether this is a "submission" or a "now playing"
|
||||||
|
notification.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('scrobble'),
|
||||||
|
id=id,
|
||||||
|
time=time,
|
||||||
|
submission=submission,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_shares(self) -> Shares:
|
||||||
|
"""
|
||||||
|
Returns information about shared media this user is allowed to manage.
|
||||||
|
Takes no extra parameters.
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('getShares'))
|
||||||
|
return result.shares
|
||||||
|
|
||||||
|
def create_share(
|
||||||
|
self,
|
||||||
|
id: Union[int, List[int]],
|
||||||
|
description: str = None,
|
||||||
|
expires: datetime = None,
|
||||||
|
) -> Shares:
|
||||||
|
"""
|
||||||
|
Creates a public URL that can be used by anyone to stream music or
|
||||||
|
video from the Subsonic server. The URL is short and suitable for
|
||||||
|
posting on Facebook, Twitter etc. Note: The user must be authorized to
|
||||||
|
share (see Settings > Users > User is allowed to share files with
|
||||||
|
anyone).
|
||||||
|
|
||||||
|
:param id: ID(s) of (a) song(s), album(s) or video(s) to share. Can be
|
||||||
|
a single ID or a list of IDs.
|
||||||
|
:param description: A user-defined description that will be displayed
|
||||||
|
to people visiting the shared media.
|
||||||
|
:param expires: The time at which the share expires.
|
||||||
|
"""
|
||||||
|
result = self._post(
|
||||||
|
self._make_url('createShare'),
|
||||||
|
id=id,
|
||||||
|
description=description,
|
||||||
|
expires=expires,
|
||||||
|
)
|
||||||
|
return result.shares
|
||||||
|
|
||||||
|
def update_share(
|
||||||
|
self,
|
||||||
|
id: int,
|
||||||
|
description: str = None,
|
||||||
|
expires: datetime = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Updates the description and/or expiration date for an existing share.
|
||||||
|
|
||||||
|
:param id: ID of the share to update.
|
||||||
|
:param description: A user-defined description that will be displayed
|
||||||
|
to people visiting the shared media.
|
||||||
|
:param expires: The time at which the share expires.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('updateShare'),
|
||||||
|
id=id,
|
||||||
|
description=description,
|
||||||
|
expires=expires,
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_share(self, id: int) -> Response:
|
||||||
|
"""
|
||||||
|
Deletes an existing share.
|
||||||
|
|
||||||
|
:param id: ID of the share to delete.
|
||||||
|
"""
|
||||||
|
return self._post(self._make_url('deleteShare'), id=id)
|
||||||
|
|
||||||
|
def get_internet_radio_stations(self) -> InternetRadioStations:
|
||||||
|
"""
|
||||||
|
Returns all internet radio stations. Takes no extra parameters.
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('getInternetRadioStations'))
|
||||||
|
return result.internetRadioStations
|
||||||
|
|
||||||
|
def create_internet_radio_station(
|
||||||
|
self,
|
||||||
|
stream_url: str,
|
||||||
|
name: str,
|
||||||
|
homepage_url: str = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Adds a new internet radio station. Only users with admin privileges are
|
||||||
|
allowed to call this method.
|
||||||
|
|
||||||
|
:param stream_url: The stream URL for the station.
|
||||||
|
:param name: The user-defined name for the station.
|
||||||
|
:param homepage_url: The home page URL for the station.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('createInternetRadioStation'),
|
||||||
|
streamUrl=stream_url,
|
||||||
|
name=name,
|
||||||
|
homepageUrl=homepage_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_internet_radio_station(
|
||||||
|
self,
|
||||||
|
id: int,
|
||||||
|
stream_url: str,
|
||||||
|
name: str,
|
||||||
|
homepage_url: str = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Updates an existing internet radio station. Only users with admin
|
||||||
|
privileges are allowed to call this method.
|
||||||
|
|
||||||
|
:param id: The ID for the station.
|
||||||
|
:param stream_url: The stream URL for the station.
|
||||||
|
:param name: The user-defined name for the station.
|
||||||
|
:param homepage_url: The home page URL for the station.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('updateInternetRadioStation'),
|
||||||
|
id=id,
|
||||||
|
streamUrl=stream_url,
|
||||||
|
name=name,
|
||||||
|
homepageUrl=homepage_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_internet_radio_station(self, id: int) -> Response:
|
||||||
|
"""
|
||||||
|
Deletes an existing internet radio station. Only users with admin
|
||||||
|
privileges are allowed to call this method.
|
||||||
|
|
||||||
|
:param id: The ID for the station.
|
||||||
|
"""
|
||||||
|
return self._post(self._make_url('deleteInternetRadioStation'), id=id)
|
||||||
|
|
||||||
|
def get_user(self, username: str) -> User:
|
||||||
|
"""
|
||||||
|
Get details about a given user, including which authorization roles and
|
||||||
|
folder access it has. Can be used to enable/disable certain features in
|
||||||
|
the client, such as jukebox control.
|
||||||
|
|
||||||
|
:param username: The name of the user to retrieve. You can only
|
||||||
|
retrieve your own user unless you have admin privileges.
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('getUser'), username=username)
|
||||||
|
return result.user
|
||||||
|
|
||||||
|
def get_users(self) -> Users:
|
||||||
|
"""
|
||||||
|
Get details about all users, including which authorization roles and
|
||||||
|
folder access they have. Only users with admin privileges are allowed
|
||||||
|
to call this method.
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('getUsers'))
|
||||||
|
return result.users
|
||||||
|
|
||||||
|
def create_user(
|
||||||
|
self,
|
||||||
|
username: str,
|
||||||
|
password: str,
|
||||||
|
email: str,
|
||||||
|
ldap_authenticated: bool = False,
|
||||||
|
admin_role: bool = False,
|
||||||
|
settings_role: bool = True,
|
||||||
|
stream_role: bool = True,
|
||||||
|
jukebox_role: bool = False,
|
||||||
|
download_role: bool = False,
|
||||||
|
upload_role: bool = False,
|
||||||
|
playlist_role: bool = False,
|
||||||
|
covert_art_role: bool = False,
|
||||||
|
comment_role: bool = False,
|
||||||
|
podcast_role: bool = False,
|
||||||
|
share_role: bool = False,
|
||||||
|
video_conversion_role: bool = False,
|
||||||
|
music_folder_id: Union[int, List[int]] = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Creates a new Subsonic user.
|
||||||
|
|
||||||
|
:param username: The name of the new user.
|
||||||
|
:param password: The password of the new user, either in clear text or
|
||||||
|
hex-encoded.
|
||||||
|
:param email: The email address of the new user.
|
||||||
|
:param ldap_authenticated: Whether the user is authenicated in LDAP.
|
||||||
|
:param admin_role: Whether the user is administrator.
|
||||||
|
:param settings_role: Whether the user is allowed to change personal
|
||||||
|
settings and password.
|
||||||
|
:param stream_role: Whether the user is allowed to play files.
|
||||||
|
:param jukebox_role: Whether the user is allowed to play files in
|
||||||
|
jukebox mode.
|
||||||
|
:param download_role: Whether the user is allowed to download files.
|
||||||
|
:param upload_role: Whether the user is allowed to upload files.
|
||||||
|
:param playlist_role: Whether the user is allowed to create and delete
|
||||||
|
playlists. Since 1.8.0, changing this role has no effect.
|
||||||
|
:param covert_art_role: Whether the user is allowed to change cover art
|
||||||
|
and tags.
|
||||||
|
:param comment_role: Whether the user is allowed to create and edit
|
||||||
|
comments and ratings.
|
||||||
|
:param podcast_role: Whether the user is allowed to administrate
|
||||||
|
Podcasts.
|
||||||
|
:param share_role: (Since 1.8.0) Whether the user is allowed to share
|
||||||
|
files with anyone.
|
||||||
|
:param video_conversion_role: (Since 1.15.0) Whether the user is
|
||||||
|
allowed to start video conversions.
|
||||||
|
:param music_folder_id: (Since 1.12.0) IDs of the music folders the
|
||||||
|
user is allowed access to. Can be a single ID or a list of IDs.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('createUser'),
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
email=email,
|
||||||
|
ldapAuthenticated=ldap_authenticated,
|
||||||
|
adminRole=admin_role,
|
||||||
|
settingsRole=settings_role,
|
||||||
|
streamRole=stream_role,
|
||||||
|
jukeboxRole=jukebox_role,
|
||||||
|
downloadRole=download_role,
|
||||||
|
uploadRole=upload_role,
|
||||||
|
playlistRole=playlist_role,
|
||||||
|
coverArtRole=covert_art_role,
|
||||||
|
commentRole=comment_role,
|
||||||
|
podcastRole=podcast_role,
|
||||||
|
shareRole=share_role,
|
||||||
|
videoConversionRole=video_conversion_role,
|
||||||
|
musicFolderId=music_folder_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_user(
|
||||||
|
self,
|
||||||
|
username: str,
|
||||||
|
password: str = None,
|
||||||
|
email: str = None,
|
||||||
|
ldap_authenticated: bool = False,
|
||||||
|
admin_role: bool = False,
|
||||||
|
settings_role: bool = True,
|
||||||
|
stream_role: bool = True,
|
||||||
|
jukebox_role: bool = False,
|
||||||
|
download_role: bool = False,
|
||||||
|
upload_role: bool = False,
|
||||||
|
playlist_role: bool = False,
|
||||||
|
covert_art_role: bool = False,
|
||||||
|
comment_role: bool = False,
|
||||||
|
podcast_role: bool = False,
|
||||||
|
share_role: bool = False,
|
||||||
|
video_conversion_role: bool = False,
|
||||||
|
music_folder_id: Union[int, List[int]] = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Modifies an existing Subsonic user.
|
||||||
|
|
||||||
|
:param username: The name of the user.
|
||||||
|
:param password: The password of the user, either in clear text or
|
||||||
|
hex-encoded.
|
||||||
|
:param email: The email address of the user.
|
||||||
|
:param ldap_authenticated: Whether the user is authenicated in LDAP.
|
||||||
|
:param admin_role: Whether the user is administrator.
|
||||||
|
:param settings_role: Whether the user is allowed to change personal
|
||||||
|
settings and password.
|
||||||
|
:param stream_role: Whether the user is allowed to play files.
|
||||||
|
:param jukebox_role: Whether the user is allowed to play files in
|
||||||
|
jukebox mode.
|
||||||
|
:param download_role: Whether the user is allowed to download files.
|
||||||
|
:param upload_role: Whether the user is allowed to upload files.
|
||||||
|
:param playlist_role: Whether the user is allowed to create and delete
|
||||||
|
playlists. Since 1.8.0, changing this role has no effect.
|
||||||
|
:param covert_art_role: Whether the user is allowed to change cover art
|
||||||
|
and tags.
|
||||||
|
:param comment_role: Whether the user is allowed to create and edit
|
||||||
|
comments and ratings.
|
||||||
|
:param podcast_role: Whether the user is allowed to administrate
|
||||||
|
Podcasts.
|
||||||
|
:param share_role: (Since 1.8.0) Whether the user is allowed to share
|
||||||
|
files with anyone.
|
||||||
|
:param video_conversion_role: (Since 1.15.0) Whether the user is
|
||||||
|
allowed to start video conversions.
|
||||||
|
:param music_folder_id: (Since 1.12.0) IDs of the music folders the
|
||||||
|
user is allowed access to. Can be a single ID or a list of IDs.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('updateUser'),
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
email=email,
|
||||||
|
ldapAuthenticated=ldap_authenticated,
|
||||||
|
adminRole=admin_role,
|
||||||
|
settingsRole=settings_role,
|
||||||
|
streamRole=stream_role,
|
||||||
|
jukeboxRole=jukebox_role,
|
||||||
|
downloadRole=download_role,
|
||||||
|
uploadRole=upload_role,
|
||||||
|
playlistRole=playlist_role,
|
||||||
|
coverArtRole=covert_art_role,
|
||||||
|
commentRole=comment_role,
|
||||||
|
podcastRole=podcast_role,
|
||||||
|
shareRole=share_role,
|
||||||
|
videoConversionRole=video_conversion_role,
|
||||||
|
musicFolderId=music_folder_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_user(self, username: str) -> Response:
|
||||||
|
"""
|
||||||
|
Deletes an existing Subsonic user.
|
||||||
|
|
||||||
|
:param username: The name of the new user.
|
||||||
|
"""
|
||||||
|
return self._post(self._make_url('deleteUser'), username=username)
|
||||||
|
|
||||||
|
def change_password(self, username: str, password: str) -> Response:
|
||||||
|
"""
|
||||||
|
Changes the password of an existing Subsonic user. You can only change
|
||||||
|
your own password unless you have admin privileges.
|
||||||
|
|
||||||
|
:param username: The name of the user which should change its password.
|
||||||
|
:param password: The new password of the new user, either in clear text
|
||||||
|
of hex-encoded.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('changePassword'),
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_bookmarks(self) -> Bookmarks:
|
||||||
|
"""
|
||||||
|
Returns all bookmarks for this user. A bookmark is a position within a
|
||||||
|
certain media file.
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('getBookmarks'))
|
||||||
|
return result.bookmarks
|
||||||
|
|
||||||
|
def create_bookmarks(
|
||||||
|
self,
|
||||||
|
id: int,
|
||||||
|
position: int,
|
||||||
|
comment: str = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Creates or updates a bookmark (a position within a media file).
|
||||||
|
Bookmarks are personal and not visible to other users.
|
||||||
|
|
||||||
|
:param id: ID of the media file to bookmark. If a bookmark already
|
||||||
|
exists for this file it will be overwritten.
|
||||||
|
:param position: The position (in milliseconds) within the media file.
|
||||||
|
:param comment: A user-defined comment.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('createBookmark'),
|
||||||
|
id=id,
|
||||||
|
position=position,
|
||||||
|
comment=comment,
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_bookmark(self, id: int) -> Response:
|
||||||
|
"""
|
||||||
|
Deletes the bookmark for a given file.
|
||||||
|
|
||||||
|
:param id: ID of the media file for which to delete the bookmark. Other
|
||||||
|
users' bookmarks are not affected.
|
||||||
|
"""
|
||||||
|
return self._post(self._make_url('deleteBookmark'), id=id)
|
||||||
|
|
||||||
|
def get_play_queue(self) -> Optional[PlayQueue]:
|
||||||
|
"""
|
||||||
|
Returns the state of the play queue for this user (as set by
|
||||||
|
``savePlayQueue``). This includes the tracks in the play queue, the
|
||||||
|
currently playing track, and the position within this track. Typically
|
||||||
|
used to allow a user to move between different clients/apps while
|
||||||
|
retaining the same play queue (for instance when listening to an audio
|
||||||
|
book).
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('getPlayQueue'))
|
||||||
|
return result.playQueue
|
||||||
|
|
||||||
|
def savePlayQueue(
|
||||||
|
self,
|
||||||
|
id: Union[int, List[int]],
|
||||||
|
current: int = None,
|
||||||
|
position: int = None,
|
||||||
|
) -> Response:
|
||||||
|
"""
|
||||||
|
Saves the state of the play queue for this user. This includes the
|
||||||
|
tracks in the play queue, the currently playing track, and the position
|
||||||
|
within this track. Typically used to allow a user to move between
|
||||||
|
different clients/apps while retaining the same play queue (for
|
||||||
|
instance when listening to an audio book).
|
||||||
|
|
||||||
|
:param id: ID(s) of a/the song(s) in the play queue. Can be either a
|
||||||
|
single ID or a list of IDs.
|
||||||
|
:param current: The Id of the current playing song.
|
||||||
|
:param position: The position in milliseconds within the currently
|
||||||
|
playing song.
|
||||||
|
"""
|
||||||
|
return self._post(
|
||||||
|
self._make_url('savePlayQueue'),
|
||||||
|
id=id,
|
||||||
|
current=current,
|
||||||
|
position=position,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_scan_status(self) -> ScanStatus:
|
||||||
|
"""
|
||||||
|
Returns the current status for media library scanning. Takes no extra
|
||||||
|
parameters.
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('getScanStatus'))
|
||||||
|
return result.scanStatus
|
||||||
|
|
||||||
|
def start_scan(self) -> ScanStatus:
|
||||||
|
"""
|
||||||
|
Initiates a rescan of the media libraries. Takes no extra parameters.
|
||||||
|
"""
|
||||||
|
result = self._post(self._make_url('startScan'))
|
||||||
|
return result.scanStatus
|
||||||
|
Reference in New Issue
Block a user