diff --git a/yandex_music/client.py b/yandex_music/client.py index 526471e..bdd3b77 100644 --- a/yandex_music/client.py +++ b/yandex_music/client.py @@ -5,6 +5,7 @@ from yandex_music import YandexMusicObject, Status, Settings, PermissionAlerts, TracksLikes, Track, AlbumsLikes, ArtistsLikes, PlaylistsLikes, Feed, PromoCodeStatus, DownloadInfo, Search, \ Suggestions, Landing from yandex_music.utils.request import Request +from yandex_music.utils.difference import Difference from yandex_music.exceptions import InvalidToken @@ -188,6 +189,88 @@ class Client(YandexMusicObject): return Suggestions.de_json(result, self) + def users_playlists(self, kind: str or int, user_id: str = None, timeout=None, *args, **kwargs): + if user_id is None: + user_id = self.account.uid + + url = f'{self.base_url}/users/{user_id}/playlists/{kind}' + + result = self._request.get(url, timeout=timeout, *args, **kwargs) + + return Playlist.de_json(result, self) + + def users_playlists_create(self, title: str, visibility: str = 'public', user_id: str = None, + timeout=None, *args, **kwargs): + if user_id is None: + user_id = self.account.uid + + url = f'{self.base_url}/users/{user_id}/playlists/create' + + data = { + 'title': title, + 'visibility': visibility + } + + result = self._request.post(url, data, timeout=timeout, *args, **kwargs) + + return Playlist.de_json(result, self) + + def users_playlists_delete(self, kind: str or int, user_id: str = None, + timeout=None, *args, **kwargs): + if user_id is None: + user_id = self.account.uid + + url = f'{self.base_url}/users/{user_id}/playlists/{kind}/delete' + + result = self._request.post(url, timeout=timeout, *args, **kwargs) + + return result == 'ok' + + def users_playlists_name(self, kind: str or int, name: str, user_id: str = None, timeout=None, *args, **kwargs): + if user_id is None: + user_id = self.account.uid + + url = f'{self.base_url}/users/{user_id}/playlists/{kind}/name' + + result = self._request.post(url, {'value': name}, timeout=timeout, *args, **kwargs) + + return Playlist.de_json(result, self) + + def users_playlists_change(self, kind: str or int, diff: str, revision: int = 1, user_id: str = None, + timeout=None, *args, **kwargs): + if user_id is None: + user_id = self.account.uid + + url = f'{self.base_url}/users/{user_id}/playlists/{kind}/change' + + data = { + 'kind': kind, + 'revision': revision, + 'diff': diff + } + + result = self._request.post(url, data, timeout=timeout, *args, **kwargs) + + return Playlist.de_json(result, self) + + def users_playlists_insert_track(self, kind: str or int, track_id, album_id, at: int = 0, revision: int = 1, + user_id: str = None, timeout=None, *args, **kwargs): + if user_id is None: + user_id = self.account.uid + + diff = Difference().add_insert(at, {'id': track_id, 'album_id': album_id}) + + return self.users_playlists_change(kind, diff.to_json(), revision, user_id, timeout, *args, **kwargs) + + def users_playlists_delete_track(self, kind: str or int, from_: int, to: int, revision: int = 1, + user_id: str = None, timeout=None, *args, **kwargs): + if user_id is None: + user_id = self.account.uid + + diff = Difference().add_delete(from_, to) + + return self.users_playlists_change(kind, diff.to_json(), revision, user_id, timeout, *args, **kwargs) + def _add_like(self, object_type: str, ids: str or int or list, remove: bool = False, user_id: str or int = None, timeout=None, *args, **kwargs): if user_id is None: diff --git a/yandex_music/cover.py b/yandex_music/cover.py index aedb5ca..57da2e1 100644 --- a/yandex_music/cover.py +++ b/yandex_music/cover.py @@ -3,23 +3,24 @@ from yandex_music import YandexMusicObject class Cover(YandexMusicObject): def __init__(self, - type, + type=None, uri=None, items_uri=None, dir=None, version=None, custom=None, prefix=None, + error=None, client=None, **kwargs): self.type = type - self.uri = uri self.items_uri = items_uri self.prefix = prefix self.dir = dir self.version = version self.custom = custom + self.error = error self.client = client diff --git a/yandex_music/playlist.py b/yandex_music/playlist.py index 4abf58e..a40627c 100644 --- a/yandex_music/playlist.py +++ b/yandex_music/playlist.py @@ -70,10 +70,20 @@ class Playlist(YandexMusicObject): self.client = client self._id_attrs = (self.uid,) + @property + def is_mine(self): + return self.owner.uid == self.client.account.uid + @property def playlist_id(self): return f'{self.owner.uid}:{self.kind}' + def rename(self, name): + client, kind = self.client, self.kind + + self.__dict__.clear() + self.__dict__.update(client.users_playlists_name(kind, name).__dict__) + @classmethod def de_json(cls, data, client): if not data: diff --git a/yandex_music/utils/difference.py b/yandex_music/utils/difference.py new file mode 100644 index 0000000..c31baf6 --- /dev/null +++ b/yandex_music/utils/difference.py @@ -0,0 +1,49 @@ +import json + +from enum import Enum + + +class Operation(Enum): + INSERT = 'insert' + DELETE = 'delete' + + +class Difference(object): + def __init__(self): + self.operations = [] + + def to_json(self): + return json.dumps(self.operations) + + def add_delete(self, from_, to): + operation = { + 'op': Operation.DELETE.value, + 'from': from_, + 'to': to + } + + self.operations.append(operation) + return self + + def add_insert(self, at, tracks: dict or list): + if not isinstance(tracks, list): + tracks = [tracks] + + operation = { + 'op': Operation.INSERT.value, + 'at': at, + 'tracks': [] + } + + for track in tracks: + track = type('TrackId', (), track) # TODO replace to normal TrackId object + + operation['tracks'].append( + { + 'id': track.id, + 'albumId': track.album_id + } + ) + + self.operations.append(operation) + return self