2019-05-07 06:02:21 +09:00
|
|
|
|
import logging
|
2019-08-28 04:28:23 +09:00
|
|
|
|
import functools
|
2019-05-17 00:29:49 +09:00
|
|
|
|
from datetime import datetime
|
2019-05-07 06:02:21 +09:00
|
|
|
|
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
from yandex_music import YandexMusicObject, Status, Settings, PermissionAlerts, Experiments, Artist, Album, Playlist, \
|
2019-07-06 17:09:47 +09:00
|
|
|
|
TracksList, Track, AlbumsLikes, ArtistsLikes, PlaylistsLikes, Feed, PromoCodeStatus, DownloadInfo, Search, \
|
2019-10-27 23:14:11 +09:00
|
|
|
|
Suggestions, Landing, Genre, Dashboard, StationResult, StationTracksResult, BriefInfo, Supplement, ArtistTracks
|
2019-05-07 06:02:21 +09:00
|
|
|
|
from yandex_music.utils.request import Request
|
2019-06-01 15:04:15 +09:00
|
|
|
|
from yandex_music.utils.difference import Difference
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
from yandex_music.exceptions import InvalidToken
|
2019-05-07 06:02:21 +09:00
|
|
|
|
|
2019-05-16 23:06:05 +09:00
|
|
|
|
CLIENT_ID = '23cabbbdc6cd418abb4b39c32c41195d'
|
|
|
|
|
CLIENT_SECRET = '53bc75238f0c4d08a118e51fe9203300'
|
|
|
|
|
|
2019-07-06 17:09:47 +09:00
|
|
|
|
de_list = {
|
|
|
|
|
'artist': Artist.de_list,
|
|
|
|
|
'album': Album.de_list,
|
|
|
|
|
'track': Track.de_list,
|
|
|
|
|
'playlist': Playlist.de_list,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
de_list_likes = {
|
|
|
|
|
'artist': ArtistsLikes.de_list,
|
|
|
|
|
'album': AlbumsLikes.de_list,
|
|
|
|
|
'playlist': PlaylistsLikes.de_list,
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-16 23:06:05 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def log(method):
|
|
|
|
|
logger = logging.getLogger(method.__module__)
|
|
|
|
|
|
2019-08-28 04:28:23 +09:00
|
|
|
|
@functools.wraps(method)
|
2019-08-25 17:49:02 +09:00
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
|
logger.debug(f'Entering: {method.__name__}')
|
|
|
|
|
|
|
|
|
|
result = method(*args, **kwargs)
|
|
|
|
|
logger.debug(result)
|
|
|
|
|
|
|
|
|
|
logger.debug(f'Exiting: {method.__name__}')
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
|
|
|
2019-05-07 06:02:21 +09:00
|
|
|
|
class Client(YandexMusicObject):
|
2019-07-02 20:40:41 +09:00
|
|
|
|
"""Класс представляющий клиент Yandex Music.
|
2019-06-04 22:30:33 +09:00
|
|
|
|
|
2019-06-15 01:49:56 +09:00
|
|
|
|
Attributes:
|
|
|
|
|
logger (:obj:`logging.Logger`): Объект логера.
|
|
|
|
|
token (:obj:`str`): Уникальный ключ для аутентификации.
|
|
|
|
|
base_url (:obj:`str`): Ссылка на API Yandex Music.
|
|
|
|
|
oauth_url (:obj:`str`): Ссылка на OAuth Yandex Music.
|
2019-07-05 02:21:54 +09:00
|
|
|
|
account (:obj:`yandex_music.Account`): Объект класса :class:`yandex_music.Account` предоставляющего основную
|
2019-06-15 01:49:56 +09:00
|
|
|
|
информацию об аккаунте.
|
|
|
|
|
|
2019-06-04 22:30:33 +09:00
|
|
|
|
Args:
|
2019-06-15 01:49:56 +09:00
|
|
|
|
token (:obj:`str`, optional): Уникальный ключ для аутентификации.
|
|
|
|
|
base_url (:obj:`str`, optional): Ссылка на API Yandex Music.
|
|
|
|
|
oauth_url (:obj:`str`, optional): Ссылка на OAuth Yandex Music.
|
2019-06-13 04:56:38 +09:00
|
|
|
|
request (:obj:`yandex_music.utils.request.Request`, optional): Пре-инициализация
|
2019-07-05 02:21:54 +09:00
|
|
|
|
:class:`yandex_music.utils.request.Request`.
|
2019-06-04 22:30:33 +09:00
|
|
|
|
"""
|
|
|
|
|
|
2019-08-23 03:56:02 +09:00
|
|
|
|
def __init__(self, token=None, base_url=None, oauth_url=None, request=None):
|
2019-05-07 06:02:21 +09:00
|
|
|
|
self.logger = logging.getLogger(__name__)
|
2019-05-17 00:29:49 +09:00
|
|
|
|
self.token = token
|
2019-05-07 06:02:21 +09:00
|
|
|
|
|
|
|
|
|
if base_url is None:
|
|
|
|
|
base_url = 'https://api.music.yandex.net'
|
2019-05-16 23:06:05 +09:00
|
|
|
|
if oauth_url is None:
|
|
|
|
|
oauth_url = 'https://oauth.yandex.ru'
|
2019-05-07 06:02:21 +09:00
|
|
|
|
|
|
|
|
|
self.base_url = base_url
|
2019-05-16 23:06:05 +09:00
|
|
|
|
self.oauth_url = oauth_url
|
|
|
|
|
|
|
|
|
|
self._request = request or Request(self)
|
|
|
|
|
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
self.account = self.account_status().account
|
|
|
|
|
|
2019-05-16 23:06:05 +09:00
|
|
|
|
@classmethod
|
2019-08-23 03:56:02 +09:00
|
|
|
|
def from_credentials(cls, username, password, *args, **kwargs):
|
|
|
|
|
"""Инициализция клиента по логину и паролю.
|
|
|
|
|
|
|
|
|
|
Данный метод получает токен каждый раз при вызове. Рекомендуется сгенерировать его самостоятельно, сохранить и
|
|
|
|
|
использовать при следующих инициализациях клиента. Не храните логины и пароли!
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
username (:obj:`str`): Логин клиента (идентификатор).
|
|
|
|
|
password (:obj:`str`): Пароль клиента (аутентификатор).
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Аргументы для конструктора клиента.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Client`.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
return cls(cls().generate_token_by_username_and_password(username, password), *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def from_token(cls, token, *args, **kwargs):
|
|
|
|
|
"""Инициализция клиента по токену.
|
|
|
|
|
|
|
|
|
|
Ничем не отличается от Client(token). Так исторически сложилось.
|
2019-06-15 01:49:56 +09:00
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
token (:obj:`str`, optional): Уникальный ключ для аутентификации.
|
2019-08-23 03:56:02 +09:00
|
|
|
|
**kwargs (:obj:`dict`, optional): Аргументы для конструктора клиента.
|
2019-06-15 01:49:56 +09:00
|
|
|
|
|
|
|
|
|
Returns:
|
2019-07-05 02:21:54 +09:00
|
|
|
|
:obj:`yandex_music.Client`.
|
2019-06-15 01:49:56 +09:00
|
|
|
|
"""
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
2019-08-23 03:56:02 +09:00
|
|
|
|
return cls(token=token, *args, **kwargs)
|
2019-05-16 23:06:05 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-15 01:49:56 +09:00
|
|
|
|
def generate_token_by_username_and_password(self, username, password, grant_type='password',
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-05 02:21:54 +09:00
|
|
|
|
"""Метод получения OAuth токена по логину и паролю.
|
2019-06-15 01:49:56 +09:00
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
username (:obj:`str`): Логин клиента (идентификатор).
|
|
|
|
|
password (:obj:`str`): Пароль клиента (аутентификатор).
|
|
|
|
|
grant_type (:obj:`str`, optional): Тип разрешения OAuth.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`str`: OAuth токен.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
2019-05-16 23:06:05 +09:00
|
|
|
|
url = f'{self.oauth_url}/token'
|
|
|
|
|
|
|
|
|
|
data = {
|
|
|
|
|
'grant_type': grant_type,
|
|
|
|
|
'client_id': CLIENT_ID,
|
|
|
|
|
'client_secret': CLIENT_SECRET,
|
|
|
|
|
'username': username,
|
|
|
|
|
'password': password
|
|
|
|
|
}
|
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
result = self._request.post(url, data, timeout=timeout, *args, **kwargs)
|
2019-05-16 23:06:05 +09:00
|
|
|
|
|
|
|
|
|
return result.get('access_token')
|
|
|
|
|
|
2019-05-07 06:02:21 +09:00
|
|
|
|
@staticmethod
|
2019-07-05 02:21:54 +09:00
|
|
|
|
def _validate_token(token: str):
|
|
|
|
|
"""Примитивная валидация токена.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
token (:obj:`str`): токен для проверки
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`str`: Токен.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.exceptions.InvalidToken`: Если токен недействителен.
|
|
|
|
|
"""
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
2019-05-07 06:02:21 +09:00
|
|
|
|
if any(x.isspace() for x in token):
|
|
|
|
|
raise InvalidToken()
|
|
|
|
|
|
|
|
|
|
if len(token) != 39:
|
|
|
|
|
raise InvalidToken()
|
|
|
|
|
|
|
|
|
|
return token
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def request(self):
|
2019-07-05 02:21:54 +09:00
|
|
|
|
""":obj:`yandex_music.utils.request.Request`: Объект вспомогательного класса для отправки запросов."""
|
2019-05-07 06:02:21 +09:00
|
|
|
|
return self._request
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
def account_status(self, timeout=None, *args, **kwargs):
|
2019-06-15 01:49:56 +09:00
|
|
|
|
"""Получение статуса аккаунта. Нет обязательных параметров.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
2019-07-05 02:21:54 +09:00
|
|
|
|
:obj:`yandex_music.Status`: Объекта класса :class:`yandex_music.Status` предоставляющий информацию об
|
2019-06-15 01:49:56 +09:00
|
|
|
|
аккаунте если валиден, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
2019-05-07 06:02:21 +09:00
|
|
|
|
url = f'{self.base_url}/account/status'
|
|
|
|
|
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
2019-05-07 06:02:21 +09:00
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
return Status.de_json(result, self)
|
2019-05-11 05:01:32 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
def settings(self, timeout=None, *args, **kwargs):
|
2019-07-03 21:28:54 +09:00
|
|
|
|
"""Получение предложений по покупке. Нет обязательных параметров.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
2019-07-05 02:21:54 +09:00
|
|
|
|
:obj:`yandex_music.Settings`: Объекта класса :class:`yandex_music.Settings` предоставляющий информацию о
|
|
|
|
|
предлагаемых продуктах, иначе :obj:`None`.
|
2019-07-03 21:28:54 +09:00
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
2019-05-11 05:01:32 +09:00
|
|
|
|
url = f'{self.base_url}/settings'
|
|
|
|
|
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
2019-05-11 05:01:32 +09:00
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
return Settings.de_json(result, self)
|
2019-05-11 05:01:32 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
def permission_alerts(self, timeout=None, *args, **kwargs):
|
2019-07-03 21:28:54 +09:00
|
|
|
|
"""Получение оповещений. Нет обязательных параметров.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
2019-07-05 02:21:54 +09:00
|
|
|
|
:obj:`yandex_music.PermissionAlerts`: Объекта класса :class:`yandex_music.PermissionAlerts`
|
|
|
|
|
представляющий оповещения, иначе :obj:`None`.
|
2019-07-03 21:28:54 +09:00
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
2019-05-11 05:01:32 +09:00
|
|
|
|
url = f'{self.base_url}/permission-alerts'
|
|
|
|
|
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
2019-05-11 05:01:32 +09:00
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
return PermissionAlerts.de_json(result, self)
|
2019-05-11 05:01:32 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
def account_experiments(self, timeout=None, *args, **kwargs):
|
2019-07-03 21:28:54 +09:00
|
|
|
|
"""Получение значений экспериментальных функций аккаунта.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
2019-07-05 02:21:54 +09:00
|
|
|
|
:obj:`yandex_music.Experiments`: Объекта класса :class:`yandex_music.Experiments`
|
|
|
|
|
представляющий состояния экспериментальных функций, иначе :obj:`None`.
|
2019-07-03 21:28:54 +09:00
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
2019-05-11 05:01:32 +09:00
|
|
|
|
url = f'{self.base_url}/account/experiments'
|
|
|
|
|
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
2019-05-11 05:01:32 +09:00
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
return Experiments.de_json(result, self)
|
2019-05-11 17:37:47 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-07-15 23:12:04 +09:00
|
|
|
|
def consume_promo_code(self, code: str, language: str = 'en', timeout=None, *args, **kwargs):
|
2019-07-15 22:39:18 +09:00
|
|
|
|
"""Активация промо-кода.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
code (:obj:`str`): Промо-код.
|
|
|
|
|
language (:obj:`str`, optional): Язык ответа API в ISO 639-1.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.PromoCodeStatus`: Объекта класса :class:`yandex_music.PromoCodeStatus`
|
|
|
|
|
представляющий информацию об активации промо-кода, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-05-17 00:29:49 +09:00
|
|
|
|
url = f'{self.base_url}/account/consume-promo-code'
|
|
|
|
|
|
|
|
|
|
result = self._request.post(url, {'code': code, 'language': language}, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
return PromoCodeStatus.de_json(result, self)
|
2019-05-17 00:29:49 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-16 04:38:39 +09:00
|
|
|
|
def feed(self, timeout=None, *args, **kwargs):
|
2019-07-15 22:39:18 +09:00
|
|
|
|
"""Получение потока информации (фида) подобранного под пользователя. Содержит умные плейлисты.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Feed`: Объекта класса :class:`yandex_music.Feed`
|
|
|
|
|
представляющий умные плейлисты пользователя, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-05-16 04:38:39 +09:00
|
|
|
|
url = f'{self.base_url}/feed'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
return Feed.de_json(result, self)
|
2019-05-16 04:38:39 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 17:23:28 +09:00
|
|
|
|
def feed_wizard_is_passed(self, timeout=None, *args, **kwargs):
|
|
|
|
|
url = f'{self.base_url}/feed/wizard/is-passed'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return result.get('is_wizard_passed') or False
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Landing, Block, BlockEntity, Chart, ChartItem, MixLink, PersonalPlaylistsData, PlayContext, PlayContextsData, Promotion, TrackId, TrackShorOld (YEAH!)
The following method are wrapped:
- /landing3
Added the ability to download covers
The following field are optional: Playlist.tags
Now, when parsing json, the "client" key is replaced with "client_"
2019-05-25 02:10:39 +09:00
|
|
|
|
def landing(self, blocks: str or list, timeout=None, *args, **kwargs):
|
2019-07-15 22:39:18 +09:00
|
|
|
|
"""Получение лендинг-страницы содержащий блоки с новыми релизами, чартами, плейлистами с новинками и т.д.
|
|
|
|
|
|
|
|
|
|
Поддерживаемые типы блоков: personalplaylists, promotions, new-releases, new-playlists, mixes,c hart, artists,
|
|
|
|
|
albums, playlists, play_contexts.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
blocks (:obj:`str` | :obj:`list` из :obj:`str`): Блок или список блоков необходимых для выдачи.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Landing`: Объекта класса :class:`yandex_music.Landing`
|
|
|
|
|
представляющий лендинг-страницу, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
New supported objects: Landing, Block, BlockEntity, Chart, ChartItem, MixLink, PersonalPlaylistsData, PlayContext, PlayContextsData, Promotion, TrackId, TrackShorOld (YEAH!)
The following method are wrapped:
- /landing3
Added the ability to download covers
The following field are optional: Playlist.tags
Now, when parsing json, the "client" key is replaced with "client_"
2019-05-25 02:10:39 +09:00
|
|
|
|
url = f'{self.base_url}/landing3'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, {'blocks': blocks}, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Landing.de_json(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 17:23:28 +09:00
|
|
|
|
def genres(self, timeout=None, *args, **kwargs):
|
2019-07-15 22:39:18 +09:00
|
|
|
|
"""Получение жанров музыки.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`list` из :obj:`yandex_music.Genre`: Список объектов класса :class:`yandex_music.Genre`
|
2019-07-16 00:58:59 +09:00
|
|
|
|
представляющих жанры музыки, иначе :obj:`None`.
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 17:23:28 +09:00
|
|
|
|
url = f'{self.base_url}/genres'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Genre.de_list(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-07-15 23:12:04 +09:00
|
|
|
|
def tracks_download_info(self, track_id: str or int, get_direct_links: bool = False, timeout=None, *args, **kwargs):
|
2019-07-15 22:39:18 +09:00
|
|
|
|
"""Получение информации о доступных вариантах загрузки трека.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
track_id (:obj:`str` | :obj:`list` из :obj:`str`): Уникальный идентификатор трека или треков.
|
|
|
|
|
get_direct_links (:obj:`bool`, optional): Получить ли при вызове метода прямую ссылку на загрузку.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`list` из :obj:`yandex_music.DownloadInfo`: Список объектов класса :class:`yandex_music.DownloadInfo`
|
2019-07-16 00:58:59 +09:00
|
|
|
|
представляющих варианты загрузки трека, иначе :obj:`None`.
|
2019-07-15 22:39:18 +09:00
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-05-17 00:29:49 +09:00
|
|
|
|
url = f'{self.base_url}/tracks/{track_id}/download-info'
|
2019-05-16 21:45:25 +09:00
|
|
|
|
|
2019-05-17 00:29:49 +09:00
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
2019-05-16 21:45:25 +09:00
|
|
|
|
|
2019-05-23 18:10:14 +09:00
|
|
|
|
return DownloadInfo.de_list(result, self, get_direct_links)
|
2019-05-17 00:29:49 +09:00
|
|
|
|
|
2019-10-17 05:10:52 +09:00
|
|
|
|
@log
|
|
|
|
|
def track_supplement(self, track_id: str or int, timeout=None, *args, **kwargs):
|
2019-10-17 12:35:24 +09:00
|
|
|
|
"""Получение дополнительной информации о треке.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
track_id (:obj:`str`): Уникальный идентификатор трека.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Supplement`: Объект класса `yandex_music.Supplement` представляющий дополнительную
|
|
|
|
|
информацию о треке.
|
|
|
|
|
|
|
|
|
|
"""
|
2019-10-19 05:44:17 +09:00
|
|
|
|
|
2019-10-17 05:10:52 +09:00
|
|
|
|
url = f'{self.base_url}/tracks/{track_id}/supplement'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Supplement.de_json(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-17 00:29:49 +09:00
|
|
|
|
def play_audio(self,
|
|
|
|
|
track_id: str or int,
|
2019-07-15 23:12:04 +09:00
|
|
|
|
from_: str,
|
|
|
|
|
album_id: str or int,
|
|
|
|
|
playlist_id: str = None,
|
|
|
|
|
from_cache: bool = False,
|
|
|
|
|
play_id: str = None,
|
|
|
|
|
uid: int = None,
|
|
|
|
|
timestamp: str = None,
|
|
|
|
|
track_length_seconds: int = 0,
|
|
|
|
|
total_played_seconds: int = 0,
|
|
|
|
|
end_position_seconds: int = 0,
|
|
|
|
|
client_now: str = None,
|
2019-05-17 00:29:49 +09:00
|
|
|
|
timeout=None,
|
|
|
|
|
*args, **kwargs):
|
2019-07-15 23:12:04 +09:00
|
|
|
|
"""Метод для отправки текущего состояния прослушиваемого трека.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека.
|
|
|
|
|
from_ (:obj:`str`): Наименования клиента с которого происходит прослушивание.
|
|
|
|
|
album_id (:obj:`str` | :obj:`int`): Уникальный идентификатор альбома.
|
|
|
|
|
playlist_id (:obj:`str`, optional): Уникальный идентификатор плейлиста, если таковой прослушивается.
|
|
|
|
|
from_cache (:obj:`bool`, optional): Проигрывается ли трек с кеша.
|
|
|
|
|
play_id (:obj:`str`, optional): Уникальный идентификатор проигрывания.
|
|
|
|
|
uid (:obj:`int`, optional): Уникальный идентификатор пользователя.
|
|
|
|
|
timestamp (:obj:`str`, optional): Текущая дата и время в ISO.
|
|
|
|
|
track_length_seconds (:obj:`int`, optional): Продолжительность трека в секундах.
|
|
|
|
|
total_played_seconds (:obj:`int`, optional): Сколько было всего воспроизведено трека в секундах.
|
|
|
|
|
end_position_seconds (:obj:`int`, optional): Окончательное значение воспроизведенных секунд.
|
|
|
|
|
client_now (:obj:`str`, optional): Текущая дата и время клиента в ISO.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
2019-07-16 00:58:59 +09:00
|
|
|
|
:obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
|
2019-07-15 23:12:04 +09:00
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-05-17 00:29:49 +09:00
|
|
|
|
url = f'{self.base_url}/play-audio'
|
2019-05-16 21:45:25 +09:00
|
|
|
|
|
2019-05-17 00:29:49 +09:00
|
|
|
|
data = {
|
|
|
|
|
'track-id': track_id,
|
|
|
|
|
'from-cache': from_cache,
|
|
|
|
|
'from': from_,
|
|
|
|
|
'play-id': play_id or '',
|
|
|
|
|
'uid': uid or self.account.uid,
|
|
|
|
|
'timestamp': timestamp or f'{datetime.now().isoformat()}Z',
|
|
|
|
|
'track-length-seconds': track_length_seconds,
|
|
|
|
|
'total-played-seconds': total_played_seconds,
|
|
|
|
|
'end-position-seconds': end_position_seconds,
|
|
|
|
|
'album-id': album_id,
|
|
|
|
|
'playlist-id': playlist_id,
|
|
|
|
|
'client-now': client_now or f'{datetime.now().isoformat()}Z'
|
|
|
|
|
}
|
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
result = self._request.post(url, data, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return result == 'ok'
|
|
|
|
|
|
2019-08-28 04:07:42 +09:00
|
|
|
|
def albums_with_tracks(self, album_id: str or int, timeout=None, *args, **kwargs):
|
|
|
|
|
"""Получение альбома по его уникальному идентификатору вместе с треками.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
album_id (:obj:`str` | :obj:`int`): Уникальный идентификатор альбома.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`list` из :obj:`yandex_music.Album`: Объект класса :class:`yandex_music.Album` представляющий альбом,
|
|
|
|
|
иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
url = f'{self.base_url}/albums/{album_id}/with-tracks'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Album.de_json(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
def search(self,
|
2019-07-15 23:12:04 +09:00
|
|
|
|
text: str,
|
|
|
|
|
nocorrect: bool = False,
|
|
|
|
|
type_: str = 'all',
|
|
|
|
|
page: int = 0,
|
|
|
|
|
playlist_in_best: bool = True,
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
timeout=None,
|
|
|
|
|
*args, **kwargs):
|
2019-08-28 04:07:42 +09:00
|
|
|
|
"""Осуществление поиска по запросу и типу, получение результатов.
|
2019-07-15 23:12:04 +09:00
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
text (:obj:`str`): Текст запроса.
|
|
|
|
|
nocorrect (:obj:`bool`): Без исправлений ли TODO.
|
|
|
|
|
type_ (:obj:`str`): Среди какого типа искать (трек, плейлист, альбом, исполнитель).
|
2019-07-16 00:58:59 +09:00
|
|
|
|
page (:obj:`int`): Номер страницы.
|
2019-07-15 23:12:04 +09:00
|
|
|
|
playlist_in_best (:obj:`bool`): Выдавать ли плейлисты лучшим вариантом поиска.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Search`: Объекта класса :class:`yandex_music.Search`
|
|
|
|
|
представляющий результаты поиска, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
url = f'{self.base_url}/search'
|
|
|
|
|
|
|
|
|
|
params = {
|
|
|
|
|
'text': text,
|
|
|
|
|
'nocorrect': nocorrect,
|
2019-07-15 23:12:04 +09:00
|
|
|
|
'type': type_,
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
'page': page,
|
|
|
|
|
'playlist-in-best': playlist_in_best,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, params, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Search.de_json(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
def search_suggest(self, part: str, timeout=None, *args, **kwargs):
|
2019-07-15 23:12:04 +09:00
|
|
|
|
"""Получение подсказок по введенной части поискового запроса.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
part (:obj:`str`): Часть поискового запроса.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Suggestions`: Объекта класса :class:`yandex_music.Suggestions`
|
|
|
|
|
представляющий подсказки для запроса, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
url = f'{self.base_url}/search/suggest'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, {'part': part}, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Suggestions.de_json(result, self)
|
2019-05-16 21:45:25 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 17:23:28 +09:00
|
|
|
|
def users_playlists(self, kind: str or int or list, user_id: str = None, timeout=None, *args, **kwargs):
|
2019-07-16 00:58:59 +09:00
|
|
|
|
"""Получение плейлиста или списка плейлистов по уникальным идентификаторам.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
kind (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста
|
|
|
|
|
или их список.
|
|
|
|
|
user_id: (:obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`list` из :obj:`yandex_music.Playlist`: Список объектов класса :class:`yandex_music.Playlist`
|
|
|
|
|
представляющих плейлист, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 15:04:15 +09:00
|
|
|
|
if user_id is None:
|
|
|
|
|
user_id = self.account.uid
|
|
|
|
|
|
2019-06-01 17:23:28 +09:00
|
|
|
|
url = f'{self.base_url}/users/{user_id}/playlists'
|
2019-06-01 15:04:15 +09:00
|
|
|
|
|
2019-06-01 17:23:28 +09:00
|
|
|
|
data = {
|
|
|
|
|
'kinds': kind
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = self._request.post(url, data, timeout=timeout, *args, **kwargs)
|
2019-06-01 15:04:15 +09:00
|
|
|
|
|
2019-06-01 17:23:28 +09:00
|
|
|
|
return Playlist.de_list(result, self)
|
2019-06-01 15:04:15 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 15:04:15 +09:00
|
|
|
|
def users_playlists_create(self, title: str, visibility: str = 'public', user_id: str = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-16 00:58:59 +09:00
|
|
|
|
"""Создание плейлиста.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
title (:obj:`str`): Название.
|
|
|
|
|
visibility (:obj:`str`, optional): Модификатор доступа.
|
|
|
|
|
user_id: (:obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Playlist`: Объекта класса :class:`yandex_music.Playlist`
|
|
|
|
|
представляющий созданный плейлист, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 15:04:15 +09:00
|
|
|
|
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)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 15:04:15 +09:00
|
|
|
|
def users_playlists_delete(self, kind: str or int, user_id: str = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-16 00:58:59 +09:00
|
|
|
|
"""Удаление плейлиста.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
|
|
|
|
|
user_id: (:obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 15:04:15 +09:00
|
|
|
|
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'
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 15:04:15 +09:00
|
|
|
|
def users_playlists_name(self, kind: str or int, name: str, user_id: str = None, timeout=None, *args, **kwargs):
|
2019-07-16 00:58:59 +09:00
|
|
|
|
"""Изменение названия плейлиста.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
|
|
|
|
|
name (:obj:`str`): Новое название.
|
|
|
|
|
user_id: (:obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Playlist`: Объекта класса :class:`yandex_music.Playlist`
|
|
|
|
|
представляющий изменённый плейлист, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 15:04:15 +09:00
|
|
|
|
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)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 15:04:15 +09:00
|
|
|
|
def users_playlists_change(self, kind: str or int, diff: str, revision: int = 1, user_id: str = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-16 00:58:59 +09:00
|
|
|
|
"""Изменение плейлиста.
|
|
|
|
|
|
|
|
|
|
Для получения отличий есть вспомогательный класс :class:`from yandex_music.utils.difference.Difference`.
|
|
|
|
|
Так же существуют уже готовые методы-обёртки над операциями.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
|
|
|
|
|
revision (:obj:`int`): TODO.
|
|
|
|
|
diff (:obj:`str`): JSON представления отличий старого и нового плейлиста.
|
|
|
|
|
user_id: (:obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Playlist`: Объекта класса :class:`yandex_music.Playlist`
|
|
|
|
|
представляющий изменённый плейлист, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 15:04:15 +09:00
|
|
|
|
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)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-07-16 00:58:59 +09:00
|
|
|
|
def users_playlists_insert_track(self, kind: str or int, track_id: str or int, album_id: str or int, at: int = 0,
|
|
|
|
|
revision: int = 1, user_id: str = None, timeout=None, *args, **kwargs):
|
|
|
|
|
"""Добавление трека в плейлист.
|
|
|
|
|
|
|
|
|
|
Трек можно вставить с любое место плейлиста задав индекс вставки (аргумент at).
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
|
|
|
|
|
track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека.
|
|
|
|
|
album_id (:obj:`str` | :obj:`int`): Уникальный идентификатор альбома.
|
|
|
|
|
at (:obj:`int`): Индекс для вставки.
|
|
|
|
|
revision (:obj:`int`): TODO.
|
|
|
|
|
user_id: (:obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Playlist`: Объекта класса :class:`yandex_music.Playlist`
|
|
|
|
|
представляющий изменённый плейлист, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 15:04:15 +09:00
|
|
|
|
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)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-06-01 15:04:15 +09:00
|
|
|
|
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):
|
2019-07-16 00:58:59 +09:00
|
|
|
|
"""Удаление треков из плейлиста.
|
|
|
|
|
|
|
|
|
|
Для удаление необходимо указать границы с какого по какой элемент (трек) удалить.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
|
|
|
|
|
from_ (:obj:`int`): С какого индекса.
|
|
|
|
|
to (:obj:`int`): По какой индекс.
|
|
|
|
|
revision (:obj:`int`): TODO.
|
|
|
|
|
user_id: (:obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
|
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.Playlist`: Объекта класса :class:`yandex_music.Playlist`
|
|
|
|
|
представляющий изменённый плейлист, иначе :obj:`None`.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
:class:`yandex_music.YandexMusicError`
|
|
|
|
|
"""
|
|
|
|
|
|
2019-06-01 15:04:15 +09:00
|
|
|
|
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)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_account_status(self, timeout=None, *args, **kwargs):
|
|
|
|
|
url = f'{self.base_url}/rotor/account/status'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Status.de_json(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_stations_dashboard(self, timeout=None, *args, **kwargs):
|
|
|
|
|
url = f'{self.base_url}/rotor/stations/dashboard'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return Dashboard.de_json(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_stations_list(self, language: str = 'en', timeout=None, *args, **kwargs):
|
|
|
|
|
url = f'{self.base_url}/rotor/stations/list'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, {'language': language}, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return StationResult.de_list(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_station_genre_feedback(self, genre: str, type_: str, timestamp=None, from_: str = None,
|
|
|
|
|
batch_id: str or int = None, track_id: str = None, timeout=None, *args, **kwargs):
|
|
|
|
|
if timestamp is None:
|
|
|
|
|
timestamp = datetime.now().timestamp()
|
|
|
|
|
|
|
|
|
|
url = f'{self.base_url}/rotor/station/genre:{genre}/feedback'
|
|
|
|
|
|
|
|
|
|
params = {}
|
|
|
|
|
data = {
|
|
|
|
|
'type': type_,
|
|
|
|
|
'timestamp': timestamp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if batch_id and track_id:
|
|
|
|
|
data.update({'trackId': track_id})
|
|
|
|
|
params = {'batch-id': batch_id}
|
|
|
|
|
|
|
|
|
|
if from_:
|
|
|
|
|
data.update({'from': from_})
|
|
|
|
|
|
|
|
|
|
result = self._request.post(url, params=params, json=data, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return result == 'ok'
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_station_genre_feedback_radio_started(self, genre: str, from_: str, timestamp=None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
|
|
|
|
return self.rotor_station_genre_feedback(genre, 'radioStarted', timestamp, from_, timeout, *args, **kwargs)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_station_genre_feedback_track_started(self, genre: str, track_id: str, batch_id: str or int,
|
|
|
|
|
timestamp=None, timeout=None, *args, **kwargs):
|
|
|
|
|
return self.rotor_station_genre_feedback(genre, 'trackStarted', timestamp, track_id=track_id, batch_id=batch_id,
|
|
|
|
|
timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_station_genre_info(self, genre: str, timeout=None, *args, **kwargs):
|
|
|
|
|
url = f'{self.base_url}/rotor/station/genre:{genre}/info'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return StationResult.de_list(result, self)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
New supported objects: Station, StationResult, StationTrackResult, Value, Sequence, RotorSettings, Restrictions, Id, Enum, DiscreteScale, DashBoard, AdParams
The following methods are wrapped:
- /rotor/account/status
- /rotor/stations/dashboard
- /rotor/stations/list
- /rotor/station/genre:{genre}/feedback
- /rotor/station/genre:{genre}/info
- /rotor/station/genre:{genre}/tracks
The following fields are now optional: Account[region, passport_phones], Status[cache_limit, subeditor, subeditor_level, plus], Subscription[auto_renewable, can_start_trial, mcdonalds]
Added new fields: Subscription.end, Status[skips_per_hour, station_exists, premium_region], Track..preview_duration_ms
Fixed downloading the cover of the track
2019-06-03 22:16:24 +09:00
|
|
|
|
def rotor_station_genre_tracks(self, genre: str, timeout=None, *args, **kwargs):
|
|
|
|
|
url = f'{self.base_url}/rotor/station/genre:{genre}/tracks'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return StationTracksResult.de_json(result, self)
|
|
|
|
|
|
Добавлен метод получения информации об артисте (Brief Info https://github.com/MarshalX/yandex-music-api/issues/9).
Добавлены следующие классы: BriefInfo, Description, Vinyl, PlaylistId.
Класс Video вынесен из пакета Search в корень.
Добавлен de_list в Cover.
Добавлены следующие поля в класс Artist: likes_count, full_names, description, countries, en_wikipedia_link, db_aliases, aliases, init_date, end_date.
Добавлено поле track_id в класс Chart.
Добавлено поле available_full_without_permission в класс Track.
Класс Video расширен для поддержки второго типа (используется в brief info, спасибо яндух) видео (добавлены необязательные поля cover, embed_url, provider, provider_video_id).
Обновлена документация.
2019-09-13 00:32:43 +09:00
|
|
|
|
@log
|
|
|
|
|
def artists_brief_info(self, artist_id: str or int, timeout=None, *args, **kwargs):
|
|
|
|
|
url = f'{self.base_url}/artists/{artist_id}/brief-info'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return BriefInfo.de_json(result, self)
|
|
|
|
|
|
2019-10-21 23:47:31 +09:00
|
|
|
|
@log
|
|
|
|
|
def artists_tracks(self, artist_id: str or int, page=0, page_size=20, timeout=None, *args, **kwargs):
|
2019-10-27 23:14:11 +09:00
|
|
|
|
"""Получение треков артиста.
|
2019-10-22 00:08:24 +09:00
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
artist_id (:obj:`str` | :obj:`int`): Уникальный идентификатор артиста.
|
2019-10-27 23:14:11 +09:00
|
|
|
|
page (:obj:`int`, optional): Номер страницы.
|
|
|
|
|
page_size (:obj:`int`, optional): Количество треков на странице.
|
2019-10-22 00:08:24 +09:00
|
|
|
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
|
|
|
|
ответа от сервера вместо указанного при создании пула.
|
|
|
|
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
:obj:`yandex_music.ArtistsTracks`: Объекта класса :class:`yandex_music.ArtistsTracks`
|
|
|
|
|
представляющий страницу списка треков артиста
|
|
|
|
|
"""
|
2019-10-27 23:14:11 +09:00
|
|
|
|
|
2019-10-21 23:47:31 +09:00
|
|
|
|
url = f'{self.base_url}/artists/{artist_id}/tracks'
|
2019-10-27 23:14:11 +09:00
|
|
|
|
|
2019-10-21 23:47:31 +09:00
|
|
|
|
params = {
|
|
|
|
|
'page': page,
|
|
|
|
|
'page-size': page_size
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, params, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
2019-10-27 23:14:11 +09:00
|
|
|
|
return ArtistTracks.de_json(result, self)
|
2019-10-21 23:47:31 +09:00
|
|
|
|
|
2019-07-06 17:09:47 +09:00
|
|
|
|
def _like_action(self, object_type: str, ids: str or int or list, remove: bool = False, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-05-19 05:59:14 +09:00
|
|
|
|
if user_id is None:
|
|
|
|
|
user_id = self.account.uid
|
2019-05-11 17:37:47 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
action = 'remove' if remove else 'add-multiple'
|
|
|
|
|
url = f'{self.base_url}/users/{user_id}/likes/{object_type}s/{action}'
|
2019-05-11 17:37:47 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
result = self._request.post(url, {f'{object_type}-ids': ids}, timeout=timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
if object_type == 'track':
|
|
|
|
|
return 'revision' in result
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
return result == 'ok'
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_tracks_add(self, track_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-10-06 05:30:46 +09:00
|
|
|
|
return self._like_action('track', track_ids, False, user_id, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_tracks_remove(self, track_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-06 17:09:47 +09:00
|
|
|
|
return self._like_action('track', track_ids, True, user_id, timeout, *args, **kwargs)
|
2019-05-15 05:38:15 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_artists_add(self, artist_ids: str or int or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-10-06 05:30:46 +09:00
|
|
|
|
return self._like_action('artist', artist_ids, False, user_id, timeout, *args, **kwargs)
|
2019-05-15 05:38:15 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_artists_remove(self, artist_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-06 17:09:47 +09:00
|
|
|
|
return self._like_action('artist', artist_ids, True, user_id, timeout, *args, **kwargs)
|
2019-05-15 05:38:15 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_playlists_add(self, playlist_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-10-06 05:30:46 +09:00
|
|
|
|
return self._like_action('playlist', playlist_ids, False, user_id, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_playlists_remove(self, playlist_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-06 17:09:47 +09:00
|
|
|
|
return self._like_action('playlist', playlist_ids, True, user_id, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_albums_add(self, album_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-10-06 05:30:46 +09:00
|
|
|
|
return self._like_action('album', album_ids, False, user_id, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_albums_remove(self, album_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-07-06 17:09:47 +09:00
|
|
|
|
return self._like_action('album', album_ids, True, user_id, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def _get_list(self, object_type: str, ids: list or int or str, params=None, timeout=None, *args, **kwargs):
|
|
|
|
|
if params is None:
|
|
|
|
|
params = {}
|
|
|
|
|
params.update({f'{object_type}-ids': ids})
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
url = f'{self.base_url}/{object_type}s' + ('/list' if object_type == 'playlist' else '')
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
result = self._request.post(url, params, timeout=timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
return de_list.get(object_type)(result, self)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def artists(self, artist_ids: list or int or str, timeout=None, *args, **kwargs):
|
|
|
|
|
return self._get_list('artist', artist_ids, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def albums(self, album_ids: list or int or str, timeout=None, *args, **kwargs):
|
|
|
|
|
return self._get_list('album', album_ids, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def tracks(self, track_ids: int or str, with_positions=True, timeout=None, *args, **kwargs):
|
|
|
|
|
return self._get_list('track', track_ids, {'with-positions': with_positions}, timeout, *args, **kwargs)
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def playlists_list(self, playlist_ids: list or int or str, timeout=None, *args, **kwargs):
|
|
|
|
|
return self._get_list('playlist', playlist_ids, timeout, *args, **kwargs)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_playlists_list(self, user_id: int or str = None, timeout=None, *args, **kwargs):
|
2019-05-15 05:38:15 +09:00
|
|
|
|
if user_id is None:
|
|
|
|
|
user_id = self.account.uid
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
url = f'{self.base_url}/users/{user_id}/playlists/list'
|
New supported objects: Album, CaseForms, Label, Library, MadeFor, Major, Normalization, PlayCounter, Playlist, Track, TrackPosition, TrackShort, User
The following methods are wrapped:
- albums;
- playlists/list;
- users/{user_id}/playlists/list;
- tracks;
- users/{user_id}/likes/tracks.
Added property to get full track ID
Cover received more optional fields
Ability to pass arguments to the request
Removed unnecessary type conversions
2019-05-13 02:39:12 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
2019-05-15 05:38:15 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
return Playlist.de_list(result, self)
|
|
|
|
|
|
|
|
|
|
def _get_likes(self, object_type, user_id: int or str = None, params=None, timeout=None, *args, **kwargs):
|
2019-05-15 05:38:15 +09:00
|
|
|
|
if user_id is None:
|
|
|
|
|
user_id = self.account.uid
|
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
url = f'{self.base_url}/users/{user_id}/likes/{object_type}s'
|
2019-05-15 05:38:15 +09:00
|
|
|
|
|
New supported objects: Search, Suggestions, Video, Best, AlbumSearchResult, ArtistSearchResult, PlaylistSearchResult, TrackSearchResult, VideoSearchResult,
The following methods are wrapped:
- /search
- /search/suggest
The following classes received optional fields instead of required ones: Album, Artist, Playlist, Track
Added "params" arg to the GET request
Code refactoring
2019-05-18 01:20:34 +09:00
|
|
|
|
result = self._request.get(url, params, timeout=timeout, *args, **kwargs)
|
2019-05-15 05:38:15 +09:00
|
|
|
|
|
2019-05-19 05:59:14 +09:00
|
|
|
|
if object_type == 'track':
|
2019-07-06 17:09:47 +09:00
|
|
|
|
return TracksList.de_json(result.get('library'), self)
|
2019-05-16 04:38:39 +09:00
|
|
|
|
|
2019-07-06 17:09:47 +09:00
|
|
|
|
return de_list_likes.get(object_type)(result, self)
|
2019-05-16 04:38:39 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-23 18:10:14 +09:00
|
|
|
|
def users_likes_tracks(self, user_id: int or str = None, if_modified_since_revision=0, timeout=None,
|
|
|
|
|
*args, **kwargs):
|
|
|
|
|
return self._get_likes('track', user_id, {'if-modified-since-revision': if_modified_since_revision}, timeout,
|
|
|
|
|
*args, **kwargs)
|
2019-05-16 04:38:39 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_albums(self, user_id: int or str = None, rich=True, timeout=None, *args, **kwargs):
|
|
|
|
|
return self._get_likes('album', user_id, {'rich': rich}, timeout, *args, **kwargs)
|
2019-05-16 04:38:39 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_artists(self, user_id: int or str = None, with_timestamps=True, timeout=None, *args, **kwargs):
|
|
|
|
|
return self._get_likes('artist', user_id, {'with-timestamps': with_timestamps}, timeout, *args, **kwargs)
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-05-19 05:59:14 +09:00
|
|
|
|
def users_likes_playlists(self, user_id: int or str = None, timeout=None, *args, **kwargs):
|
|
|
|
|
return self._get_likes('playlist', user_id, timeout=timeout, *args, **kwargs)
|
2019-07-06 17:09:47 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-07-06 17:09:47 +09:00
|
|
|
|
def users_dislikes_tracks(self, user_id: int or str = None, if_modified_since_revision=0,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
|
|
|
|
if user_id is None:
|
|
|
|
|
user_id = self.account.uid
|
|
|
|
|
|
|
|
|
|
url = f'{self.base_url}/users/{user_id}/dislikes/tracks'
|
|
|
|
|
|
|
|
|
|
result = self._request.get(url, {'if_modified_since_revision': if_modified_since_revision},
|
|
|
|
|
timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return TracksList.de_json(result.get('library'), self)
|
|
|
|
|
|
|
|
|
|
def _dislike_action(self, ids: str or int or list, remove: bool = False, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
|
|
|
|
if user_id is None:
|
|
|
|
|
user_id = self.account.uid
|
|
|
|
|
|
|
|
|
|
action = 'remove' if remove else 'add-multiple'
|
|
|
|
|
url = f'{self.base_url}/users/{user_id}/dislikes/tracks/{action}'
|
|
|
|
|
|
|
|
|
|
result = self._request.post(url, {f'track-ids': ids}, timeout=timeout, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
return 'revision' in result
|
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-07-06 17:09:47 +09:00
|
|
|
|
def users_dislikes_tracks_add(self, track_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
2019-10-06 05:30:46 +09:00
|
|
|
|
return self._dislike_action(track_ids, False, user_id, timeout, *args, **kwargs)
|
2019-07-06 17:09:47 +09:00
|
|
|
|
|
2019-08-25 17:49:02 +09:00
|
|
|
|
@log
|
2019-07-06 17:09:47 +09:00
|
|
|
|
def users_dislikes_tracks_remove(self, track_ids: str or list, user_id: str or int = None,
|
|
|
|
|
timeout=None, *args, **kwargs):
|
|
|
|
|
return self._dislike_action(track_ids, True, user_id, timeout, *args, **kwargs)
|
2019-08-05 05:05:17 +09:00
|
|
|
|
|
|
|
|
|
# camelCase псевдонимы
|
|
|
|
|
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`from_credentials`
|
2019-08-24 19:53:04 +09:00
|
|
|
|
fromCredentials = from_credentials
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`from_token`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
fromToken = from_token
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`generate_token_by_username_and_password`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
generateTokenByUsernameAndPassword = generate_token_by_username_and_password
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`account_status`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
accountStatus = account_status
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`permission_alerts`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
permissionAlerts = permission_alerts
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`account_experiments`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
accountExperiments = account_experiments
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`consume_promo_code`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
consumePromoCode = consume_promo_code
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`feed_wizard_is_passed`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
feedWizardIsPassed = feed_wizard_is_passed
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`tracks_download_info`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
tracksDownloadInfo = tracks_download_info
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`track_supplement`
|
2019-10-17 12:35:24 +09:00
|
|
|
|
trackSupplement = track_supplement
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`play_audio`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
playAudio = play_audio
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`albums_with_tracks`
|
2019-08-28 04:07:42 +09:00
|
|
|
|
albumsWithTracks = albums_with_tracks
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`search_suggest`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
searchSuggest = search_suggest
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylists = users_playlists
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists_create`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylistsCreate = users_playlists_create
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists_delete`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylistsDelete = users_playlists_delete
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists_name`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylistsName = users_playlists_name
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists_change`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylistsChange = users_playlists_change
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists_insert_track`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylistsInsertTrack = users_playlists_insert_track
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists_delete_track`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylistsDeleteTrack = users_playlists_delete_track
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_account_status`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorAccountStatus = rotor_account_status
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_stations_dashboard`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorStationsDashboard = rotor_stations_dashboard
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_stations_list`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorStationsList = rotor_stations_list
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_station_genre_feedback`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorStationGenreFeedback = rotor_station_genre_feedback
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_station_genre_feedback_radio_started`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorStationGenreFeedbackRadioStarted = rotor_station_genre_feedback_radio_started
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_station_genre_feedback_track_started`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorStationGenreFeedbackTrackStarted = rotor_station_genre_feedback_track_started
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_station_genre_info`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorStationGenreInfo = rotor_station_genre_info
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`rotor_station_genre_tracks`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
rotorStationGenreTracks = rotor_station_genre_tracks
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`artists_brief_info`
|
2019-10-19 05:44:17 +09:00
|
|
|
|
artistsBriefInfo = artists_brief_info
|
2019-10-22 00:29:02 +09:00
|
|
|
|
#: Псевдоним для :attr:`artists_tracks`
|
|
|
|
|
artistsTracks = artists_tracks
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_tracks_add`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesTracksAdd = users_likes_tracks_add
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_tracks_remove`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesTracksRemove = users_likes_tracks_remove
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_artists_add`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesArtistsAdd = users_likes_artists_add
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_artists_remove`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesArtistsRemove = users_likes_artists_remove
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_playlists_add`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesPlaylistsAdd = users_likes_playlists_add
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_playlists_remove`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesPlaylistsRemove = users_likes_playlists_remove
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_albums_add`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesAlbumsAdd = users_likes_albums_add
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_albums_remove`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesAlbumsRemove = users_likes_albums_remove
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`playlists_list`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
playlistsList = playlists_list
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_playlists_list`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersPlaylistsList = users_playlists_list
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_tracks`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesTracks = users_likes_tracks
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_albums`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesAlbums = users_likes_albums
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_artists`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesArtists = users_likes_artists
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_likes_playlists`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersLikesPlaylists = users_likes_playlists
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_dislikes_tracks`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersDislikesTracks = users_dislikes_tracks
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_dislikes_tracks_add`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersDislikesTracksAdd = users_dislikes_tracks_add
|
2019-10-19 17:55:45 +09:00
|
|
|
|
#: Псевдоним для :attr:`users_dislikes_tracks_remove`
|
2019-08-05 05:05:17 +09:00
|
|
|
|
usersDislikesTracksRemove = users_dislikes_tracks_remove
|