#################################################################### # THIS IS AUTO GENERATED COPY OF client.py. DON'T EDIT IN BY HANDS # #################################################################### import functools import logging from datetime import datetime from typing import Dict, List, Optional, Union, TypeVar, Callable, Any from yandex_music import ( Album, Artist, ArtistAlbums, ArtistTracks, BriefInfo, Dashboard, DownloadInfo, Experiments, Feed, Genre, Landing, Like, PermissionAlerts, Playlist, PromoCodeStatus, Search, Settings, ShotEvent, Supplement, StationResult, StationTracksResult, Status, Suggestions, SimilarTracks, TrackLyrics, Track, TracksList, UserSettings, YandexMusicObject, ChartInfo, TagResult, PlaylistRecommendations, LandingList, QueueItem, Queue, __copyright__, __license__, __version__, ) from yandex_music.exceptions import BadRequestError from yandex_music.utils.difference import Difference from yandex_music.utils.request_async import Request from yandex_music.utils.sign_request import get_sign_request de_list = { 'artist': Artist.de_list, 'album': Album.de_list, 'track': Track.de_list, 'playlist': Playlist.de_list, } logging.getLogger(__name__).addHandler(logging.NullHandler()) F = TypeVar('F', bound=Callable[..., Any]) def log(method: F) -> F: logger = logging.getLogger(method.__module__) @functools.wraps(method) async def wrapper(*args, **kwargs) -> Any: logger.debug(f'Entering: {method.__name__}') result = await method(*args, **kwargs) logger.debug(result) logger.debug(f'Exiting: {method.__name__}') return result return wrapper class ClientAsync(YandexMusicObject): """Класс, представляющий клиент Yandex Music. Note: Доступные языки: en, uz, uk, us, ru, kk, hy. Поле `device` используется только при работе с очередью прослушивания. Attributes: logger (:obj:`logging.Logger`): Объект логгера. token (:obj:`str`): Уникальный ключ для аутентификации. base_url (:obj:`str`): Ссылка на API Yandex Music. me (:obj:`yandex_music.Status`): Информация об аккаунте. device (:obj:`str`): Строка, содержащая сведения об устройстве, с которого выполняются запросы. report_unknown_fields (:obj:`bool`): Включены ли предупреждения о неизвестных полях от API, которых нет в библиотеке. Args: token (:obj:`str`, optional): Уникальный ключ для аутентификации. base_url (:obj:`str`, optional): Ссылка на API Yandex Music. request (:obj:`yandex_music.utils.request.Request`, optional): Пре-инициализация :class:`yandex_music.utils.request.Request`. language (:obj:`str`, optional): Язык, на котором будут приходить ответы от API. По умолчанию русский. report_unknown_fields (:obj:`bool`, optional): Включить предупреждения о неизвестных полях от API, которых нет в библиотеке. """ __notice_displayed = False def __init__( self, token: str = None, base_url: str = None, request: Request = None, language: str = 'ru', report_unknown_fields=False, ) -> None: if not ClientAsync.__notice_displayed: print(f'Yandex Music API v{__version__}, {__copyright__}') print(f'Licensed under the terms of the {__license__}', end='\n\n') ClientAsync.__notice_displayed = True self.logger = logging.getLogger(__name__) self.token = token if base_url is None: base_url = 'https://api.music.yandex.net' self.base_url = base_url self.report_unknown_fields = report_unknown_fields if request: self._request = request self._request.set_and_return_client(self) else: self._request = Request(self) self.language = language self._request.set_language(self.language) self.device = ( 'os=Python; os_version=; manufacturer=Marshal; ' 'model=Yandex Music API; clid=; device_id=random; uuid=random' ) self.me = None @property def request(self) -> Request: """:obj:`yandex_music.utils.request.Request`: Объект вспомогательного класса для отправки запросов.""" return self._request @log async def init(self): """Получение информацию об аккаунте использующихся в других запросах.""" self.me = await self.account_status() return self @log async def account_status(self, *args, **kwargs) -> Optional[Status]: """Получение статуса аккаунта. Нет обязательных параметров. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Status` | :obj:`None`: Информация об аккаунте если он валиден, иначе :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/account/status' result = await self._request.get(url, *args, **kwargs) return Status.de_json(result, self) @log async def account_settings(self, *args, **kwargs) -> Optional[UserSettings]: """Получение настроек текущего пользователя. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.UserSettings` | :obj:`None`: Настройки пользователя если аккаунт валиден, иначе :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/account/settings' result = await self._request.get(url, *args, **kwargs) return UserSettings.de_json(result, self) @log async def account_settings_set( self, param: str = None, value: Union[str, int, bool] = None, data: Dict[str, Union[str, int, bool]] = None, *args, **kwargs, ) -> Optional[UserSettings]: """Изменение настроек текущего пользователя. Note: Доступные названия параметров есть поля в классе :class:`yandex_music.UserSettings`, только в CamelCase. Args: param (:obj:`str`): Название параметра для изменения. value (:obj:`str` | :obj:`int` | :obj:`bool`): Значение параметра. data (:obj:`dict`): Словарь параметров и значений для множественного изменения. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.UserSettings` | :obj:`None`: Настройки пользователя или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/account/settings' if not data: data = {param: str(value)} result = await self._request.post(url, data, *args, **kwargs) return UserSettings.de_json(result, self) @log async def settings(self, *args, **kwargs) -> Optional[Settings]: """Получение предложений по покупке. Нет обязательных параметров. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Settings` | :obj:`None`: Информацию о предлагаемых продуктах если аккаунт валиден или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/settings' result = await self._request.get(url, *args, **kwargs) return Settings.de_json(result, self) @log async def permission_alerts(self, *args, **kwargs) -> Optional[PermissionAlerts]: """Получение оповещений. Нет обязательных параметров. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.PermissionAlerts` | :obj:`None`: Оповещения если аккаунт валиден или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/permission-alerts' result = await self._request.get(url, *args, **kwargs) return PermissionAlerts.de_json(result, self) @log async def account_experiments(self, *args, **kwargs) -> Optional[Experiments]: """Получение значений экспериментальных функций аккаунта. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Experiments` | :obj:`None`: Состояние экспериментальных функций или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/account/experiments' result = await self._request.get(url, *args, **kwargs) return Experiments.de_json(result, self) @log async def consume_promo_code( self, code: str, language: Optional[str] = None, *args, **kwargs ) -> Optional[PromoCodeStatus]: """Активация промо-кода. Note: Доступные языки: en, uz, uk, us, ru, kk, hy. Args: code (:obj:`str`): Промо-код. language (:obj:`str`, optional): Язык ответа API в ISO 639-1. По умолчанию язык клиента. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.PromoCodeStatus` | :obj:`None`: Информация об активации промо-кода или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/account/consume-promo-code' if not language: language = self.language result = await self._request.post(url, {'code': code, 'language': language}, *args, **kwargs) return PromoCodeStatus.de_json(result, self) @log async def feed(self, *args, **kwargs) -> Optional[Feed]: """Получение потока информации (фида) подобранного под пользователя. Содержит умные плейлисты. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Feed` | :obj:`None`: Умные плейлисты пользователя или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/feed' result = await self._request.get(url, *args, **kwargs) return Feed.de_json(result, self) @log async def feed_wizard_is_passed(self, *args, **kwargs) -> bool: url = f'{self.base_url}/feed/wizard/is-passed' result = await self._request.get(url, *args, **kwargs) return result.get('is_wizard_passed') or False @log async def landing(self, blocks: Union[str, List[str]], *args, **kwargs) -> Optional[Landing]: """Получение лендинг-страницы содержащий блоки с новыми релизами, чартами, плейлистами с новинками и т.д. Note: Поддерживаемые типы блоков: `personalplaylists`, `promotions`, `new-releases`, `new-playlists`, `mixes`, `chart`, `artists`, `albums`, `playlists`, `play_contexts`. Args: blocks (:obj:`str` | :obj:`list` из :obj:`str`): Блок или список блоков необходимых для выдачи. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Landing` | :obj:`None`: Лендинг-страница или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/landing3' result = await self._request.get( url, {'blocks': blocks, 'eitherUserId': '10254713668400548221'}, *args, **kwargs ) # TODO (MarshalX) что тут делает константа с чьим-то User ID # https://github.com/MarshalX/yandex-music-api/issues/553 return Landing.de_json(result, self) @log async def chart(self, chart_option: str = '', *args, **kwargs) -> Optional[ChartInfo]: """Получение чарта. Note: `chart_option` - это постфикс к запросу из поля `menu` чарта. Например, на сайте можно выбрать глобальный (world) чарт или российский (russia). Args: chart_option (:obj:`str` optional): Параметры чарта. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.ChartInfo`: Чарт. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/landing3/chart' if chart_option: url = f'{url}/{chart_option}' result = await self._request.get(url, *args, **kwargs) return ChartInfo.de_json(result, self) @log async def new_releases(self, *args, **kwargs) -> Optional[LandingList]: """Получение полного списка всех новых релизов (альбомов). Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.LandingList`: Список новых альбомов. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/landing3/new-releases' result = await self._request.get(url, *args, **kwargs) return LandingList.de_json(result, self) @log async def new_playlists(self, *args, **kwargs) -> Optional[LandingList]: """Получение полного списка всех новых плейлистов. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.LandingList`: Список новых плейлистов. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/landing3/new-playlists' result = await self._request.get(url, *args, **kwargs) return LandingList.de_json(result, self) @log async def podcasts(self, *args, **kwargs) -> Optional[LandingList]: """Получение подкастов с лендинга. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.LandingList`: Список подкастов. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/landing3/podcasts' result = await self._request.get(url, *args, **kwargs) return LandingList.de_json(result, self) @log async def genres(self, *args, **kwargs) -> List[Genre]: """Получение жанров музыки. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Genre` | :obj:`None`: Жанры музыки или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/genres' result = await self._request.get(url, *args, **kwargs) return Genre.de_list(result, self) @log async def tags(self, tag_id: str, *args, **kwargs) -> Optional[TagResult]: """Получение тега (подборки). Note: Теги есть в `MixLink` у `Landing`, а также плейлистов в `.tags`. У `MixLink` есть `URL`, но `tag_id` только его последняя часть. Например, `/tag/belarus/`. `Tag` - `belarus`. Args: tag_id (:obj:`str`): Уникальный идентификатор тега. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.TagResult`: Тег с плейлистами. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/tags/{tag_id}/playlist-ids' result = await self._request.get(url, *args, **kwargs) return TagResult.de_json(result, self) @log async def tracks_download_info( self, track_id: Union[str, int], get_direct_links: bool = False, *args, **kwargs, ) -> List[DownloadInfo]: """Получение информации о доступных вариантах загрузки трека. Args: track_id (:obj:`str` | :obj:`list` из :obj:`str`): Уникальный идентификатор трека или треков. get_direct_links (:obj:`bool`, optional): Получить ли при вызове метода прямую ссылку на загрузку. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.DownloadInfo` | :obj:`None`: Варианты загрузки трека или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/tracks/{track_id}/download-info' result = await self._request.get(url, *args, **kwargs) return await DownloadInfo.de_list_async(result, self, get_direct_links) @log async def track_supplement(self, track_id: Union[str, int], *args, **kwargs) -> Optional[Supplement]: """Получение дополнительной информации о треке. Warning: Получение текста из дополнительной информации устарело. Используйте :func:`yandex_music.ClientAsync.tracks_lyrics`. Args: track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Supplement`: Дополнительная информация о треке. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/tracks/{track_id}/supplement' result = await self._request.get(url, *args, **kwargs) return Supplement.de_json(result, self) @log async def tracks_lyrics( self, track_id: Union[str, int], format: str = 'TEXT', **kwargs, ) -> Optional[TrackLyrics]: """Получение текста трека. Note: Для работы с методом необходима авторизация. Известные значения для аргумента format: - `LRC` - формат с временными метками. - `TEXT` - простой текст. Args: track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека. format (:obj:`str`): Формат текста. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.TrackLyrics` | :obj:`None`: Информация о тексте трека. Raises: :class:`yandex_music.exceptions.UnauthorizedError`: Метод вызван без авторизации. :class:`yandex_music.exceptions.NotFoundError`: Текст у трека отсутствует. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/tracks/{track_id}/lyrics' sign = get_sign_request(track_id) params = { 'format': format, 'timeStamp': sign.timestamp, 'sign': sign.value, } result = await self._request.get(url, params=params, **kwargs) return TrackLyrics.de_json(result, self) @log async def tracks_similar(self, track_id: Union[str, int], *args, **kwargs) -> Optional[SimilarTracks]: """Получение похожих треков. Args: track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.SimilarTracks`: Похожие треки на другой трек. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/tracks/{track_id}/similar' result = await self._request.get(url, *args, **kwargs) return SimilarTracks.de_json(result, self) @log async def play_audio( self, track_id: Union[str, int], from_: str, album_id: Union[str, 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, *args, **kwargs, ) -> bool: """Метод для отправки текущего состояния прослушиваемого трека. 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. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if uid is None and self.me is not None: uid = self.me.account.uid url = f'{self.base_url}/play-audio' data = { 'track-id': track_id, 'from-cache': str(from_cache), 'from': from_, 'play-id': play_id or '', 'uid': 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', } result = await self._request.post(url, data, *args, **kwargs) return result == 'ok' @log async def albums_with_tracks(self, album_id: Union[str, int], *args, **kwargs) -> Optional[Album]: """Получение альбома по его уникальному идентификатору вместе с треками. Args: album_id (:obj:`str` | :obj:`int`): Уникальный идентификатор альбома. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Album` | :obj:`None`: Альбом или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/albums/{album_id}/with-tracks' result = await self._request.get(url, *args, **kwargs) return Album.de_json(result, self) @log async def search( self, text: str, nocorrect: bool = False, type_: str = 'all', page: int = 0, playlist_in_best: bool = True, *args, **kwargs, ) -> Optional[Search]: """Осуществление поиска по запросу и типу, получение результатов. Note: Известные значения для поля `type_`: `all`, `artist`, `user`, `album`, `playlist`, `track`, `podcast`, `podcast_episode`. При поиске `type=all` не возвращаются подкасты и эпизоды. Указывайте конкретный тип для поиска. Args: text (:obj:`str`): Текст запроса. nocorrect (:obj:`bool`): Если :obj:`False`, то ошибочный запрос будет исправлен. Например, запрос "Гражданская абарона" будет исправлен на "Гражданская оборона". type_ (:obj:`str`): Среди какого типа искать (трек, плейлист, альбом, исполнитель, пользователь, подкаст). page (:obj:`int`): Номер страницы. playlist_in_best (:obj:`bool`): Выдавать ли плейлисты лучшим вариантом поиска. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Search` | :obj:`None`: Результаты поиска или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/search' params = { 'text': text, 'nocorrect': str(nocorrect), 'type': type_, 'page': page, 'playlist-in-best': str(playlist_in_best), } result = await self._request.get(url, params, *args, **kwargs) if isinstance(result, str): raise BadRequestError(result) return Search.de_json(result, self) @log async def search_suggest(self, part: str, *args, **kwargs) -> Optional[Suggestions]: """Получение подсказок по введенной части поискового запроса. Args: part (:obj:`str`): Часть поискового запроса. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Suggestions` | :obj:`None`: Подсказки для запроса или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/search/suggest' result = await self._request.get(url, {'part': part}, *args, **kwargs) return Suggestions.de_json(result, self) @log async def users_settings(self, user_id: Union[str, int] = None, *args, **kwargs) -> Optional[UserSettings]: """Получение настроек пользователя. Note: Для получения настроек пользователя нужно быть авторизованным или владеть `user_id`. Args: user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя чьи настройки хотим получить. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.UserSettings` | :obj:`None`: Настройки пользователя или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/settings' result = await self._request.get(url, *args, **kwargs) return UserSettings.de_json(result.get('user_settings'), self) @log async def users_playlists( self, kind: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, *args, **kwargs, ) -> Union[Playlist, List[Playlist]]: """Получение плейлиста или списка плейлистов по уникальным идентификаторам. Note: Если передан один `kind`, то вернётся не список плейлистов, а один плейлист. Args: kind (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста или их список. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Playlist` | :obj:`yandex_music.Playlist` | :obj:`None`: Список плейлистов или плейлист, иначе :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid if isinstance(kind, list): url = f'{self.base_url}/users/{user_id}/playlists' data = {'kinds': kind} result = await self._request.post(url, data, *args, **kwargs) return Playlist.de_list(result, self) else: url = f'{self.base_url}/users/{user_id}/playlists/{kind}' result = await self._request.get(url, *args, **kwargs) return Playlist.de_json(result, self) @log async def users_playlists_recommendations( self, kind: Union[str, int], user_id: Union[str, int] = None, *args, **kwargs ): """Получение рекомендаций для плейлиста. Args: kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста. user_id (:obj:`str` | :obj:`int`): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.PlaylistRecommendations` | :obj:`None`: Рекомендации для плейлиста или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/playlists/{kind}/recommendations' result = await self._request.get(url, *args, **kwargs) return PlaylistRecommendations.de_json(result, self) @log async def users_playlists_create( self, title: str, visibility: str = 'public', user_id: Union[str, int] = None, *args, **kwargs, ) -> Optional[Playlist]: """Создание плейлиста. Args: title (:obj:`str`): Название. visibility (:obj:`str`, optional): Модификатор доступа. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Playlist` | :obj:`None`: Созданный плейлист или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/playlists/create' data = {'title': title, 'visibility': visibility} result = await self._request.post(url, data, *args, **kwargs) return Playlist.de_json(result, self) @log async def users_playlists_delete( self, kind: Union[str, int], user_id: Union[str, int] = None, *args, **kwargs ) -> bool: """Удаление плейлиста. Args: kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/playlists/{kind}/delete' result = await self._request.post(url, *args, **kwargs) return result == 'ok' @log async def users_playlists_name( self, kind: Union[str, int], name: str, user_id: Union[str, int] = None, *args, **kwargs, ) -> Optional[Playlist]: """Изменение названия плейлиста. Args: kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста. name (:obj:`str`): Новое название. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Playlist` | :obj:`None`: Изменённый плейлист или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/playlists/{kind}/name' result = await self._request.post(url, {'value': name}, *args, **kwargs) return Playlist.de_json(result, self) @log async def users_playlists_visibility( self, kind: Union[str, int], visibility: str, user_id: Union[str, int] = None, *args, **kwargs, ) -> Optional[Playlist]: """Изменение видимости плейлиста. Note: Видимость (`visibility`) может быть задана только одним из двух значений: `private`, `public`. Args: kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста. visibility (:obj:`str`): Новое название. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Playlist` | :obj:`None`: Изменённый плейлист или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/playlists/{kind}/visibility' result = await self._request.post(url, {'value': visibility}, *args, **kwargs) return Playlist.de_json(result, self) @log async def users_playlists_change( self, kind: Union[str, int], diff: str, revision: int = 1, user_id: Union[str, int] = None, *args, **kwargs, ) -> Optional[Playlist]: """Изменение плейлиста. Note: Для получения отличий есть вспомогательный класс :class:`yandex_music.utils.difference.Difference`. Так же существуют уже готовые методы-обёртки над операциями. Args: kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста. revision (:obj:`int`): TODO. diff (:obj:`str`): JSON представления отличий старого и нового плейлиста. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Playlist`: Изменённый плейлист или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/playlists/{kind}/change' data = {'kind': kind, 'revision': revision, 'diff': diff} result = await self._request.post(url, data, *args, **kwargs) return Playlist.de_json(result, self) @log async def users_playlists_insert_track( self, kind: Union[str, int], track_id: Union[str, int], album_id: Union[str, int], at: int = 0, revision: int = 1, user_id: Union[str, int] = None, *args, **kwargs, ) -> Optional[Playlist]: """Добавление трека в плейлист. Note: Трек можно вставить с любое место плейлиста задав индекс вставки (аргумент `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:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Playlist`: Изменённый плейлист или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid diff = Difference().add_insert(at, {'id': track_id, 'album_id': album_id}) return await self.users_playlists_change(kind, diff.to_json(), revision, user_id, *args, **kwargs) @log async def users_playlists_delete_track( self, kind: Union[str, int], from_: int, to: int, revision: int = 1, user_id: Union[str, int] = None, *args, **kwargs, ) -> Optional[Playlist]: """Удаление треков из плейлиста. Note: Для удаление необходимо указать границы с какого по какой элемент (трек) удалить. Args: kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста. from_ (:obj:`int`): С какого индекса. to (:obj:`int`): По какой индекс. revision (:obj:`int`): TODO. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Playlist` | :obj:`None`: Изменённый плейлист или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid diff = Difference().add_delete(from_, to) return await self.users_playlists_change(kind, diff.to_json(), revision, user_id, *args, **kwargs) @log async def rotor_account_status(self, *args, **kwargs) -> Optional[Status]: """Получение статуса пользователя с дополнительными полями. Note: Данный статус отличается от обычного наличием дополнительных полей, например, `skips_per_hour`. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Status` | :obj:`None`: Статус пользователя с дополнительными полями от радио или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/rotor/account/status' result = await self._request.get(url, *args, **kwargs) return Status.de_json(result, self) @log async def rotor_stations_dashboard(self, *args, **kwargs) -> Optional[Dashboard]: """Получение рекомендованных станций текущего пользователя. Args: **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Dashboard` | :obj:`None`: Рекомендованные станции или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/rotor/stations/dashboard' result = await self._request.get(url, *args, **kwargs) return Dashboard.de_json(result, self) @log async def rotor_stations_list(self, language: Optional[str] = None, *args, **kwargs) -> List[StationResult]: """Получение всех радиостанций с настройками пользователя. Note: Доступные языки: en, uz, uk, us, ru, kk, hy. Чтобы определить что за тип станции (жанры, настроения, занятие и т.д.) необходимо смотреть в поле `id_for_from`. Args: language (:obj:`str`, optional): Язык, на котором будет информация о станциях. По умолчанию язык клиента. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.StationResult`: Список станций. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/rotor/stations/list' if not language: language = self.language result = await self._request.get(url, {'language': language}, *args, **kwargs) return StationResult.de_list(result, self) @log async def rotor_station_feedback( self, station: str, type_: str, timestamp: Union[str, float, int] = None, from_: str = None, batch_id: str = None, total_played_seconds: Union[int, float] = None, track_id: Union[str, int] = None, **kwargs, ) -> bool: """Отправка обратной связи на действия при прослушивании радио. Note: Сообщения о начале прослушивания радио, начале и конце трека, его пропуска. Известные типы обратной связи: `radioStarted`, `trackStarted`, `trackFinished`, `skip`. Пример `station`: `user:onyourwave`, `genre:allrock`. Пример `from_`: `mobile-radio-user-123456789`. Args: station (:obj:`str`): Станция. type_ (:obj:`str`): Тип отправляемого отзыва. timestamp (:obj:`str` | :obj:`float` | :obj:`int`, optional): Текущее время и дата. from_ (:obj:`str`, optional): Откуда начато воспроизведение радио. batch_id (:obj:`str`, optional): Уникальный идентификатор партии треков. Возвращается при получении треков. total_played_seconds (:obj:`int` |:obj:`float`, optional): Сколько было проиграно секунд трека перед действием. track_id (:obj:`int` | :obj:`str`, optional): Уникальной идентификатор трека. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if timestamp is None: timestamp = datetime.now().timestamp() url = f'{self.base_url}/rotor/station/{station}/feedback' params = {} data = {'type': type_, 'timestamp': timestamp} if batch_id: params = {'batch-id': batch_id} if track_id: data.update({'trackId': track_id}) if from_: data.update({'from': from_}) if total_played_seconds: data.update({'totalPlayedSeconds': total_played_seconds}) result = await self._request.post(url, params=params, json=data, **kwargs) return result == 'ok' @log async def rotor_station_feedback_radio_started( self, station: str, from_: str, batch_id: str = None, timestamp: Union[str, float, int] = None, **kwargs, ) -> bool: """Сокращение для:: client.rotor_station_feedback(station, 'radioStarted', timestamp, from, batch_id, **kwargs) Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self.rotor_station_feedback( station, 'radioStarted', timestamp, from_=from_, batch_id=batch_id, **kwargs ) @log async def rotor_station_feedback_track_started( self, station: str, track_id: Union[str, int], batch_id: str = None, timestamp: Union[str, float, int] = None, **kwargs, ) -> bool: """Сокращение для:: client.rotor_station_feedback(station, 'trackStarted', timestamp, track_id=track_id, batch_id=batch_id, **kwargs) Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self.rotor_station_feedback( station, 'trackStarted', timestamp, track_id=track_id, batch_id=batch_id, **kwargs ) @log async def rotor_station_feedback_track_finished( self, station: str, track_id: Union[str, int], total_played_seconds: float, batch_id: str = None, timestamp: Union[str, float, int] = None, **kwargs, ) -> bool: """Сокращение для:: client.rotor_station_feedback(station, 'trackFinished', timestamp, track_id=track_id, total_played_seconds=total_played_seconds, batch_id=batch_id, **kwargs) Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self.rotor_station_feedback( station, 'trackFinished', timestamp, track_id=track_id, total_played_seconds=total_played_seconds, batch_id=batch_id, **kwargs, ) @log async def rotor_station_feedback_skip( self, station: str, track_id: Union[str, int], total_played_seconds: float, batch_id: str = None, timestamp: Union[str, float, int] = None, **kwargs, ) -> bool: """Сокращение для:: client.rotor_station_feedback(station, 'skip', timestamp, track_id=track_id, total_played_seconds=total_played_seconds, batch_id=batch_id, **kwargs) Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self.rotor_station_feedback( station, 'skip', timestamp, track_id=track_id, total_played_seconds=total_played_seconds, batch_id=batch_id, **kwargs, ) @log async def rotor_station_info(self, station: str, *args, **kwargs) -> List[StationResult]: """Получение информации о станции и пользовательских настроек на неё. Args: station (:obj:`str`): Станция. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.StationResult` | :obj:`None`: Информация о станции или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/rotor/station/{station}/info' result = await self._request.get(url, *args, **kwargs) return StationResult.de_list(result, self) @log async def rotor_station_settings2( self, station: str, mood_energy: str, diversity: str, language: str = 'not-russian', # TODO(#555): заменить на any type_: str = 'rotor', **kwargs, ) -> bool: """Изменение настроек определённой станции. Note: Доступные значения для `mood_energy`: `fun`, `active`, `calm`, `sad`, `all`. Доступные значения для `diversity`: `favorite`, `popular`, `discover`, `default`. Доступные значения для `language`: `not-russian`, `russian`, `any`. Доступные значения для `type_`: `rotor`, `generative`. У станций в `restrictions` есть Enum'ы, а в них `possible_values` - доступные значения для поля. Args: station (:obj:`str`): Станция. mood_energy (:obj:`str`): Настроение. diversity (:obj:`str`): Треки. language (:obj:`str`): Язык. type_ (:obj:`str`): Тип. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/rotor/station/{station}/settings3' data = {'moodEnergy': mood_energy, 'diversity': diversity, 'type': type_} if language: data.update({'language': language}) result = await self._request.post(url, json=data, **kwargs) return result == 'ok' @log async def rotor_station_tracks( self, station: str, settings2: bool = True, queue: Union[str, int] = None, *args, **kwargs, ) -> Optional[StationTracksResult]: """Получение цепочки треков определённой станции. Note: Запуск потока по сущности сервиса осуществляется через станцию `:`. Например, станцией для запуска потока по треку будет `track:1234`. Для продолжения цепочки треков необходимо: 1. Передавать `ID` трека, что был до этого (первый в цепочки). 2. Отправить фидбек о конце или скипе трека, что был передан в `queue`. 3. Отправить фидбек о начале следующего трека (второй в цепочки). 4. Выполнить запрос получения треков. В ответе придёт новые треки или произойдёт сдвиг цепочки на 1 элемент. Проход по цепочке до конца не изучен. Часто встречаются дубликаты. Все официальные клиенты выполняют запросы с `settings2 = True`. Args: station (:obj:`str`): Станция. settings2 (:obj:`bool`, optional): Использовать ли второй набор настроек. queue (:obj:`str` | :obj:`int` , optional): Уникальной идентификатор трека, который только что был. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.StationTracksResult` | :obj:`None`: Последовательность треков станции или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/rotor/station/{station}/tracks' params = {} if settings2: params = {'settings2': str(True)} if queue: params = {'queue': queue} result = await self._request.get(url, params, *args, **kwargs) return StationTracksResult.de_json(result, self) @log async def artists_brief_info(self, artist_id: Union[str, int], *args, **kwargs) -> Optional[BriefInfo]: """Получение информации об артисте. Args: artist_id (:obj:`str` | :obj:`int`): Уникальный идентификатор исполнителя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.BriefInfo` | :obj:`None`: Информация об артисте или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/artists/{artist_id}/brief-info' result = await self._request.get(url, *args, **kwargs) return BriefInfo.de_json(result, self) @log async def artists_tracks( self, artist_id: Union[str, int], page: int = 0, page_size: int = 20, *args, **kwargs, ) -> Optional[ArtistTracks]: """Получение треков артиста. Args: artist_id (:obj:`str` | :obj:`int`): Уникальный идентификатор артиста. page (:obj:`int`, optional): Номер страницы. page_size (:obj:`int`, optional): Количество треков на странице. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.ArtistsTracks` | :obj:`None`: Страница списка треков артиста или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/artists/{artist_id}/tracks' params = {'page': page, 'page-size': page_size} result = await self._request.get(url, params, *args, **kwargs) return ArtistTracks.de_json(result, self) @log async def artists_direct_albums( self, artist_id: Union[str, int], page: int = 0, page_size: int = 20, sort_by: str = 'year', *args, **kwargs, ) -> Optional[ArtistAlbums]: """Получение альбомов артиста. Note: Известные значения для `sort_by`: `year`, `rating`. Args: artist_id (:obj:`str` | :obj:`int`): Уникальный идентификатор артиста. page (:obj:`int`, optional): Номер страницы. page_size (:obj:`int`, optional): Количество альбомов на странице. sort_by (:obj:`str`, optional): Параметр для сортировки. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.ArtistAlbums` | :obj:`None`: Страница списка альбомов артиста или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/artists/{artist_id}/direct-albums' params = {'sort-by': sort_by, 'page': page, 'page-size': page_size} result = await self._request.get(url, params, *args, **kwargs) return ArtistAlbums.de_json(result, self) async def _like_action( self, object_type: str, ids: Union[List[Union[str, int]], str, int], remove: bool = False, user_id: Union[str, int] = None, *args, **kwargs, ) -> bool: """Действия с отметкой "Мне нравится". Note: Типы объектов: `track` - трек, `artist` - исполнитель, `playlist` - плейлист, `album` - альбом. Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста. Args: object_type (:obj:`str`): Тип объекта. ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор объекта или объектов. remove (:obj:`bool`, optional): Если :obj:`True` то снимает отметку, иначе ставит. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid action = 'remove' if remove else 'add-multiple' url = f'{self.base_url}/users/{user_id}/likes/{object_type}s/{action}' result = await self._request.post(url, {f'{object_type}-ids': ids}, *args, **kwargs) if object_type == 'track': return 'revision' in result return result == 'ok' @log async def users_likes_tracks_add( self, track_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Поставить отметку "Мне нравится" треку/трекам. Note: Так же снимает отметку "Не рекомендовать" если она есть. Args: track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор трека или треков. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('track', track_ids, remove=False, user_id=user_id, **kwargs) @log async def users_likes_tracks_remove( self, track_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Снять отметку "Мне нравится" у трека/треков. Args: track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор трека или треков. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('track', track_ids, remove=True, user_id=user_id, **kwargs) @log async def users_likes_artists_add( self, artist_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Поставить отметку "Мне нравится" исполнителю/исполнителям. Args: artist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор артиста или артистов. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('artist', artist_ids, remove=False, user_id=user_id, **kwargs) @log async def users_likes_artists_remove( self, artist_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Снять отметку "Мне нравится" у исполнителя/исполнителей. Args: artist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор артиста или артистов. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('artist', artist_ids, remove=True, user_id=user_id, **kwargs) @log async def users_likes_playlists_add( self, playlist_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Поставить отметку "Мне нравится" плейлисту/плейлистам. Note: Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста. Args: playlist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор плейлиста или плейлистов. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('playlist', playlist_ids, remove=False, user_id=user_id, **kwargs) @log async def users_likes_playlists_remove( self, playlist_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Снять отметку "Мне нравится" у плейлиста/плейлистов. Note: Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста. Args: playlist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор плейлиста или плейлистов. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('playlist', playlist_ids, remove=True, user_id=user_id, **kwargs) @log async def users_likes_albums_add( self, album_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Поставить отметку "Мне нравится" альбому/альбомам. Args: album_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор артиста или артистов. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('album', album_ids, remove=False, user_id=user_id, **kwargs) @log async def users_likes_albums_remove( self, album_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Снять отметку "Мне нравится" у альбома/альбомов. Args: album_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор артиста или артистов. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._like_action('album', album_ids, remove=True, user_id=user_id, **kwargs) async def _get_list( self, object_type: str, ids: Union[List[Union[str, int]], int, str], params: dict = None, *args, **kwargs, ) -> List[Union[Artist, Album, Track, Playlist]]: """Получение объекта/объектов. Args: object_type (:obj:`str`): Тип объекта. ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор объекта или объектов. params (:obj:`dict`, optional): Параметры, которые будут переданы в запрос. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Artist` | :obj:`list` из :obj:`yandex_music.Album` | :obj:`list` из :obj:`yandex_music.Track` | :obj:`list` из :obj:`yandex_music.Playlist`: Запрошенный объект. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if params is None: params = {} params.update({f'{object_type}-ids': ids}) url = f'{self.base_url}/{object_type}s' + ('/list' if object_type == 'playlist' else '') result = await self._request.post(url, params, *args, **kwargs) return de_list[object_type](result, self) @log async def artists(self, artist_ids: Union[List[Union[str, int]], int, str], *args, **kwargs) -> List[Artist]: """Получение исполнителя/исполнителей. Args: artist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор исполнителя или исполнителей. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Artist`: Исполнитель или исполнители. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_list('artist', artist_ids, *args, **kwargs) @log async def albums(self, album_ids: Union[List[Union[str, int]], int, str], *args, **kwargs) -> List[Album]: """Получение альбома/альбомов. Args: album_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор альбома или альбомов. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Album`: Альбом или альбомы. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_list('album', album_ids, *args, **kwargs) @log async def tracks( self, track_ids: Union[List[Union[str, int]], int, str], with_positions: bool = True, *args, **kwargs, ) -> List[Track]: """Получение трека/треков. Args: track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор трека или треков. with_positions (:obj:`bool`, optional): С позициями TODO. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Track`: Трек или Треки. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_list('track', track_ids, {'with-positions': str(with_positions)}, *args, **kwargs) @log async def playlists_list( self, playlist_ids: Union[List[Union[str, int]], int, str], *args, **kwargs ) -> List[Playlist]: """Получение плейлиста/плейлистов. Note: Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста. Данный метод возвращает сокращенную модель плейлиста для отображения больших список. Warning: Данный метод не возвращает список треков у плейлиста! Для получения объекта :obj:`yandex_music.Playlist` c заполненным полем `tracks` используйте метод :func:`yandex_music.ClientAsync.users_playlists` или метод :func:`yandex_music.Playlist.fetch_tracks`. Args: playlist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор плейлиста или плейлистов. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Playlist`: Плейлист или плейлисты. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_list('playlist', playlist_ids, *args, **kwargs) @log async def playlists_collective_join(self, user_id: int, token: str, **kwargs) -> bool: """Присоединение к плейлисту как соавтор. Note: В качестве `user_id` принимается исключительно числовой уникальный идентификатор пользователя, не username. Токен можно получить в Web-версии. Для этого, на странице плейлиста нужно нажать на "Добавить соавтора". В полученной ссылке GET параметр `token` и будет токеном для присоединения. Args: user_id (:obj:`int`): Владелец плейлиста. token (:obj:`str`): Токен для присоединения. **kwargs: Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/playlists/collective/join' params = {'uid': user_id, 'token': token} result = await self._request.post(url, params=params, **kwargs) return result == 'ok' @log async def users_playlists_list(self, user_id: Union[str, int] = None, *args, **kwargs) -> List[Playlist]: """Получение списка плейлистов пользователя. Args: user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Playlist`: Плейлисты пользователя. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/playlists/list' result = await self._request.get(url, *args, **kwargs) return Playlist.de_list(result, self) async def _get_likes( self, object_type: str, user_id: Union[str, int] = None, params: dict = None, *args, **kwargs, ) -> Union[List[Like], Optional[TracksList]]: """Получение объектов с отметкой "Мне нравится". Args: object_type (:obj:`str`): Тип объекта. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. params (:obj:`dict`, optional): Параметры, которые будут переданы в запрос. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Like` | :obj:`yandex_music.TracksList`: Объекты с отметкой "Мне нравится". Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/likes/{object_type}s' result = await self._request.get(url, params, *args, **kwargs) if object_type == 'track': return TracksList.de_json(result.get('library'), self) return Like.de_list(result, self, object_type) @log async def users_likes_tracks( self, user_id: Union[str, int] = None, if_modified_since_revision: int = 0, *args, **kwargs, ) -> Optional[TracksList]: """Получение треков с отметкой "Мне нравится". Args: user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. if_modified_since_revision (:obj:`int`, optional): TODO. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.TracksList`: Треки с отметкой "Мне нравится". Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_likes( 'track', user_id, {'if-modified-since-revision': if_modified_since_revision}, *args, **kwargs ) @log async def users_likes_albums( self, user_id: Union[str, int] = None, rich: bool = True, *args, **kwargs ) -> List[Like]: """Получение альбомов с отметкой "Мне нравится". Args: user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. rich (:obj:`bool`, optional): Если False, то приходит укороченная версия. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Like`: Альбомы с отметкой "Мне нравится". Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_likes('album', user_id, {'rich': str(rich)}, *args, **kwargs) @log async def users_likes_artists( self, user_id: Union[str, int] = None, with_timestamps: bool = True, *args, **kwargs, ) -> List[Like]: """Получение артистов с отметкой "Мне нравится". Args: user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. with_timestamps (:obj:`bool`, optional): С временными метками TODO. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Like`: Артисты с отметкой "Мне нравится". Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_likes('artist', user_id, {'with-timestamps': str(with_timestamps)}, *args, **kwargs) @log async def users_likes_playlists(self, user_id: Union[str, int] = None, *args, **kwargs) -> List[Like]: """Получение плейлистов с отметкой "Мне нравится". Args: user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.Like`: Плейлисты с отметкой "Мне нравится". Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._get_likes('playlist', user_id, *args, **kwargs) @log async def users_dislikes_tracks( self, user_id: Union[str, int] = None, if_modified_since_revision: int = 0, *args, **kwargs, ) -> Optional[TracksList]: """Получение треков с отметкой "Не рекомендовать". Args: user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. if_modified_since_revision (:obj:`bool`, optional): TODO. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.TracksList`: Треки с отметкой "Не рекомендовать". Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid url = f'{self.base_url}/users/{user_id}/dislikes/tracks' result = await self._request.get( url, {'if_modified_since_revision': if_modified_since_revision}, *args, **kwargs ) return TracksList.de_json(result.get('library'), self) async def _dislike_action( self, ids: Union[List[Union[str, int]], str, int], remove: bool = False, user_id: Union[str, int] = None, *args, **kwargs, ) -> bool: """Действия с отметкой "Не рекомендовать". Args: ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор объекта или объектов. remove (:obj:`bool`, optional): Если :obj:`True`, то снимает отметку, иначе ставит. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if user_id is None and self.me is not None: user_id = self.me.account.uid action = 'remove' if remove else 'add-multiple' url = f'{self.base_url}/users/{user_id}/dislikes/tracks/{action}' result = await self._request.post(url, {f'track-ids': ids}, *args, **kwargs) return 'revision' in result @log async def users_dislikes_tracks_add( self, track_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Поставить отметку "Не рекомендовать" треку/трекам. Note: Так же снимает отметку "Мне нравится" если она есть. Args: track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор трека или треков. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._dislike_action(track_ids, remove=False, user_id=user_id, **kwargs) @log async def users_dislikes_tracks_remove( self, track_ids: Union[List[Union[str, int]], str, int], user_id: Union[str, int] = None, **kwargs, ) -> bool: """Снять отметку "Не рекомендовать" у трека/треков. Args: track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный идентификатор трека или треков. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан используется ID текущего пользователя. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ return await self._dislike_action(track_ids, remove=True, user_id=user_id, **kwargs) @log async def after_track( self, next_track_id: Union[str, int], context_item: str, prev_track_id: Union[str, int] = None, context: str = 'playlist', types: str = 'shot', from_: str = 'mobile-landing-origin-default', *args, **kwargs, ) -> Optional[ShotEvent]: """Получение рекламы или шота от Алисы после трека. Note: При получения шота от Алисы `prev_track_id` можно не указывать. Если `context = 'playlist'`, то в `context_item` необходимо передать `{OWNER_PLAYLIST}:{ID_PLAYLIST}`. Плейлист с Алисой имеет владельца с `id = 940441070`. ID плейлиста можно получить из блоков landing'a. Получить шот чужого плейлиста нельзя. Известные значения `context`: `playlist`. Известные значения `types`: `shot`, `ad`. Args: prev_track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор предыдущего трека. next_track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор следующего трека. context_item (:obj:`str`): Уникальный идентификатор контекста. context (:obj:`str`, optional): Место, откуда было вызвано получение. types (:obj:`str`, optional): Тип того, что вернуть после трека. from_ (:obj:`str`, optional): Место, с которого попали в контекст. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.ShotEvent`: Шот от Алисы или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/after-track' params = { 'from': from_, 'prevTrackId': prev_track_id, 'nextTrackId': next_track_id, 'context': context, 'contextItem': context_item, 'types': types, } result = await self._request.get(url, params, *args, **kwargs) # TODO (MarshalX) судя по всему ручка ещё возвращает рекламу после треков для пользователей без подписки. # https://github.com/MarshalX/yandex-music-api/issues/557 return ShotEvent.de_json(result.get('shot_event'), self) @log async def queues_list(self, device: str = None, *args, **kwargs) -> List[QueueItem]: """Получение всех очередей треков с разных устройств для синхронизации между ними. Note: Именно к `device` привязывается очередь. На одном устройстве может быть создана одна очередь. Аргумент `device` имеет следующий формат: `ключ=значение; ключ2=значение2`. Обязательные паля указы в значении по умолчанию. Args: device (:obj:`str`, optional): Содержит информацию об устройстве с которого выполняется запрос. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`list` из :obj:`yandex_music.QueueItem`: Элементы очереди всех устройств. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if not device: device = self.device url = f'{self.base_url}/queues' self._request.headers['X-Yandex-Music-Device'] = device result = await self._request.get(url, *args, **kwargs) return QueueItem.de_list(result.get('queues'), self) @log async def queue(self, queue_id: str, *args, **kwargs) -> Optional[Queue]: """Получение информации об очереди треков и самих треков в ней. Args: queue_id (:obj:`str`): Уникальный идентификатор очереди. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`yandex_music.Queue`: Очередь или :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ url = f'{self.base_url}/queues/{queue_id}' result = await self._request.get(url, *args, **kwargs) return Queue.de_json(result, self) @log async def queue_update_position(self, queue_id: str, current_index: int, device: str = None, **kwargs) -> bool: """Установка текущего индекса проигрываемого трека в очереди треков. Note: Изменить можно только у той очереди, которая была создана с переданного `device`! Args: queue_id (:obj:`str`): Уникальный идентификатор очереди. current_index (:obj:`int`): Текущий индекс. device (:obj:`str`, optional): Содержит информацию об устройстве с которого выполняется запрос. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if not device: device = self.device url = f'{self.base_url}/queues/{queue_id}/update-position' self._request.headers['X-Yandex-Music-Device'] = device result = await self._request.post( url, {'isInteractive': False}, params={'currentIndex': current_index}, **kwargs ) return result.get('status') == 'ok' @log async def queue_create(self, queue: Union[Queue, str], device: str = None, *args, **kwargs) -> Optional[str]: """Создание новой очереди треков. Args: queue (:obj:`yandex_music.Queue` | :obj:`str`): Объект очереди или JSON строка с этим объектом. device (:obj:`str`, optional): Содержит информацию об устройстве с которого выполняется запрос. **kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос). Returns: :obj:`str`: Вернёт уникальный идентификатор созданной очереди, иначе :obj:`None`. Raises: :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки. """ if not device: device = self.device if isinstance(queue, Queue): queue = queue.to_json(True) url = f'{self.base_url}/queues' self._request.headers['X-Yandex-Music-Device'] = device result = await self._request.post(url, queue, *args, **kwargs) return result.get('id') # camelCase псевдонимы #: Псевдоним для :attr:`account_status` accountStatus = account_status #: Псевдоним для :attr:`account_settings` accountSettings = account_settings #: Псевдоним для :attr:`account_settings_set` accountSettingsSet = account_settings_set #: Псевдоним для :attr:`permission_alerts` permissionAlerts = permission_alerts #: Псевдоним для :attr:`account_experiments` accountExperiments = account_experiments #: Псевдоним для :attr:`consume_promo_code` consumePromoCode = consume_promo_code #: Псевдоним для :attr:`feed_wizard_is_passed` feedWizardIsPassed = feed_wizard_is_passed #: Псевдоним для :attr:`new_releases` newReleases = new_releases #: Псевдоним для :attr:`new_playlists` newPlaylists = new_playlists #: Псевдоним для :attr:`tracks_download_info` tracksDownloadInfo = tracks_download_info #: Псевдоним для :attr:`track_supplement` trackSupplement = track_supplement #: Псевдоним для :attr:`tracks_lyrics` tracksLyrics = tracks_lyrics #: Псевдоним для :attr:`tracks_similar` tracksSimilar = tracks_similar #: Псевдоним для :attr:`play_audio` playAudio = play_audio #: Псевдоним для :attr:`albums_with_tracks` albumsWithTracks = albums_with_tracks #: Псевдоним для :attr:`search_suggest` searchSuggest = search_suggest #: Псевдоним для :attr:`users_settings` usersSettings = users_settings #: Псевдоним для :attr:`users_playlists` usersPlaylists = users_playlists #: Псевдоним для :attr:`users_playlists_recommendations` usersPlaylistsRecommendations = users_playlists_recommendations #: Псевдоним для :attr:`users_playlists_create` usersPlaylistsCreate = users_playlists_create #: Псевдоним для :attr:`users_playlists_delete` usersPlaylistsDelete = users_playlists_delete #: Псевдоним для :attr:`users_playlists_name` usersPlaylistsName = users_playlists_name #: Псевдоним для :attr:`users_playlists_visibility` usersPlaylistsVisibility = users_playlists_visibility #: Псевдоним для :attr:`users_playlists_change` usersPlaylistsChange = users_playlists_change #: Псевдоним для :attr:`users_playlists_insert_track` usersPlaylistsInsertTrack = users_playlists_insert_track #: Псевдоним для :attr:`users_playlists_delete_track` usersPlaylistsDeleteTrack = users_playlists_delete_track #: Псевдоним для :attr:`rotor_account_status` rotorAccountStatus = rotor_account_status #: Псевдоним для :attr:`rotor_stations_dashboard` rotorStationsDashboard = rotor_stations_dashboard #: Псевдоним для :attr:`rotor_stations_list` rotorStationsList = rotor_stations_list #: Псевдоним для :attr:`rotor_station_feedback` rotorStationFeedback = rotor_station_feedback #: Псевдоним для :attr:`rotor_station_feedback_radio_started` rotorStationFeedbackRadioStarted = rotor_station_feedback_radio_started #: Псевдоним для :attr:`rotor_station_feedback_track_started` rotorStationFeedbackTrackStarted = rotor_station_feedback_track_started #: Псевдоним для :attr:`rotor_station_feedback_track_finished` rotorStationFeedbackTrackFinished = rotor_station_feedback_track_finished #: Псевдоним для :attr:`rotor_station_feedback_skip` rotorStationFeedbackSkip = rotor_station_feedback_skip #: Псевдоним для :attr:`rotor_station_info` rotorStationInfo = rotor_station_info #: Псевдоним для :attr:`rotor_station_settings2` rotorStationSettings2 = rotor_station_settings2 #: Псевдоним для :attr:`rotor_station_tracks` rotorStationTracks = rotor_station_tracks #: Псевдоним для :attr:`artists_brief_info` artistsBriefInfo = artists_brief_info #: Псевдоним для :attr:`artists_tracks` artistsTracks = artists_tracks #: Псевдоним для :attr:`artists_direct_albums` artistsDirectAlbums = artists_direct_albums #: Псевдоним для :attr:`users_likes_tracks_add` usersLikesTracksAdd = users_likes_tracks_add #: Псевдоним для :attr:`users_likes_tracks_remove` usersLikesTracksRemove = users_likes_tracks_remove #: Псевдоним для :attr:`users_likes_artists_add` usersLikesArtistsAdd = users_likes_artists_add #: Псевдоним для :attr:`users_likes_artists_remove` usersLikesArtistsRemove = users_likes_artists_remove #: Псевдоним для :attr:`users_likes_playlists_add` usersLikesPlaylistsAdd = users_likes_playlists_add #: Псевдоним для :attr:`users_likes_playlists_remove` usersLikesPlaylistsRemove = users_likes_playlists_remove #: Псевдоним для :attr:`users_likes_albums_add` usersLikesAlbumsAdd = users_likes_albums_add #: Псевдоним для :attr:`users_likes_albums_remove` usersLikesAlbumsRemove = users_likes_albums_remove #: Псевдоним для :attr:`playlists_list` playlistsList = playlists_list #: Псевдоним для :attr:`playlists_collective_join` playlistsCollectiveJoin = playlists_collective_join #: Псевдоним для :attr:`users_playlists_list` usersPlaylistsList = users_playlists_list #: Псевдоним для :attr:`users_likes_tracks` usersLikesTracks = users_likes_tracks #: Псевдоним для :attr:`users_likes_albums` usersLikesAlbums = users_likes_albums #: Псевдоним для :attr:`users_likes_artists` usersLikesArtists = users_likes_artists #: Псевдоним для :attr:`users_likes_playlists` usersLikesPlaylists = users_likes_playlists #: Псевдоним для :attr:`users_dislikes_tracks` usersDislikesTracks = users_dislikes_tracks #: Псевдоним для :attr:`users_dislikes_tracks_add` usersDislikesTracksAdd = users_dislikes_tracks_add #: Псевдоним для :attr:`users_dislikes_tracks_remove` usersDislikesTracksRemove = users_dislikes_tracks_remove #: Псевдоним для :attr:`after_track` afterTrack = after_track #: Псевдоним для :attr:`queues_list` queuesList = queues_list #: Псевдоним для :attr:`queue_update_position` queueUpdatePosition = queue_update_position #: Псевдоним для :attr:`queue_create` queueCreate = queue_create