client_async.py 123 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621
  1. ####################################################################
  2. # THIS IS AUTO GENERATED COPY OF client.py. DON'T EDIT IN BY HANDS #
  3. ####################################################################
  4. import functools
  5. import logging
  6. from datetime import datetime
  7. from typing import TYPE_CHECKING, Any, Callable, List, Optional, TypeVar, Union, cast
  8. from yandex_music import (
  9. Album,
  10. Artist,
  11. ArtistAlbums,
  12. ArtistTracks,
  13. BriefInfo,
  14. ChartInfo,
  15. Dashboard,
  16. DownloadInfo,
  17. Experiments,
  18. Feed,
  19. Genre,
  20. Landing,
  21. LandingList,
  22. Like,
  23. PermissionAlerts,
  24. Playlist,
  25. PlaylistRecommendations,
  26. PromoCodeStatus,
  27. Queue,
  28. QueueItem,
  29. Search,
  30. Settings,
  31. ShotEvent,
  32. SimilarTracks,
  33. StationResult,
  34. StationTracksResult,
  35. Status,
  36. Suggestions,
  37. Supplement,
  38. TagResult,
  39. Track,
  40. TrackLyrics,
  41. TracksList,
  42. UserSettings,
  43. YandexMusicObject,
  44. __copyright__,
  45. __license__,
  46. __version__,
  47. )
  48. if TYPE_CHECKING:
  49. from yandex_music.base import JSONType
  50. from yandex_music.exceptions import BadRequestError
  51. from yandex_music.utils.difference import Difference
  52. from yandex_music.utils.request_async import Request
  53. from yandex_music.utils.sign_request import get_sign_request
  54. de_list = {
  55. 'artist': Artist.de_list,
  56. 'album': Album.de_list,
  57. 'track': Track.de_list,
  58. 'playlist': Playlist.de_list,
  59. }
  60. logging.getLogger(__name__).addHandler(logging.NullHandler())
  61. F = TypeVar('F', bound=Callable[..., Any])
  62. UserIdType = Optional[Union[str, int]]
  63. TimestampType = Optional[Union[str, float, int]]
  64. def log(method: F) -> F:
  65. logger = logging.getLogger(method.__module__)
  66. @functools.wraps(method)
  67. async def wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401:
  68. logger.debug(f'Entering: {method.__name__}')
  69. result = await method(*args, **kwargs)
  70. logger.debug(result)
  71. logger.debug(f'Exiting: {method.__name__}')
  72. return result
  73. return wrapper
  74. class ClientAsync(YandexMusicObject):
  75. """Класс, представляющий клиент Yandex Music.
  76. Note:
  77. Доступные языки: en, uz, uk, us, ru, kk, hy.
  78. Поле `device` используется только при работе с очередью прослушивания.
  79. Attributes:
  80. logger (:obj:`logging.Logger`): Объект логгера.
  81. token (:obj:`str`): Уникальный ключ для аутентификации.
  82. base_url (:obj:`str`): Ссылка на API Yandex Music.
  83. me (:obj:`yandex_music.Status`): Информация об аккаунте.
  84. device (:obj:`str`): Строка, содержащая сведения об устройстве, с которого выполняются запросы.
  85. report_unknown_fields (:obj:`bool`): Включены ли предупреждения о неизвестных полях от API,
  86. которых нет в библиотеке.
  87. Args:
  88. token (:obj:`str`, optional): Уникальный ключ для аутентификации.
  89. base_url (:obj:`str`, optional): Ссылка на API Yandex Music.
  90. request (:obj:`yandex_music.utils.request.Request`, optional): Пре-инициализация
  91. :class:`yandex_music.utils.request.Request`.
  92. language (:obj:`str`, optional): Язык, на котором будут приходить ответы от API. По умолчанию русский.
  93. report_unknown_fields (:obj:`bool`, optional): Включить предупреждения о неизвестных полях от API,
  94. которых нет в библиотеке.
  95. """
  96. __notice_displayed = True # больше не используется
  97. def __init__(
  98. self,
  99. token: Optional[str] = None,
  100. base_url: Optional[str] = None,
  101. request: Optional[Request] = None,
  102. language: str = 'ru',
  103. report_unknown_fields: bool = False,
  104. ) -> None:
  105. if not ClientAsync.__notice_displayed:
  106. print(f'Yandex Music API v{__version__}, {__copyright__}')
  107. print(f'Licensed under the terms of the {__license__}', end='\n\n')
  108. ClientAsync.__notice_displayed = True
  109. self.logger = logging.getLogger(__name__)
  110. self.token = token
  111. if base_url is None:
  112. base_url = 'https://api.music.yandex.net'
  113. self.base_url = base_url
  114. self.report_unknown_fields = report_unknown_fields
  115. if request:
  116. self._request = request
  117. self._request.set_and_return_client(self)
  118. else:
  119. self._request = Request(self)
  120. self.language = language
  121. self._request.set_language(self.language)
  122. self.device = (
  123. 'os=Python; os_version=; manufacturer=Marshal; '
  124. 'model=Yandex Music API; clid=; device_id=random; uuid=random'
  125. )
  126. self.me: Optional['Status'] = None
  127. self.account_uid: Optional[str] = None
  128. @property
  129. def request(self) -> Request:
  130. """:obj:`yandex_music.utils.request.Request`: Объект вспомогательного класса для отправки запросов."""
  131. return self._request
  132. @log
  133. async def init(self) -> 'ClientAsync':
  134. """Получение информацию об аккаунте использующихся в других запросах."""
  135. self.me = await self.account_status()
  136. if self.me and self.me.account:
  137. self.account_uid = self.me.account.uid
  138. return self
  139. @log
  140. async def account_status(self, *args: Any, **kwargs: Any) -> Optional[Status]:
  141. """Получение статуса аккаунта. Нет обязательных параметров.
  142. Args:
  143. *args: Произвольные аргументы (будут переданы в запрос).
  144. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  145. Returns:
  146. :obj:`yandex_music.Status` | :obj:`None`: Информация об аккаунте если он валиден, иначе :obj:`None`.
  147. Raises:
  148. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  149. """
  150. url = f'{self.base_url}/account/status'
  151. result = await self._request.get(url, *args, **kwargs)
  152. return Status.de_json(result, self)
  153. @log
  154. async def account_settings(self, *args: Any, **kwargs: Any) -> Optional[UserSettings]:
  155. """Получение настроек текущего пользователя.
  156. Args:
  157. *args: Произвольные аргументы (будут переданы в запрос).
  158. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  159. Returns:
  160. :obj:`yandex_music.UserSettings` | :obj:`None`: Настройки пользователя если аккаунт валиден,
  161. иначе :obj:`None`.
  162. Raises:
  163. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  164. """
  165. url = f'{self.base_url}/account/settings'
  166. result = await self._request.get(url, *args, **kwargs)
  167. return UserSettings.de_json(result, self)
  168. @log
  169. async def account_settings_set(
  170. self,
  171. param: Optional[str] = None,
  172. value: Optional[Union[str, int, bool]] = None,
  173. data: Optional['JSONType'] = None,
  174. *args: Any,
  175. **kwargs: Any,
  176. ) -> Optional[UserSettings]:
  177. """Изменение настроек текущего пользователя.
  178. Note:
  179. Доступные названия параметров есть поля в классе :class:`yandex_music.UserSettings`, только в CamelCase.
  180. Args:
  181. param (:obj:`str`): Название параметра для изменения.
  182. value (:obj:`str` | :obj:`int` | :obj:`bool`): Значение параметра.
  183. data (:obj:`dict`): Словарь параметров и значений для множественного изменения.
  184. *args: Произвольные аргументы (будут переданы в запрос).
  185. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  186. Returns:
  187. :obj:`yandex_music.UserSettings` | :obj:`None`: Настройки пользователя или :obj:`None`.
  188. Raises:
  189. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  190. """
  191. url = f'{self.base_url}/account/settings'
  192. if not data and param:
  193. data = {param: str(value)}
  194. result = await self._request.post(url, data, *args, **kwargs)
  195. return UserSettings.de_json(result, self)
  196. @log
  197. async def settings(self, *args: Any, **kwargs: Any) -> Optional[Settings]:
  198. """Получение предложений по покупке. Нет обязательных параметров.
  199. Args:
  200. *args: Произвольные аргументы (будут переданы в запрос).
  201. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  202. Returns:
  203. :obj:`yandex_music.Settings` | :obj:`None`: Информацию о предлагаемых продуктах если аккаунт валиден
  204. или :obj:`None`.
  205. Raises:
  206. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  207. """
  208. url = f'{self.base_url}/settings'
  209. result = await self._request.get(url, *args, **kwargs)
  210. return Settings.de_json(result, self)
  211. @log
  212. async def permission_alerts(self, *args: Any, **kwargs: Any) -> Optional[PermissionAlerts]:
  213. """Получение оповещений. Нет обязательных параметров.
  214. Args:
  215. *args: Произвольные аргументы (будут переданы в запрос).
  216. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  217. Returns:
  218. :obj:`yandex_music.PermissionAlerts` | :obj:`None`: Оповещения если аккаунт валиден или :obj:`None`.
  219. Raises:
  220. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  221. """
  222. url = f'{self.base_url}/permission-alerts'
  223. result = await self._request.get(url, *args, **kwargs)
  224. return PermissionAlerts.de_json(result, self)
  225. @log
  226. async def account_experiments(self, *args: Any, **kwargs: Any) -> Optional[Experiments]:
  227. """Получение значений экспериментальных функций аккаунта.
  228. Args:
  229. *args: Произвольные аргументы (будут переданы в запрос).
  230. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  231. Returns:
  232. :obj:`yandex_music.Experiments` | :obj:`None`: Состояние экспериментальных функций или :obj:`None`.
  233. Raises:
  234. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  235. """
  236. url = f'{self.base_url}/account/experiments'
  237. result = await self._request.get(url, *args, **kwargs)
  238. return Experiments.de_json(result, self)
  239. @log
  240. async def consume_promo_code(
  241. self, code: str, language: Optional[str] = None, *args, **kwargs
  242. ) -> Optional[PromoCodeStatus]:
  243. """Активация промо-кода.
  244. Note:
  245. Доступные языки: en, uz, uk, us, ru, kk, hy.
  246. Args:
  247. code (:obj:`str`): Промо-код.
  248. language (:obj:`str`, optional): Язык ответа API в ISO 639-1. По умолчанию язык клиента.
  249. *args: Произвольные аргументы (будут переданы в запрос).
  250. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  251. Returns:
  252. :obj:`yandex_music.PromoCodeStatus` | :obj:`None`: Информация об активации промо-кода или :obj:`None`.
  253. Raises:
  254. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  255. """
  256. url = f'{self.base_url}/account/consume-promo-code'
  257. if not language:
  258. language = self.language
  259. result = await self._request.post(url, {'code': code, 'language': language}, *args, **kwargs)
  260. return PromoCodeStatus.de_json(result, self)
  261. @log
  262. async def feed(self, *args: Any, **kwargs: Any) -> Optional[Feed]:
  263. """Получение потока информации (фида) подобранного под пользователя. Содержит умные плейлисты.
  264. Args:
  265. *args: Произвольные аргументы (будут переданы в запрос).
  266. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  267. Returns:
  268. :obj:`yandex_music.Feed` | :obj:`None`: Умные плейлисты пользователя или :obj:`None`.
  269. Raises:
  270. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  271. """
  272. url = f'{self.base_url}/feed'
  273. result = await self._request.get(url, *args, **kwargs)
  274. return Feed.de_json(result, self)
  275. @log
  276. async def feed_wizard_is_passed(self, *args: Any, **kwargs: Any) -> bool:
  277. """Получение информации о прохождении визарда.
  278. Note:
  279. Временное событие на хэллоуин.
  280. Args:
  281. *args: Произвольные аргументы (будут переданы в запрос).
  282. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  283. Returns:
  284. :obj:`bool`: Прошел ли пользователь визард или нет.
  285. """
  286. url = f'{self.base_url}/feed/wizard/is-passed'
  287. result = await self._request.get(url, *args, **kwargs)
  288. return result.get('is_wizard_passed') or False
  289. @log
  290. async def landing(self, blocks: Union[str, List[str]], *args: Any, **kwargs: Any) -> Optional[Landing]:
  291. """Получение лендинг-страницы содержащий блоки с новыми релизами, чартами, плейлистами с новинками и т.д.
  292. Note:
  293. Поддерживаемые типы блоков: `personalplaylists`, `promotions`, `new-releases`, `new-playlists`, `mixes`,
  294. `chart`, `artists`, `albums`, `playlists`, `play_contexts`.
  295. Args:
  296. blocks (:obj:`str` | :obj:`list` из :obj:`str`): Блок или список блоков необходимых для выдачи.
  297. *args: Произвольные аргументы (будут переданы в запрос).
  298. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  299. Returns:
  300. :obj:`yandex_music.Landing` | :obj:`None`: Лендинг-страница или :obj:`None`.
  301. Raises:
  302. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  303. """
  304. url = f'{self.base_url}/landing3'
  305. params = cast('JSONType', {'blocks': blocks, 'eitherUserId': '10254713668400548221'})
  306. result = await self._request.get(url, params, *args, **kwargs)
  307. # TODO (MarshalX) что тут делает константа с чьим-то User ID
  308. # https://github.com/MarshalX/yandex-music-api/issues/553
  309. return Landing.de_json(result, self)
  310. @log
  311. async def chart(self, chart_option: str = '', *args: Any, **kwargs: Any) -> Optional[ChartInfo]:
  312. """Получение чарта.
  313. Note:
  314. `chart_option` - это постфикс к запросу из поля `menu` чарта.
  315. Например, на сайте можно выбрать глобальный (world) чарт или российский (russia).
  316. Args:
  317. chart_option (:obj:`str` optional): Параметры чарта.
  318. *args: Произвольные аргументы (будут переданы в запрос).
  319. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  320. Returns:
  321. :obj:`yandex_music.ChartInfo`: Чарт.
  322. Raises:
  323. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  324. """
  325. url = f'{self.base_url}/landing3/chart'
  326. if chart_option:
  327. url = f'{url}/{chart_option}'
  328. result = await self._request.get(url, *args, **kwargs)
  329. return ChartInfo.de_json(result, self)
  330. @log
  331. async def new_releases(self, *args: Any, **kwargs: Any) -> Optional[LandingList]:
  332. """Получение полного списка всех новых релизов (альбомов).
  333. Args:
  334. *args: Произвольные аргументы (будут переданы в запрос).
  335. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  336. Returns:
  337. :obj:`yandex_music.LandingList`: Список новых альбомов.
  338. Raises:
  339. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  340. """
  341. url = f'{self.base_url}/landing3/new-releases'
  342. result = await self._request.get(url, *args, **kwargs)
  343. return LandingList.de_json(result, self)
  344. @log
  345. async def new_playlists(self, *args: Any, **kwargs: Any) -> Optional[LandingList]:
  346. """Получение полного списка всех новых плейлистов.
  347. Args:
  348. *args: Произвольные аргументы (будут переданы в запрос).
  349. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  350. Returns:
  351. :obj:`yandex_music.LandingList`: Список новых плейлистов.
  352. Raises:
  353. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  354. """
  355. url = f'{self.base_url}/landing3/new-playlists'
  356. result = await self._request.get(url, *args, **kwargs)
  357. return LandingList.de_json(result, self)
  358. @log
  359. async def podcasts(self, *args: Any, **kwargs: Any) -> Optional[LandingList]:
  360. """Получение подкастов с лендинга.
  361. Args:
  362. *args: Произвольные аргументы (будут переданы в запрос).
  363. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  364. Returns:
  365. :obj:`yandex_music.LandingList`: Список подкастов.
  366. Raises:
  367. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  368. """
  369. url = f'{self.base_url}/landing3/podcasts'
  370. result = await self._request.get(url, *args, **kwargs)
  371. return LandingList.de_json(result, self)
  372. @log
  373. async def genres(self, *args: Any, **kwargs: Any) -> List[Genre]:
  374. """Получение жанров музыки.
  375. Args:
  376. *args: Произвольные аргументы (будут переданы в запрос).
  377. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  378. Returns:
  379. :obj:`list` из :obj:`yandex_music.Genre` | :obj:`None`: Жанры музыки или :obj:`None`.
  380. Raises:
  381. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  382. """
  383. url = f'{self.base_url}/genres'
  384. result = await self._request.get(url, *args, **kwargs)
  385. return Genre.de_list(result, self)
  386. @log
  387. async def tags(self, tag_id: str, *args: Any, **kwargs: Any) -> Optional[TagResult]:
  388. """Получение тега (подборки).
  389. Note:
  390. Теги есть в `MixLink` у `Landing`, а также плейлистов в `.tags`.
  391. У `MixLink` есть `URL`, но `tag_id` только его последняя часть.
  392. Например, `/tag/belarus/`. `Tag` - `belarus`.
  393. Args:
  394. tag_id (:obj:`str`): Уникальный идентификатор тега.
  395. *args: Произвольные аргументы (будут переданы в запрос).
  396. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  397. Returns:
  398. :obj:`yandex_music.TagResult`: Тег с плейлистами.
  399. Raises:
  400. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  401. """
  402. url = f'{self.base_url}/tags/{tag_id}/playlist-ids'
  403. result = await self._request.get(url, *args, **kwargs)
  404. return TagResult.de_json(result, self)
  405. @log
  406. async def tracks_download_info(
  407. self,
  408. track_id: Union[str, int],
  409. get_direct_links: bool = False,
  410. *args: Any,
  411. **kwargs: Any,
  412. ) -> List[DownloadInfo]:
  413. """Получение информации о доступных вариантах загрузки трека.
  414. Args:
  415. track_id (:obj:`str` | :obj:`list` из :obj:`str`): Уникальный идентификатор трека или треков.
  416. get_direct_links (:obj:`bool`, optional): Получить ли при вызове метода прямую ссылку на загрузку.
  417. *args: Произвольные аргументы (будут переданы в запрос).
  418. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  419. Returns:
  420. :obj:`list` из :obj:`yandex_music.DownloadInfo` | :obj:`None`: Варианты загрузки трека или :obj:`None`.
  421. Raises:
  422. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  423. """
  424. url = f'{self.base_url}/tracks/{track_id}/download-info'
  425. result = await self._request.get(url, *args, **kwargs)
  426. return await DownloadInfo.de_list_async(result, self, get_direct_links)
  427. @log
  428. async def track_supplement(self, track_id: Union[str, int], *args: Any, **kwargs: Any) -> Optional[Supplement]:
  429. """Получение дополнительной информации о треке.
  430. Warning:
  431. Получение текста из дополнительной информации устарело. Используйте
  432. :func:`yandex_music.ClientAsync.tracks_lyrics`.
  433. Args:
  434. track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека.
  435. *args: Произвольные аргументы (будут переданы в запрос).
  436. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  437. Returns:
  438. :obj:`yandex_music.Supplement`: Дополнительная информация о треке.
  439. Raises:
  440. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  441. """
  442. url = f'{self.base_url}/tracks/{track_id}/supplement'
  443. result = await self._request.get(url, *args, **kwargs)
  444. return Supplement.de_json(result, self)
  445. @log
  446. async def tracks_lyrics(
  447. self,
  448. track_id: Union[str, int],
  449. format_: str = 'TEXT',
  450. **kwargs: Any,
  451. ) -> Optional[TrackLyrics]:
  452. """Получение текста трека.
  453. Note:
  454. Для работы с методом необходима авторизация.
  455. Известные значения для аргумента format:
  456. - `LRC` - формат с временными метками.
  457. - `TEXT` - простой текст.
  458. Args:
  459. track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека.
  460. format_ (:obj:`str`): Формат текста.
  461. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  462. Returns:
  463. :obj:`yandex_music.TrackLyrics` | :obj:`None`: Информация о тексте трека.
  464. Raises:
  465. :class:`yandex_music.exceptions.UnauthorizedError`: Метод вызван без авторизации.
  466. :class:`yandex_music.exceptions.NotFoundError`: Текст у трека отсутствует.
  467. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  468. """
  469. url = f'{self.base_url}/tracks/{track_id}/lyrics'
  470. sign = get_sign_request(track_id)
  471. params = {
  472. 'format': format_,
  473. 'timeStamp': sign.timestamp,
  474. 'sign': sign.value,
  475. }
  476. result = await self._request.get(url, params=params, **kwargs)
  477. return TrackLyrics.de_json(result, self)
  478. @log
  479. async def tracks_similar(self, track_id: Union[str, int], *args: Any, **kwargs: Any) -> Optional[SimilarTracks]:
  480. """Получение похожих треков.
  481. Args:
  482. track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека.
  483. *args: Произвольные аргументы (будут переданы в запрос).
  484. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  485. Returns:
  486. :obj:`yandex_music.SimilarTracks`: Похожие треки на другой трек.
  487. Raises:
  488. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  489. """
  490. url = f'{self.base_url}/tracks/{track_id}/similar'
  491. result = await self._request.get(url, *args, **kwargs)
  492. return SimilarTracks.de_json(result, self)
  493. @log
  494. async def play_audio(
  495. self,
  496. track_id: Union[str, int],
  497. from_: str,
  498. album_id: Union[str, int],
  499. playlist_id: Optional[str] = None,
  500. from_cache: bool = False,
  501. play_id: Optional[str] = None,
  502. uid: Optional[int] = None,
  503. timestamp: Optional[str] = None,
  504. track_length_seconds: int = 0,
  505. total_played_seconds: int = 0,
  506. end_position_seconds: int = 0,
  507. client_now: Optional[str] = None,
  508. *args: Any,
  509. **kwargs: Any,
  510. ) -> bool:
  511. """Метод для отправки текущего состояния прослушиваемого трека.
  512. Args:
  513. track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека.
  514. from_ (:obj:`str`): Наименования клиента с которого происходит прослушивание.
  515. album_id (:obj:`str` | :obj:`int`): Уникальный идентификатор альбома.
  516. playlist_id (:obj:`str`, optional): Уникальный идентификатор плейлиста, если таковой прослушивается.
  517. from_cache (:obj:`bool`, optional): Проигрывается ли трек с кеша.
  518. play_id (:obj:`str`, optional): Уникальный идентификатор проигрывания.
  519. uid (:obj:`int`, optional): Уникальный идентификатор пользователя.
  520. timestamp (:obj:`str`, optional): Текущая дата и время в ISO.
  521. track_length_seconds (:obj:`int`, optional): Продолжительность трека в секундах.
  522. total_played_seconds (:obj:`int`, optional): Сколько было всего воспроизведено трека в секундах.
  523. end_position_seconds (:obj:`int`, optional): Окончательное значение воспроизведенных секунд.
  524. client_now (:obj:`str`, optional): Текущая дата и время клиента в ISO.
  525. *args: Произвольные аргументы (будут переданы в запрос).
  526. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  527. Returns:
  528. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  529. Raises:
  530. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  531. """
  532. if uid is None and self.account_uid is not None:
  533. uid = self.account_uid
  534. url = f'{self.base_url}/play-audio'
  535. data = {
  536. 'track-id': track_id,
  537. 'from-cache': str(from_cache),
  538. 'from': from_,
  539. 'play-id': play_id or '',
  540. 'uid': uid,
  541. 'timestamp': timestamp or f'{datetime.now().isoformat()}Z',
  542. 'track-length-seconds': track_length_seconds,
  543. 'total-played-seconds': total_played_seconds,
  544. 'end-position-seconds': end_position_seconds,
  545. 'album-id': album_id,
  546. 'playlist-id': playlist_id,
  547. 'client-now': client_now or f'{datetime.now().isoformat()}Z',
  548. }
  549. result = await self._request.post(url, data, *args, **kwargs)
  550. return result == 'ok'
  551. @log
  552. async def albums_with_tracks(self, album_id: Union[str, int], *args: Any, **kwargs: Any) -> Optional[Album]:
  553. """Получение альбома по его уникальному идентификатору вместе с треками.
  554. Args:
  555. album_id (:obj:`str` | :obj:`int`): Уникальный идентификатор альбома.
  556. *args: Произвольные аргументы (будут переданы в запрос).
  557. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  558. Returns:
  559. :obj:`list` из :obj:`yandex_music.Album` | :obj:`None`: Альбом или :obj:`None`.
  560. Raises:
  561. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  562. """
  563. url = f'{self.base_url}/albums/{album_id}/with-tracks'
  564. result = await self._request.get(url, *args, **kwargs)
  565. return Album.de_json(result, self)
  566. @log
  567. async def search(
  568. self,
  569. text: str,
  570. nocorrect: bool = False,
  571. type_: str = 'all',
  572. page: int = 0,
  573. playlist_in_best: bool = True,
  574. *args: Any,
  575. **kwargs: Any,
  576. ) -> Optional[Search]:
  577. """Осуществление поиска по запросу и типу, получение результатов.
  578. Note:
  579. Известные значения для поля `type_`: `all`, `artist`, `user`, `album`, `playlist`, `track`, `podcast`,
  580. `podcast_episode`.
  581. При поиске `type=all` не возвращаются подкасты и эпизоды. Указывайте конкретный тип для поиска.
  582. Args:
  583. text (:obj:`str`): Текст запроса.
  584. nocorrect (:obj:`bool`): Если :obj:`False`, то ошибочный запрос будет исправлен. Например, запрос
  585. "Гражданская абарона" будет исправлен на "Гражданская оборона".
  586. type_ (:obj:`str`): Среди какого типа искать (трек, плейлист, альбом, исполнитель, пользователь, подкаст).
  587. page (:obj:`int`): Номер страницы.
  588. playlist_in_best (:obj:`bool`): Выдавать ли плейлисты лучшим вариантом поиска.
  589. *args: Произвольные аргументы (будут переданы в запрос).
  590. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  591. Returns:
  592. :obj:`yandex_music.Search` | :obj:`None`: Результаты поиска или :obj:`None`.
  593. Raises:
  594. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  595. """
  596. url = f'{self.base_url}/search'
  597. params = {
  598. 'text': text,
  599. 'nocorrect': str(nocorrect),
  600. 'type': type_,
  601. 'page': page,
  602. 'playlist-in-best': str(playlist_in_best),
  603. }
  604. result = await self._request.get(url, params, *args, **kwargs)
  605. if isinstance(result, str):
  606. raise BadRequestError(result)
  607. return Search.de_json(result, self)
  608. @log
  609. async def search_suggest(self, part: str, *args: Any, **kwargs: Any) -> Optional[Suggestions]:
  610. """Получение подсказок по введенной части поискового запроса.
  611. Args:
  612. part (:obj:`str`): Часть поискового запроса.
  613. *args: Произвольные аргументы (будут переданы в запрос).
  614. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  615. Returns:
  616. :obj:`yandex_music.Suggestions` | :obj:`None`: Подсказки для запроса или :obj:`None`.
  617. Raises:
  618. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  619. """
  620. url = f'{self.base_url}/search/suggest'
  621. result = await self._request.get(url, {'part': part}, *args, **kwargs)
  622. return Suggestions.de_json(result, self)
  623. @log
  624. async def users_settings(self, user_id: UserIdType = None, *args: Any, **kwargs: Any) -> Optional[UserSettings]:
  625. """Получение настроек пользователя.
  626. Note:
  627. Для получения настроек пользователя нужно быть авторизованным или владеть `user_id`.
  628. Args:
  629. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя чьи настройки хотим
  630. получить.
  631. *args: Произвольные аргументы (будут переданы в запрос).
  632. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  633. Returns:
  634. :obj:`yandex_music.UserSettings` | :obj:`None`: Настройки пользователя или :obj:`None`.
  635. Raises:
  636. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  637. """
  638. if user_id is None and self.account_uid is not None:
  639. user_id = self.account_uid
  640. url = f'{self.base_url}/users/{user_id}/settings'
  641. result = await self._request.get(url, *args, **kwargs)
  642. return UserSettings.de_json(result.get('user_settings'), self)
  643. @log
  644. async def users_playlists(
  645. self,
  646. kind: Union[List[Union[str, int]], str, int],
  647. user_id: UserIdType = None,
  648. *args: Any,
  649. **kwargs: Any,
  650. ) -> Union[Playlist, List[Playlist], None]:
  651. """Получение плейлиста или списка плейлистов по уникальным идентификаторам.
  652. Note:
  653. Если передан один `kind`, то вернётся не список плейлистов, а один плейлист.
  654. Args:
  655. kind (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста
  656. или их список.
  657. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  658. *args: Произвольные аргументы (будут переданы в запрос).
  659. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  660. Returns:
  661. :obj:`list` из :obj:`yandex_music.Playlist` | :obj:`yandex_music.Playlist` | :obj:`None`:
  662. Список плейлистов или плейлист, иначе :obj:`None`.
  663. Raises:
  664. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  665. """
  666. if user_id is None and self.account_uid is not None:
  667. user_id = self.account_uid
  668. if isinstance(kind, list):
  669. url = f'{self.base_url}/users/{user_id}/playlists'
  670. data = {'kinds': kind}
  671. result = await self._request.post(url, data, *args, **kwargs)
  672. return Playlist.de_list(result, self)
  673. url = f'{self.base_url}/users/{user_id}/playlists/{kind}'
  674. result = await self._request.get(url, *args, **kwargs)
  675. return Playlist.de_json(result, self)
  676. @log
  677. async def users_playlists_recommendations(
  678. self, kind: Union[str, int], user_id: UserIdType = None, *args: Any, **kwargs: Any
  679. ) -> Optional[PlaylistRecommendations]:
  680. """Получение рекомендаций для плейлиста.
  681. Args:
  682. kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
  683. user_id (:obj:`str` | :obj:`int`): Уникальный идентификатор пользователя владеющим плейлистом.
  684. *args: Произвольные аргументы (будут переданы в запрос).
  685. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  686. Returns:
  687. :obj:`yandex_music.PlaylistRecommendations` | :obj:`None`: Рекомендации для плейлиста или :obj:`None`.
  688. Raises:
  689. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  690. """
  691. if user_id is None and self.account_uid is not None:
  692. user_id = self.account_uid
  693. url = f'{self.base_url}/users/{user_id}/playlists/{kind}/recommendations'
  694. result = await self._request.get(url, *args, **kwargs)
  695. return PlaylistRecommendations.de_json(result, self)
  696. @log
  697. async def users_playlists_create(
  698. self,
  699. title: str,
  700. visibility: str = 'public',
  701. user_id: UserIdType = None,
  702. *args: Any,
  703. **kwargs: Any,
  704. ) -> Optional[Playlist]:
  705. """Создание плейлиста.
  706. Args:
  707. title (:obj:`str`): Название.
  708. visibility (:obj:`str`, optional): Модификатор доступа.
  709. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  710. *args: Произвольные аргументы (будут переданы в запрос).
  711. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  712. Returns:
  713. :obj:`yandex_music.Playlist` | :obj:`None`: Созданный плейлист или :obj:`None`.
  714. Raises:
  715. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  716. """
  717. if user_id is None and self.account_uid is not None:
  718. user_id = self.account_uid
  719. url = f'{self.base_url}/users/{user_id}/playlists/create'
  720. data = {'title': title, 'visibility': visibility}
  721. result = await self._request.post(url, data, *args, **kwargs)
  722. return Playlist.de_json(result, self)
  723. @log
  724. async def users_playlists_delete(
  725. self, kind: Union[str, int], user_id: UserIdType = None, *args: Any, **kwargs: Any
  726. ) -> bool:
  727. """Удаление плейлиста.
  728. Args:
  729. kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
  730. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  731. *args: Произвольные аргументы (будут переданы в запрос).
  732. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  733. Returns:
  734. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  735. Raises:
  736. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  737. """
  738. if user_id is None and self.account_uid is not None:
  739. user_id = self.account_uid
  740. url = f'{self.base_url}/users/{user_id}/playlists/{kind}/delete'
  741. result = await self._request.post(url, *args, **kwargs)
  742. return result == 'ok'
  743. @log
  744. async def users_playlists_name(
  745. self,
  746. kind: Union[str, int],
  747. name: str,
  748. user_id: UserIdType = None,
  749. *args: Any,
  750. **kwargs: Any,
  751. ) -> Optional[Playlist]:
  752. """Изменение названия плейлиста.
  753. Args:
  754. kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
  755. name (:obj:`str`): Новое название.
  756. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  757. *args: Произвольные аргументы (будут переданы в запрос).
  758. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  759. Returns:
  760. :obj:`yandex_music.Playlist` | :obj:`None`: Изменённый плейлист или :obj:`None`.
  761. Raises:
  762. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  763. """
  764. if user_id is None and self.account_uid is not None:
  765. user_id = self.account_uid
  766. url = f'{self.base_url}/users/{user_id}/playlists/{kind}/name'
  767. result = await self._request.post(url, {'value': name}, *args, **kwargs)
  768. return Playlist.de_json(result, self)
  769. @log
  770. async def users_playlists_visibility(
  771. self,
  772. kind: Union[str, int],
  773. visibility: str,
  774. user_id: UserIdType = None,
  775. *args: Any,
  776. **kwargs: Any,
  777. ) -> Optional[Playlist]:
  778. """Изменение видимости плейлиста.
  779. Note:
  780. Видимость (`visibility`) может быть задана только одним из двух значений: `private`, `public`.
  781. Args:
  782. kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
  783. visibility (:obj:`str`): Новое название.
  784. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  785. *args: Произвольные аргументы (будут переданы в запрос).
  786. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  787. Returns:
  788. :obj:`yandex_music.Playlist` | :obj:`None`: Изменённый плейлист или :obj:`None`.
  789. Raises:
  790. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  791. """
  792. if user_id is None and self.account_uid is not None:
  793. user_id = self.account_uid
  794. url = f'{self.base_url}/users/{user_id}/playlists/{kind}/visibility'
  795. result = await self._request.post(url, {'value': visibility}, *args, **kwargs)
  796. return Playlist.de_json(result, self)
  797. @log
  798. async def users_playlists_change(
  799. self,
  800. kind: Union[str, int],
  801. diff: str,
  802. revision: int = 1,
  803. user_id: UserIdType = None,
  804. *args: Any,
  805. **kwargs: Any,
  806. ) -> Optional[Playlist]:
  807. """Изменение плейлиста.
  808. Note:
  809. Для получения отличий есть вспомогательный класс :class:`yandex_music.utils.difference.Difference`.
  810. Так же существуют уже готовые методы-обёртки над операциями.
  811. Args:
  812. kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
  813. revision (:obj:`int`): TODO.
  814. diff (:obj:`str`): JSON представления отличий старого и нового плейлиста.
  815. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  816. *args: Произвольные аргументы (будут переданы в запрос).
  817. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  818. Returns:
  819. :obj:`yandex_music.Playlist`: Изменённый плейлист или :obj:`None`.
  820. Raises:
  821. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  822. """
  823. if user_id is None and self.account_uid is not None:
  824. user_id = self.account_uid
  825. url = f'{self.base_url}/users/{user_id}/playlists/{kind}/change'
  826. data = {'kind': kind, 'revision': revision, 'diff': diff}
  827. result = await self._request.post(url, data, *args, **kwargs)
  828. return Playlist.de_json(result, self)
  829. @log
  830. async def users_playlists_insert_track(
  831. self,
  832. kind: Union[str, int],
  833. track_id: Union[str, int],
  834. album_id: Union[str, int],
  835. at: int = 0,
  836. revision: int = 1,
  837. user_id: UserIdType = None,
  838. *args: Any,
  839. **kwargs: Any,
  840. ) -> Optional[Playlist]:
  841. """Добавление трека в плейлист.
  842. Note:
  843. Трек можно вставить с любое место плейлиста задав индекс вставки (аргумент `at`).
  844. Args:
  845. kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
  846. track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор трека.
  847. album_id (:obj:`str` | :obj:`int`): Уникальный идентификатор альбома.
  848. at (:obj:`int`): Индекс для вставки.
  849. revision (:obj:`int`): TODO.
  850. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  851. *args: Произвольные аргументы (будут переданы в запрос).
  852. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  853. Returns:
  854. :obj:`yandex_music.Playlist`: Изменённый плейлист или :obj:`None`.
  855. Raises:
  856. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  857. """
  858. if user_id is None and self.account_uid is not None:
  859. user_id = self.account_uid
  860. diff = Difference().add_insert(at, {'id': track_id, 'album_id': album_id})
  861. return await self.users_playlists_change(kind, diff.to_json(), revision, user_id, *args, **kwargs)
  862. @log
  863. async def users_playlists_delete_track(
  864. self,
  865. kind: Union[str, int],
  866. from_: int,
  867. to: int,
  868. revision: int = 1,
  869. user_id: UserIdType = None,
  870. *args: Any,
  871. **kwargs: Any,
  872. ) -> Optional[Playlist]:
  873. """Удаление треков из плейлиста.
  874. Note:
  875. Для удаление необходимо указать границы с какого по какой элемент (трек) удалить.
  876. Args:
  877. kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
  878. from_ (:obj:`int`): С какого индекса.
  879. to (:obj:`int`): По какой индекс.
  880. revision (:obj:`int`): TODO.
  881. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя владеющим плейлистом.
  882. *args: Произвольные аргументы (будут переданы в запрос).
  883. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  884. Returns:
  885. :obj:`yandex_music.Playlist` | :obj:`None`: Изменённый плейлист или :obj:`None`.
  886. Raises:
  887. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  888. """
  889. if user_id is None and self.account_uid is not None:
  890. user_id = self.account_uid
  891. diff = Difference().add_delete(from_, to)
  892. return await self.users_playlists_change(kind, diff.to_json(), revision, user_id, *args, **kwargs)
  893. @log
  894. async def rotor_account_status(self, *args: Any, **kwargs: Any) -> Optional[Status]:
  895. """Получение статуса пользователя с дополнительными полями.
  896. Note:
  897. Данный статус отличается от обычного наличием дополнительных полей, например, `skips_per_hour`.
  898. Args:
  899. *args: Произвольные аргументы (будут переданы в запрос).
  900. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  901. Returns:
  902. :obj:`yandex_music.Status` | :obj:`None`: Статус пользователя с дополнительными полями от радио или
  903. :obj:`None`.
  904. Raises:
  905. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  906. """
  907. url = f'{self.base_url}/rotor/account/status'
  908. result = await self._request.get(url, *args, **kwargs)
  909. return Status.de_json(result, self)
  910. @log
  911. async def rotor_stations_dashboard(self, *args: Any, **kwargs: Any) -> Optional[Dashboard]:
  912. """Получение рекомендованных станций текущего пользователя.
  913. Args:
  914. *args: Произвольные аргументы (будут переданы в запрос).
  915. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  916. Returns:
  917. :obj:`yandex_music.Dashboard` | :obj:`None`: Рекомендованные станции или :obj:`None`.
  918. Raises:
  919. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  920. """
  921. url = f'{self.base_url}/rotor/stations/dashboard'
  922. result = await self._request.get(url, *args, **kwargs)
  923. return Dashboard.de_json(result, self)
  924. @log
  925. async def rotor_stations_list(
  926. self, language: Optional[str] = None, *args: Any, **kwargs: Any
  927. ) -> List[StationResult]:
  928. """Получение всех радиостанций с настройками пользователя.
  929. Note:
  930. Доступные языки: en, uz, uk, us, ru, kk, hy.
  931. Чтобы определить что за тип станции (жанры, настроения, занятие и т.д.) необходимо смотреть в поле
  932. `id_for_from`.
  933. Args:
  934. language (:obj:`str`, optional): Язык, на котором будет информация о станциях. По умолчанию язык клиента.
  935. *args: Произвольные аргументы (будут переданы в запрос).
  936. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  937. Returns:
  938. :obj:`list` из :obj:`yandex_music.StationResult`: Список станций.
  939. Raises:
  940. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  941. """
  942. url = f'{self.base_url}/rotor/stations/list'
  943. if not language:
  944. language = self.language
  945. result = await self._request.get(url, {'language': language}, *args, **kwargs)
  946. return StationResult.de_list(result, self)
  947. @log
  948. async def rotor_station_feedback(
  949. self,
  950. station: str,
  951. type_: str,
  952. timestamp: TimestampType = None,
  953. from_: Optional[str] = None,
  954. batch_id: Optional[str] = None,
  955. total_played_seconds: Optional[Union[int, float]] = None,
  956. track_id: Optional[Union[str, int]] = None,
  957. **kwargs: Any,
  958. ) -> bool:
  959. """Отправка обратной связи на действия при прослушивании радио.
  960. Note:
  961. Сообщения о начале прослушивания радио, начале и конце трека, его пропуска.
  962. Известные типы обратной связи: `radioStarted`, `trackStarted`, `trackFinished`, `skip`.
  963. Пример `station`: `user:onyourwave`, `genre:allrock`.
  964. Пример `from_`: `mobile-radio-user-123456789`.
  965. Args:
  966. station (:obj:`str`): Станция.
  967. type_ (:obj:`str`): Тип отправляемого отзыва.
  968. timestamp (:obj:`str` | :obj:`float` | :obj:`int`, optional): Текущее время и дата.
  969. from_ (:obj:`str`, optional): Откуда начато воспроизведение радио.
  970. batch_id (:obj:`str`, optional): Уникальный идентификатор партии треков. Возвращается при получении треков.
  971. total_played_seconds (:obj:`int` |:obj:`float`, optional): Сколько было проиграно секунд трека
  972. перед действием.
  973. track_id (:obj:`int` | :obj:`str`, optional): Уникальной идентификатор трека.
  974. *args: Произвольные аргументы (будут переданы в запрос).
  975. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  976. Returns:
  977. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  978. Raises:
  979. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  980. """
  981. if timestamp is None:
  982. timestamp = datetime.now().timestamp()
  983. url = f'{self.base_url}/rotor/station/{station}/feedback'
  984. params = {}
  985. data = {'type': type_, 'timestamp': timestamp}
  986. if batch_id:
  987. params = {'batch-id': batch_id}
  988. if track_id:
  989. data.update({'trackId': track_id})
  990. if from_:
  991. data.update({'from': from_})
  992. if total_played_seconds:
  993. data.update({'totalPlayedSeconds': total_played_seconds})
  994. result = await self._request.post(url, params=params, json=data, **kwargs)
  995. return result == 'ok'
  996. @log
  997. async def rotor_station_feedback_radio_started(
  998. self,
  999. station: str,
  1000. from_: str,
  1001. batch_id: Optional[str] = None,
  1002. timestamp: TimestampType = None,
  1003. **kwargs: Any,
  1004. ) -> bool:
  1005. """Сокращение для::
  1006. client.rotor_station_feedback(station, 'radioStarted', timestamp, from, batch_id, **kwargs)
  1007. Returns:
  1008. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1009. Raises:
  1010. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1011. """
  1012. return await self.rotor_station_feedback(
  1013. station, 'radioStarted', timestamp, from_=from_, batch_id=batch_id, **kwargs
  1014. )
  1015. @log
  1016. async def rotor_station_feedback_track_started(
  1017. self,
  1018. station: str,
  1019. track_id: Union[str, int],
  1020. batch_id: Optional[str] = None,
  1021. timestamp: TimestampType = None,
  1022. **kwargs: Any,
  1023. ) -> bool:
  1024. """Сокращение для::
  1025. client.rotor_station_feedback(station, 'trackStarted', timestamp, track_id=track_id,
  1026. batch_id=batch_id, **kwargs)
  1027. Returns:
  1028. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1029. Raises:
  1030. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1031. """
  1032. return await self.rotor_station_feedback(
  1033. station, 'trackStarted', timestamp, track_id=track_id, batch_id=batch_id, **kwargs
  1034. )
  1035. @log
  1036. async def rotor_station_feedback_track_finished(
  1037. self,
  1038. station: str,
  1039. track_id: Union[str, int],
  1040. total_played_seconds: float,
  1041. batch_id: Optional[str] = None,
  1042. timestamp: TimestampType = None,
  1043. **kwargs: Any,
  1044. ) -> bool:
  1045. """Сокращение для::
  1046. client.rotor_station_feedback(station, 'trackFinished', timestamp,
  1047. track_id=track_id, total_played_seconds=total_played_seconds, batch_id=batch_id, **kwargs)
  1048. Returns:
  1049. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1050. Raises:
  1051. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1052. """
  1053. return await self.rotor_station_feedback(
  1054. station,
  1055. 'trackFinished',
  1056. timestamp,
  1057. track_id=track_id,
  1058. total_played_seconds=total_played_seconds,
  1059. batch_id=batch_id,
  1060. **kwargs,
  1061. )
  1062. @log
  1063. async def rotor_station_feedback_skip(
  1064. self,
  1065. station: str,
  1066. track_id: Union[str, int],
  1067. total_played_seconds: float,
  1068. batch_id: Optional[str] = None,
  1069. timestamp: TimestampType = None,
  1070. **kwargs: Any,
  1071. ) -> bool:
  1072. """Сокращение для::
  1073. client.rotor_station_feedback(station, 'skip', timestamp, track_id=track_id,
  1074. total_played_seconds=total_played_seconds, batch_id=batch_id, **kwargs)
  1075. Returns:
  1076. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1077. Raises:
  1078. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1079. """
  1080. return await self.rotor_station_feedback(
  1081. station,
  1082. 'skip',
  1083. timestamp,
  1084. track_id=track_id,
  1085. total_played_seconds=total_played_seconds,
  1086. batch_id=batch_id,
  1087. **kwargs,
  1088. )
  1089. @log
  1090. async def rotor_station_info(self, station: str, *args: Any, **kwargs: Any) -> List[StationResult]:
  1091. """Получение информации о станции и пользовательских настроек на неё.
  1092. Args:
  1093. station (:obj:`str`): Станция.
  1094. *args: Произвольные аргументы (будут переданы в запрос).
  1095. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1096. Returns:
  1097. :obj:`list` из :obj:`yandex_music.StationResult` | :obj:`None`: Информация о станции или :obj:`None`.
  1098. Raises:
  1099. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1100. """
  1101. url = f'{self.base_url}/rotor/station/{station}/info'
  1102. result = await self._request.get(url, *args, **kwargs)
  1103. return StationResult.de_list(result, self)
  1104. @log
  1105. async def rotor_station_settings2(
  1106. self,
  1107. station: str,
  1108. mood_energy: str,
  1109. diversity: str,
  1110. language: str = 'not-russian', # TODO(#555): заменить на any
  1111. type_: str = 'rotor',
  1112. **kwargs: Any,
  1113. ) -> bool:
  1114. """Изменение настроек определённой станции.
  1115. Note:
  1116. Доступные значения для `mood_energy`: `fun`, `active`, `calm`, `sad`, `all`.
  1117. Доступные значения для `diversity`: `favorite`, `popular`, `discover`, `default`.
  1118. Доступные значения для `language`: `not-russian`, `russian`, `any`.
  1119. Доступные значения для `type_`: `rotor`, `generative`.
  1120. У станций в `restrictions` есть Enum'ы, а в них `possible_values` - доступные значения для поля.
  1121. Args:
  1122. station (:obj:`str`): Станция.
  1123. mood_energy (:obj:`str`): Настроение.
  1124. diversity (:obj:`str`): Треки.
  1125. language (:obj:`str`): Язык.
  1126. type_ (:obj:`str`): Тип.
  1127. *args: Произвольные аргументы (будут переданы в запрос).
  1128. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1129. Returns:
  1130. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1131. Raises:
  1132. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1133. """
  1134. url = f'{self.base_url}/rotor/station/{station}/settings3'
  1135. data = {'moodEnergy': mood_energy, 'diversity': diversity, 'type': type_}
  1136. if language:
  1137. data.update({'language': language})
  1138. result = await self._request.post(url, json=data, **kwargs)
  1139. return result == 'ok'
  1140. @log
  1141. async def rotor_station_tracks(
  1142. self,
  1143. station: str,
  1144. settings2: bool = True,
  1145. queue: Optional[Union[str, int]] = None,
  1146. *args: Any,
  1147. **kwargs: Any,
  1148. ) -> Optional[StationTracksResult]:
  1149. """Получение цепочки треков определённой станции.
  1150. Note:
  1151. Запуск потока по сущности сервиса осуществляется через станцию `<type>:<id>`.
  1152. Например, станцией для запуска потока по треку будет `track:1234`.
  1153. Для продолжения цепочки треков необходимо:
  1154. 1. Передавать `ID` трека, что был до этого (первый в цепочки).
  1155. 2. Отправить фидбек о конце или скипе трека, что был передан в `queue`.
  1156. 3. Отправить фидбек о начале следующего трека (второй в цепочки).
  1157. 4. Выполнить запрос получения треков. В ответе придёт новые треки или произойдёт сдвиг цепочки на 1 элемент.
  1158. Проход по цепочке до конца не изучен. Часто встречаются дубликаты.
  1159. Все официальные клиенты выполняют запросы с `settings2 = True`.
  1160. Args:
  1161. station (:obj:`str`): Станция.
  1162. settings2 (:obj:`bool`, optional): Использовать ли второй набор настроек.
  1163. queue (:obj:`str` | :obj:`int`, optional): Уникальной идентификатор трека, который только что был.
  1164. *args: Произвольные аргументы (будут переданы в запрос).
  1165. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1166. Returns:
  1167. :obj:`yandex_music.StationTracksResult` | :obj:`None`: Последовательность треков станции или :obj:`None`.
  1168. Raises:
  1169. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1170. """
  1171. url = f'{self.base_url}/rotor/station/{station}/tracks'
  1172. params = {}
  1173. if settings2:
  1174. params = {'settings2': str(True)}
  1175. if queue:
  1176. params = {'queue': queue}
  1177. result = await self._request.get(url, params, *args, **kwargs)
  1178. return StationTracksResult.de_json(result, self)
  1179. @log
  1180. async def artists_brief_info(self, artist_id: Union[str, int], *args: Any, **kwargs: Any) -> Optional[BriefInfo]:
  1181. """Получение информации об артисте.
  1182. Args:
  1183. artist_id (:obj:`str` | :obj:`int`): Уникальный идентификатор исполнителя.
  1184. *args: Произвольные аргументы (будут переданы в запрос).
  1185. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1186. Returns:
  1187. :obj:`yandex_music.BriefInfo` | :obj:`None`: Информация об артисте или :obj:`None`.
  1188. Raises:
  1189. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1190. """
  1191. url = f'{self.base_url}/artists/{artist_id}/brief-info'
  1192. result = await self._request.get(url, *args, **kwargs)
  1193. return BriefInfo.de_json(result, self)
  1194. @log
  1195. async def artists_tracks(
  1196. self,
  1197. artist_id: Union[str, int],
  1198. page: int = 0,
  1199. page_size: int = 20,
  1200. *args: Any,
  1201. **kwargs: Any,
  1202. ) -> Optional[ArtistTracks]:
  1203. """Получение треков артиста.
  1204. Args:
  1205. artist_id (:obj:`str` | :obj:`int`): Уникальный идентификатор артиста.
  1206. page (:obj:`int`, optional): Номер страницы.
  1207. page_size (:obj:`int`, optional): Количество треков на странице.
  1208. *args: Произвольные аргументы (будут переданы в запрос).
  1209. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1210. Returns:
  1211. :obj:`yandex_music.ArtistsTracks` | :obj:`None`: Страница списка треков артиста или :obj:`None`.
  1212. Raises:
  1213. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1214. """
  1215. url = f'{self.base_url}/artists/{artist_id}/tracks'
  1216. params = {'page': page, 'page-size': page_size}
  1217. result = await self._request.get(url, params, *args, **kwargs)
  1218. return ArtistTracks.de_json(result, self)
  1219. @log
  1220. async def artists_direct_albums(
  1221. self,
  1222. artist_id: Union[str, int],
  1223. page: int = 0,
  1224. page_size: int = 20,
  1225. sort_by: str = 'year',
  1226. *args: Any,
  1227. **kwargs: Any,
  1228. ) -> Optional[ArtistAlbums]:
  1229. """Получение альбомов артиста.
  1230. Note:
  1231. Известные значения для `sort_by`: `year`, `rating`.
  1232. Args:
  1233. artist_id (:obj:`str` | :obj:`int`): Уникальный идентификатор артиста.
  1234. page (:obj:`int`, optional): Номер страницы.
  1235. page_size (:obj:`int`, optional): Количество альбомов на странице.
  1236. sort_by (:obj:`str`, optional): Параметр для сортировки.
  1237. *args: Произвольные аргументы (будут переданы в запрос).
  1238. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1239. Returns:
  1240. :obj:`yandex_music.ArtistAlbums` | :obj:`None`: Страница списка альбомов артиста или :obj:`None`.
  1241. Raises:
  1242. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1243. """
  1244. url = f'{self.base_url}/artists/{artist_id}/direct-albums'
  1245. params = {'sort-by': sort_by, 'page': page, 'page-size': page_size}
  1246. result = await self._request.get(url, params, *args, **kwargs)
  1247. return ArtistAlbums.de_json(result, self)
  1248. async def _like_action(
  1249. self,
  1250. object_type: str,
  1251. ids: Union[List[Union[str, int]], str, int],
  1252. remove: bool = False,
  1253. user_id: UserIdType = None,
  1254. *args: Any,
  1255. **kwargs: Any,
  1256. ) -> bool:
  1257. """Действия с отметкой "Мне нравится".
  1258. Note:
  1259. Типы объектов: `track` - трек, `artist` - исполнитель, `playlist` - плейлист, `album` - альбом.
  1260. Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор
  1261. плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста.
  1262. Args:
  1263. object_type (:obj:`str`): Тип объекта.
  1264. ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1265. идентификатор объекта или объектов.
  1266. remove (:obj:`bool`, optional): Если :obj:`True` то снимает отметку, иначе ставит.
  1267. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1268. используется ID текущего пользователя.
  1269. *args: Произвольные аргументы (будут переданы в запрос).
  1270. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1271. Returns:
  1272. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1273. Raises:
  1274. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1275. """
  1276. if user_id is None and self.account_uid is not None:
  1277. user_id = self.account_uid
  1278. action = 'remove' if remove else 'add-multiple'
  1279. url = f'{self.base_url}/users/{user_id}/likes/{object_type}s/{action}'
  1280. result = await self._request.post(url, {f'{object_type}-ids': ids}, *args, **kwargs)
  1281. if object_type == 'track':
  1282. return 'revision' in result
  1283. return result == 'ok'
  1284. @log
  1285. async def users_likes_tracks_add(
  1286. self,
  1287. track_ids: Union[List[Union[str, int]], str, int],
  1288. user_id: UserIdType = None,
  1289. **kwargs: Any,
  1290. ) -> bool:
  1291. """Поставить отметку "Мне нравится" треку/трекам.
  1292. Note:
  1293. Так же снимает отметку "Не рекомендовать" если она есть.
  1294. Args:
  1295. track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1296. идентификатор трека или треков.
  1297. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1298. используется ID текущего пользователя.
  1299. *args: Произвольные аргументы (будут переданы в запрос).
  1300. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1301. Returns:
  1302. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1303. Raises:
  1304. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1305. """
  1306. return await self._like_action('track', track_ids, remove=False, user_id=user_id, **kwargs)
  1307. @log
  1308. async def users_likes_tracks_remove(
  1309. self,
  1310. track_ids: Union[List[Union[str, int]], str, int],
  1311. user_id: UserIdType = None,
  1312. **kwargs: Any,
  1313. ) -> bool:
  1314. """Снять отметку "Мне нравится" у трека/треков.
  1315. Args:
  1316. track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1317. идентификатор трека или треков.
  1318. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1319. используется ID текущего пользователя.
  1320. *args: Произвольные аргументы (будут переданы в запрос).
  1321. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1322. Returns:
  1323. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1324. Raises:
  1325. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1326. """
  1327. return await self._like_action('track', track_ids, remove=True, user_id=user_id, **kwargs)
  1328. @log
  1329. async def users_likes_artists_add(
  1330. self,
  1331. artist_ids: Union[List[Union[str, int]], str, int],
  1332. user_id: UserIdType = None,
  1333. **kwargs: Any,
  1334. ) -> bool:
  1335. """Поставить отметку "Мне нравится" исполнителю/исполнителям.
  1336. Args:
  1337. artist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1338. идентификатор артиста или артистов.
  1339. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1340. используется ID текущего пользователя.
  1341. *args: Произвольные аргументы (будут переданы в запрос).
  1342. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1343. Returns:
  1344. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1345. Raises:
  1346. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1347. """
  1348. return await self._like_action('artist', artist_ids, remove=False, user_id=user_id, **kwargs)
  1349. @log
  1350. async def users_likes_artists_remove(
  1351. self,
  1352. artist_ids: Union[List[Union[str, int]], str, int],
  1353. user_id: UserIdType = None,
  1354. **kwargs: Any,
  1355. ) -> bool:
  1356. """Снять отметку "Мне нравится" у исполнителя/исполнителей.
  1357. Args:
  1358. artist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1359. идентификатор артиста или артистов.
  1360. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1361. используется ID текущего пользователя.
  1362. *args: Произвольные аргументы (будут переданы в запрос).
  1363. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1364. Returns:
  1365. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1366. Raises:
  1367. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1368. """
  1369. return await self._like_action('artist', artist_ids, remove=True, user_id=user_id, **kwargs)
  1370. @log
  1371. async def users_likes_playlists_add(
  1372. self,
  1373. playlist_ids: Union[List[Union[str, int]], str, int],
  1374. user_id: UserIdType = None,
  1375. **kwargs: Any,
  1376. ) -> bool:
  1377. """Поставить отметку "Мне нравится" плейлисту/плейлистам.
  1378. Note:
  1379. Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор
  1380. плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста.
  1381. Args:
  1382. playlist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1383. идентификатор плейлиста или плейлистов.
  1384. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1385. используется ID текущего пользователя.
  1386. *args: Произвольные аргументы (будут переданы в запрос).
  1387. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1388. Returns:
  1389. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1390. Raises:
  1391. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1392. """
  1393. return await self._like_action('playlist', playlist_ids, remove=False, user_id=user_id, **kwargs)
  1394. @log
  1395. async def users_likes_playlists_remove(
  1396. self,
  1397. playlist_ids: Union[List[Union[str, int]], str, int],
  1398. user_id: UserIdType = None,
  1399. **kwargs: Any,
  1400. ) -> bool:
  1401. """Снять отметку "Мне нравится" у плейлиста/плейлистов.
  1402. Note:
  1403. Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор
  1404. плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста.
  1405. Args:
  1406. playlist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1407. идентификатор плейлиста или плейлистов.
  1408. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1409. используется ID текущего пользователя.
  1410. *args: Произвольные аргументы (будут переданы в запрос).
  1411. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1412. Returns:
  1413. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1414. Raises:
  1415. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1416. """
  1417. return await self._like_action('playlist', playlist_ids, remove=True, user_id=user_id, **kwargs)
  1418. @log
  1419. async def users_likes_albums_add(
  1420. self,
  1421. album_ids: Union[List[Union[str, int]], str, int],
  1422. user_id: UserIdType = None,
  1423. **kwargs: Any,
  1424. ) -> bool:
  1425. """Поставить отметку "Мне нравится" альбому/альбомам.
  1426. Args:
  1427. album_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1428. идентификатор артиста или артистов.
  1429. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1430. используется ID текущего пользователя.
  1431. *args: Произвольные аргументы (будут переданы в запрос).
  1432. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1433. Returns:
  1434. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1435. Raises:
  1436. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1437. """
  1438. return await self._like_action('album', album_ids, remove=False, user_id=user_id, **kwargs)
  1439. @log
  1440. async def users_likes_albums_remove(
  1441. self,
  1442. album_ids: Union[List[Union[str, int]], str, int],
  1443. user_id: UserIdType = None,
  1444. **kwargs: Any,
  1445. ) -> bool:
  1446. """Снять отметку "Мне нравится" у альбома/альбомов.
  1447. Args:
  1448. album_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1449. идентификатор артиста или артистов.
  1450. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1451. используется ID текущего пользователя.
  1452. *args: Произвольные аргументы (будут переданы в запрос).
  1453. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1454. Returns:
  1455. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1456. Raises:
  1457. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1458. """
  1459. return await self._like_action('album', album_ids, remove=True, user_id=user_id, **kwargs)
  1460. async def _get_list(
  1461. self,
  1462. object_type: str,
  1463. ids: Union[List[Union[str, int]], int, str],
  1464. params: Optional['JSONType'] = None,
  1465. *args: Any,
  1466. **kwargs: Any,
  1467. ) -> List[Union[Artist, Album, Track, Playlist]]:
  1468. """Получение объекта/объектов.
  1469. Args:
  1470. object_type (:obj:`str`): Тип объекта.
  1471. ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1472. идентификатор объекта или объектов.
  1473. params (:obj:`dict`, optional): Параметры, которые будут переданы в запрос.
  1474. *args: Произвольные аргументы (будут переданы в запрос).
  1475. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1476. Returns:
  1477. :obj:`list` из :obj:`yandex_music.Artist` | :obj:`list` из :obj:`yandex_music.Album` |
  1478. :obj:`list` из :obj:`yandex_music.Track` | :obj:`list` из :obj:`yandex_music.Playlist`: Запрошенный
  1479. объект.
  1480. Raises:
  1481. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1482. """
  1483. if params is None:
  1484. params = {}
  1485. params.update({f'{object_type}-ids': ids})
  1486. url = f'{self.base_url}/{object_type}s' + ('/list' if object_type == 'playlist' else '')
  1487. result = await self._request.post(url, params, *args, **kwargs)
  1488. return de_list[object_type](result, self)
  1489. @log
  1490. async def artists(
  1491. self, artist_ids: Union[List[Union[str, int]], int, str], *args: Any, **kwargs: Any
  1492. ) -> List[Artist]:
  1493. """Получение исполнителя/исполнителей.
  1494. Args:
  1495. artist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1496. идентификатор исполнителя или исполнителей.
  1497. *args: Произвольные аргументы (будут переданы в запрос).
  1498. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1499. Returns:
  1500. :obj:`list` из :obj:`yandex_music.Artist`: Исполнитель или исполнители.
  1501. Raises:
  1502. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1503. """
  1504. return await self._get_list('artist', artist_ids, *args, **kwargs)
  1505. @log
  1506. async def albums(self, album_ids: Union[List[Union[str, int]], int, str], *args: Any, **kwargs: Any) -> List[Album]:
  1507. """Получение альбома/альбомов.
  1508. Args:
  1509. album_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1510. идентификатор альбома или альбомов.
  1511. *args: Произвольные аргументы (будут переданы в запрос).
  1512. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1513. Returns:
  1514. :obj:`list` из :obj:`yandex_music.Album`: Альбом или альбомы.
  1515. Raises:
  1516. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1517. """
  1518. return await self._get_list('album', album_ids, *args, **kwargs)
  1519. @log
  1520. async def tracks(
  1521. self,
  1522. track_ids: Union[List[str], List[int], List[Union[str, int]], int, str],
  1523. with_positions: bool = True,
  1524. *args: Any,
  1525. **kwargs: Any,
  1526. ) -> List[Track]:
  1527. """Получение трека/треков.
  1528. Args:
  1529. track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1530. идентификатор трека или треков.
  1531. with_positions (:obj:`bool`, optional): С позициями TODO.
  1532. *args: Произвольные аргументы (будут переданы в запрос).
  1533. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1534. Returns:
  1535. :obj:`list` из :obj:`yandex_music.Track`: Трек или Треки.
  1536. Raises:
  1537. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1538. """
  1539. return await self._get_list('track', track_ids, {'with-positions': str(with_positions)}, *args, **kwargs)
  1540. @log
  1541. async def playlists_list(
  1542. self, playlist_ids: Union[List[Union[str, int]], int, str], *args: Any, **kwargs: Any
  1543. ) -> List[Playlist]:
  1544. """Получение плейлиста/плейлистов.
  1545. Note:
  1546. Идентификатор плейлиста указывается в формате `owner_id:playlist_id`. Где `playlist_id` - идентификатор
  1547. плейлиста, `owner_id` - уникальный идентификатор владельца плейлиста.
  1548. Данный метод возвращает сокращенную модель плейлиста для отображения больших список.
  1549. Warning:
  1550. Данный метод не возвращает список треков у плейлиста! Для получения объекта :obj:`yandex_music.Playlist` c
  1551. заполненным полем `tracks` используйте метод :func:`yandex_music.ClientAsync.users_playlists` или
  1552. метод :func:`yandex_music.Playlist.fetch_tracks`.
  1553. Args:
  1554. playlist_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1555. идентификатор плейлиста или плейлистов.
  1556. *args: Произвольные аргументы (будут переданы в запрос).
  1557. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1558. Returns:
  1559. :obj:`list` из :obj:`yandex_music.Playlist`: Плейлист или плейлисты.
  1560. Raises:
  1561. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1562. """
  1563. return await self._get_list('playlist', playlist_ids, *args, **kwargs)
  1564. @log
  1565. async def playlists_collective_join(self, user_id: int, token: str, **kwargs: Any) -> bool:
  1566. """Присоединение к плейлисту как соавтор.
  1567. Note:
  1568. В качестве `user_id` принимается исключительно числовой уникальный идентификатор пользователя, не username.
  1569. Токен можно получить в Web-версии. Для этого, на странице плейлиста нужно нажать на
  1570. "Добавить соавтора". В полученной ссылке GET параметр `token` и будет токеном для присоединения.
  1571. Args:
  1572. user_id (:obj:`int`): Владелец плейлиста.
  1573. token (:obj:`str`): Токен для присоединения.
  1574. **kwargs: Произвольные аргументы (будут переданы в запрос).
  1575. Returns:
  1576. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1577. Raises:
  1578. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1579. """
  1580. url = f'{self.base_url}/playlists/collective/join'
  1581. params = {'uid': user_id, 'token': token}
  1582. result = await self._request.post(url, params=params, **kwargs)
  1583. return result == 'ok'
  1584. @log
  1585. async def users_playlists_list(self, user_id: UserIdType = None, *args: Any, **kwargs: Any) -> List[Playlist]:
  1586. """Получение списка плейлистов пользователя.
  1587. Args:
  1588. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1589. используется ID текущего пользователя.
  1590. *args: Произвольные аргументы (будут переданы в запрос).
  1591. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1592. Returns:
  1593. :obj:`list` из :obj:`yandex_music.Playlist`: Плейлисты пользователя.
  1594. Raises:
  1595. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1596. """
  1597. if user_id is None and self.account_uid is not None:
  1598. user_id = self.account_uid
  1599. url = f'{self.base_url}/users/{user_id}/playlists/list'
  1600. result = await self._request.get(url, *args, **kwargs)
  1601. return Playlist.de_list(result, self)
  1602. async def _get_likes(
  1603. self,
  1604. object_type: str,
  1605. user_id: UserIdType = None,
  1606. params: Optional['JSONType'] = None,
  1607. *args: Any,
  1608. **kwargs: Any,
  1609. ) -> Union[List[Like], Optional[TracksList]]:
  1610. """Получение объектов с отметкой "Мне нравится".
  1611. Args:
  1612. object_type (:obj:`str`): Тип объекта.
  1613. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1614. используется ID текущего пользователя.
  1615. params (:obj:`dict`, optional): Параметры, которые будут переданы в запрос.
  1616. *args: Произвольные аргументы (будут переданы в запрос).
  1617. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1618. Returns:
  1619. :obj:`list` из :obj:`yandex_music.Like` | :obj:`yandex_music.TracksList`: Объекты с отметкой "Мне нравится".
  1620. Raises:
  1621. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1622. """
  1623. if user_id is None and self.account_uid is not None:
  1624. user_id = self.account_uid
  1625. url = f'{self.base_url}/users/{user_id}/likes/{object_type}s'
  1626. result = await self._request.get(url, params, *args, **kwargs)
  1627. if object_type == 'track':
  1628. return TracksList.de_json(result.get('library'), self)
  1629. return Like.de_list(result, self, object_type)
  1630. @log
  1631. async def users_likes_tracks(
  1632. self,
  1633. user_id: UserIdType = None,
  1634. if_modified_since_revision: int = 0,
  1635. *args: Any,
  1636. **kwargs: Any,
  1637. ) -> Optional[TracksList]:
  1638. """Получение треков с отметкой "Мне нравится".
  1639. Args:
  1640. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1641. используется ID текущего пользователя.
  1642. if_modified_since_revision (:obj:`int`, optional): TODO.
  1643. *args: Произвольные аргументы (будут переданы в запрос).
  1644. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1645. Returns:
  1646. :obj:`yandex_music.TracksList`: Треки с отметкой "Мне нравится".
  1647. Raises:
  1648. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1649. """
  1650. return await self._get_likes(
  1651. 'track', user_id, {'if-modified-since-revision': if_modified_since_revision}, *args, **kwargs
  1652. )
  1653. @log
  1654. async def users_likes_albums(
  1655. self, user_id: UserIdType = None, rich: bool = True, *args: Any, **kwargs: Any
  1656. ) -> List[Like]:
  1657. """Получение альбомов с отметкой "Мне нравится".
  1658. Args:
  1659. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1660. используется ID текущего пользователя.
  1661. rich (:obj:`bool`, optional): Если False, то приходит укороченная версия.
  1662. *args: Произвольные аргументы (будут переданы в запрос).
  1663. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1664. Returns:
  1665. :obj:`list` из :obj:`yandex_music.Like`: Альбомы с отметкой "Мне нравится".
  1666. Raises:
  1667. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1668. """
  1669. return await self._get_likes('album', user_id, {'rich': str(rich)}, *args, **kwargs)
  1670. @log
  1671. async def users_likes_artists(
  1672. self,
  1673. user_id: UserIdType = None,
  1674. with_timestamps: bool = True,
  1675. *args: Any,
  1676. **kwargs: Any,
  1677. ) -> List[Like]:
  1678. """Получение артистов с отметкой "Мне нравится".
  1679. Args:
  1680. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1681. используется ID текущего пользователя.
  1682. with_timestamps (:obj:`bool`, optional): С временными метками TODO.
  1683. *args: Произвольные аргументы (будут переданы в запрос).
  1684. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1685. Returns:
  1686. :obj:`list` из :obj:`yandex_music.Like`: Артисты с отметкой "Мне нравится".
  1687. Raises:
  1688. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1689. """
  1690. return await self._get_likes('artist', user_id, {'with-timestamps': str(with_timestamps)}, *args, **kwargs)
  1691. @log
  1692. async def users_likes_playlists(self, user_id: UserIdType = None, *args: Any, **kwargs: Any) -> List[Like]:
  1693. """Получение плейлистов с отметкой "Мне нравится".
  1694. Args:
  1695. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1696. используется ID текущего пользователя.
  1697. *args: Произвольные аргументы (будут переданы в запрос).
  1698. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1699. Returns:
  1700. :obj:`list` из :obj:`yandex_music.Like`: Плейлисты с отметкой "Мне нравится".
  1701. Raises:
  1702. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1703. """
  1704. return await self._get_likes('playlist', user_id, *args, **kwargs)
  1705. @log
  1706. async def users_dislikes_tracks(
  1707. self,
  1708. user_id: UserIdType = None,
  1709. if_modified_since_revision: int = 0,
  1710. *args: Any,
  1711. **kwargs: Any,
  1712. ) -> Optional[TracksList]:
  1713. """Получение треков с отметкой "Не рекомендовать".
  1714. Args:
  1715. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1716. используется ID текущего пользователя.
  1717. if_modified_since_revision (:obj:`bool`, optional): TODO.
  1718. *args: Произвольные аргументы (будут переданы в запрос).
  1719. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1720. Returns:
  1721. :obj:`list` из :obj:`yandex_music.TracksList`: Треки с отметкой "Не рекомендовать".
  1722. Raises:
  1723. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1724. """
  1725. if user_id is None and self.account_uid is not None:
  1726. user_id = self.account_uid
  1727. url = f'{self.base_url}/users/{user_id}/dislikes/tracks'
  1728. result = await self._request.get(
  1729. url, {'if_modified_since_revision': if_modified_since_revision}, *args, **kwargs
  1730. )
  1731. return TracksList.de_json(result.get('library'), self)
  1732. async def _dislike_action(
  1733. self,
  1734. ids: Union[List[Union[str, int]], str, int],
  1735. remove: bool = False,
  1736. user_id: UserIdType = None,
  1737. *args: Any,
  1738. **kwargs: Any,
  1739. ) -> bool:
  1740. """Действия с отметкой "Не рекомендовать".
  1741. Args:
  1742. ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1743. идентификатор объекта или объектов.
  1744. remove (:obj:`bool`, optional): Если :obj:`True`, то снимает отметку, иначе ставит.
  1745. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1746. используется ID текущего пользователя.
  1747. *args: Произвольные аргументы (будут переданы в запрос).
  1748. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1749. Returns:
  1750. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1751. Raises:
  1752. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1753. """
  1754. if user_id is None and self.account_uid is not None:
  1755. user_id = self.account_uid
  1756. action = 'remove' if remove else 'add-multiple'
  1757. url = f'{self.base_url}/users/{user_id}/dislikes/tracks/{action}'
  1758. result = await self._request.post(url, {'track-ids': ids}, *args, **kwargs)
  1759. return 'revision' in result
  1760. @log
  1761. async def users_dislikes_tracks_add(
  1762. self,
  1763. track_ids: Union[List[Union[str, int]], str, int],
  1764. user_id: UserIdType = None,
  1765. **kwargs: Any,
  1766. ) -> bool:
  1767. """Поставить отметку "Не рекомендовать" треку/трекам.
  1768. Note:
  1769. Так же снимает отметку "Мне нравится" если она есть.
  1770. Args:
  1771. track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1772. идентификатор трека или треков.
  1773. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1774. используется ID текущего пользователя.
  1775. *args: Произвольные аргументы (будут переданы в запрос).
  1776. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1777. Returns:
  1778. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1779. Raises:
  1780. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1781. """
  1782. return await self._dislike_action(track_ids, remove=False, user_id=user_id, **kwargs)
  1783. @log
  1784. async def users_dislikes_tracks_remove(
  1785. self,
  1786. track_ids: Union[List[Union[str, int]], str, int],
  1787. user_id: UserIdType = None,
  1788. **kwargs: Any,
  1789. ) -> bool:
  1790. """Снять отметку "Не рекомендовать" у трека/треков.
  1791. Args:
  1792. track_ids (:obj:`str` | :obj:`int` | :obj:`list` из :obj:`str` | :obj:`list` из :obj:`int`): Уникальный
  1793. идентификатор трека или треков.
  1794. user_id (:obj:`str` | :obj:`int`, optional): Уникальный идентификатор пользователя. Если не указан
  1795. используется ID текущего пользователя.
  1796. *args: Произвольные аргументы (будут переданы в запрос).
  1797. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1798. Returns:
  1799. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1800. Raises:
  1801. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1802. """
  1803. return await self._dislike_action(track_ids, remove=True, user_id=user_id, **kwargs)
  1804. @log
  1805. async def after_track(
  1806. self,
  1807. next_track_id: Union[str, int],
  1808. context_item: str,
  1809. prev_track_id: Optional[Union[str, int]] = None,
  1810. context: str = 'playlist',
  1811. types: str = 'shot',
  1812. from_: str = 'mobile-landing-origin-default',
  1813. *args: Any,
  1814. **kwargs: Any,
  1815. ) -> Optional[ShotEvent]:
  1816. """Получение рекламы или шота от Алисы после трека.
  1817. Note:
  1818. При получения шота от Алисы `prev_track_id` можно не указывать.
  1819. Если `context = 'playlist'`, то в `context_item` необходимо передать `{OWNER_PLAYLIST}:{ID_PLAYLIST}`.
  1820. Плейлист с Алисой имеет владельца с `id = 940441070`.
  1821. ID плейлиста можно получить из блоков landing'a. Получить шот чужого плейлиста нельзя.
  1822. Известные значения `context`: `playlist`.
  1823. Известные значения `types`: `shot`, `ad`.
  1824. Args:
  1825. prev_track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор предыдущего трека.
  1826. next_track_id (:obj:`str` | :obj:`int`): Уникальный идентификатор следующего трека.
  1827. context_item (:obj:`str`): Уникальный идентификатор контекста.
  1828. context (:obj:`str`, optional): Место, откуда было вызвано получение.
  1829. types (:obj:`str`, optional): Тип того, что вернуть после трека.
  1830. from_ (:obj:`str`, optional): Место, с которого попали в контекст.
  1831. *args: Произвольные аргументы (будут переданы в запрос).
  1832. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1833. Returns:
  1834. :obj:`yandex_music.ShotEvent`: Шот от Алисы или :obj:`None`.
  1835. Raises:
  1836. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1837. """
  1838. url = f'{self.base_url}/after-track'
  1839. params = {
  1840. 'from': from_,
  1841. 'prevTrackId': prev_track_id,
  1842. 'nextTrackId': next_track_id,
  1843. 'context': context,
  1844. 'contextItem': context_item,
  1845. 'types': types,
  1846. }
  1847. result = await self._request.get(url, params, *args, **kwargs)
  1848. # TODO (MarshalX) судя по всему ручка ещё возвращает рекламу после треков для пользователей без подписки.
  1849. # https://github.com/MarshalX/yandex-music-api/issues/557
  1850. return ShotEvent.de_json(result.get('shot_event'), self)
  1851. @log
  1852. async def queues_list(self, device: Optional[str] = None, *args: Any, **kwargs: Any) -> List[QueueItem]:
  1853. """Получение всех очередей треков с разных устройств для синхронизации между ними.
  1854. Note:
  1855. Именно к `device` привязывается очередь. На одном устройстве может быть создана одна очередь.
  1856. Аргумент `device` имеет следующий формат: `ключ=значение; ключ2=значение2`. Обязательные паля указы в
  1857. значении по умолчанию.
  1858. Args:
  1859. device (:obj:`str`, optional): Содержит информацию об устройстве с которого выполняется запрос.
  1860. *args: Произвольные аргументы (будут переданы в запрос).
  1861. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1862. Returns:
  1863. :obj:`list` из :obj:`yandex_music.QueueItem`: Элементы очереди всех устройств.
  1864. Raises:
  1865. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1866. """
  1867. if not device:
  1868. device = self.device
  1869. url = f'{self.base_url}/queues'
  1870. self._request.headers['X-Yandex-Music-Device'] = device
  1871. result = await self._request.get(url, *args, **kwargs)
  1872. return QueueItem.de_list(result.get('queues'), self)
  1873. @log
  1874. async def queue(self, queue_id: str, *args: Any, **kwargs: Any) -> Optional[Queue]:
  1875. """Получение информации об очереди треков и самих треков в ней.
  1876. Args:
  1877. queue_id (:obj:`str`): Уникальный идентификатор очереди.
  1878. *args: Произвольные аргументы (будут переданы в запрос).
  1879. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1880. Returns:
  1881. :obj:`yandex_music.Queue`: Очередь или :obj:`None`.
  1882. Raises:
  1883. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1884. """
  1885. url = f'{self.base_url}/queues/{queue_id}'
  1886. result = await self._request.get(url, *args, **kwargs)
  1887. return Queue.de_json(result, self)
  1888. @log
  1889. async def queue_update_position(
  1890. self, queue_id: str, current_index: int, device: Optional[str] = None, **kwargs
  1891. ) -> bool:
  1892. """Установка текущего индекса проигрываемого трека в очереди треков.
  1893. Note:
  1894. Изменить можно только у той очереди, которая была создана с переданного `device`!
  1895. Args:
  1896. queue_id (:obj:`str`): Уникальный идентификатор очереди.
  1897. current_index (:obj:`int`): Текущий индекс.
  1898. device (:obj:`str`, optional): Содержит информацию об устройстве с которого выполняется запрос.
  1899. *args: Произвольные аргументы (будут переданы в запрос).
  1900. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1901. Returns:
  1902. :obj:`bool`: :obj:`True` при успешном выполнении запроса, иначе :obj:`False`.
  1903. Raises:
  1904. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1905. """
  1906. if not device:
  1907. device = self.device
  1908. url = f'{self.base_url}/queues/{queue_id}/update-position'
  1909. self._request.headers['X-Yandex-Music-Device'] = device
  1910. result = await self._request.post(
  1911. url, {'isInteractive': False}, params={'currentIndex': current_index}, **kwargs
  1912. )
  1913. return result.get('status') == 'ok'
  1914. @log
  1915. async def queue_create(
  1916. self, queue: Union[Queue, str], device: Optional[str] = None, *args: Any, **kwargs: Any
  1917. ) -> Optional[str]:
  1918. """Создание новой очереди треков.
  1919. Args:
  1920. queue (:obj:`yandex_music.Queue` | :obj:`str`): Объект очереди или JSON строка с этим объектом.
  1921. device (:obj:`str`, optional): Содержит информацию об устройстве с которого выполняется запрос.
  1922. *args: Произвольные аргументы (будут переданы в запрос).
  1923. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  1924. Returns:
  1925. :obj:`str`: Вернёт уникальный идентификатор созданной очереди, иначе :obj:`None`.
  1926. Raises:
  1927. :class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
  1928. """
  1929. if not device:
  1930. device = self.device
  1931. if isinstance(queue, Queue):
  1932. queue = queue.to_json(True)
  1933. url = f'{self.base_url}/queues'
  1934. self._request.headers['X-Yandex-Music-Device'] = device
  1935. result = await self._request.post(url, queue, *args, **kwargs)
  1936. return result.get('id')
  1937. # camelCase псевдонимы
  1938. #: Псевдоним для :attr:`account_status`
  1939. accountStatus = account_status
  1940. #: Псевдоним для :attr:`account_settings`
  1941. accountSettings = account_settings
  1942. #: Псевдоним для :attr:`account_settings_set`
  1943. accountSettingsSet = account_settings_set
  1944. #: Псевдоним для :attr:`permission_alerts`
  1945. permissionAlerts = permission_alerts
  1946. #: Псевдоним для :attr:`account_experiments`
  1947. accountExperiments = account_experiments
  1948. #: Псевдоним для :attr:`consume_promo_code`
  1949. consumePromoCode = consume_promo_code
  1950. #: Псевдоним для :attr:`feed_wizard_is_passed`
  1951. feedWizardIsPassed = feed_wizard_is_passed
  1952. #: Псевдоним для :attr:`new_releases`
  1953. newReleases = new_releases
  1954. #: Псевдоним для :attr:`new_playlists`
  1955. newPlaylists = new_playlists
  1956. #: Псевдоним для :attr:`tracks_download_info`
  1957. tracksDownloadInfo = tracks_download_info
  1958. #: Псевдоним для :attr:`track_supplement`
  1959. trackSupplement = track_supplement
  1960. #: Псевдоним для :attr:`tracks_lyrics`
  1961. tracksLyrics = tracks_lyrics
  1962. #: Псевдоним для :attr:`tracks_similar`
  1963. tracksSimilar = tracks_similar
  1964. #: Псевдоним для :attr:`play_audio`
  1965. playAudio = play_audio
  1966. #: Псевдоним для :attr:`albums_with_tracks`
  1967. albumsWithTracks = albums_with_tracks
  1968. #: Псевдоним для :attr:`search_suggest`
  1969. searchSuggest = search_suggest
  1970. #: Псевдоним для :attr:`users_settings`
  1971. usersSettings = users_settings
  1972. #: Псевдоним для :attr:`users_playlists`
  1973. usersPlaylists = users_playlists
  1974. #: Псевдоним для :attr:`users_playlists_recommendations`
  1975. usersPlaylistsRecommendations = users_playlists_recommendations
  1976. #: Псевдоним для :attr:`users_playlists_create`
  1977. usersPlaylistsCreate = users_playlists_create
  1978. #: Псевдоним для :attr:`users_playlists_delete`
  1979. usersPlaylistsDelete = users_playlists_delete
  1980. #: Псевдоним для :attr:`users_playlists_name`
  1981. usersPlaylistsName = users_playlists_name
  1982. #: Псевдоним для :attr:`users_playlists_visibility`
  1983. usersPlaylistsVisibility = users_playlists_visibility
  1984. #: Псевдоним для :attr:`users_playlists_change`
  1985. usersPlaylistsChange = users_playlists_change
  1986. #: Псевдоним для :attr:`users_playlists_insert_track`
  1987. usersPlaylistsInsertTrack = users_playlists_insert_track
  1988. #: Псевдоним для :attr:`users_playlists_delete_track`
  1989. usersPlaylistsDeleteTrack = users_playlists_delete_track
  1990. #: Псевдоним для :attr:`rotor_account_status`
  1991. rotorAccountStatus = rotor_account_status
  1992. #: Псевдоним для :attr:`rotor_stations_dashboard`
  1993. rotorStationsDashboard = rotor_stations_dashboard
  1994. #: Псевдоним для :attr:`rotor_stations_list`
  1995. rotorStationsList = rotor_stations_list
  1996. #: Псевдоним для :attr:`rotor_station_feedback`
  1997. rotorStationFeedback = rotor_station_feedback
  1998. #: Псевдоним для :attr:`rotor_station_feedback_radio_started`
  1999. rotorStationFeedbackRadioStarted = rotor_station_feedback_radio_started
  2000. #: Псевдоним для :attr:`rotor_station_feedback_track_started`
  2001. rotorStationFeedbackTrackStarted = rotor_station_feedback_track_started
  2002. #: Псевдоним для :attr:`rotor_station_feedback_track_finished`
  2003. rotorStationFeedbackTrackFinished = rotor_station_feedback_track_finished
  2004. #: Псевдоним для :attr:`rotor_station_feedback_skip`
  2005. rotorStationFeedbackSkip = rotor_station_feedback_skip
  2006. #: Псевдоним для :attr:`rotor_station_info`
  2007. rotorStationInfo = rotor_station_info
  2008. #: Псевдоним для :attr:`rotor_station_settings2`
  2009. rotorStationSettings2 = rotor_station_settings2
  2010. #: Псевдоним для :attr:`rotor_station_tracks`
  2011. rotorStationTracks = rotor_station_tracks
  2012. #: Псевдоним для :attr:`artists_brief_info`
  2013. artistsBriefInfo = artists_brief_info
  2014. #: Псевдоним для :attr:`artists_tracks`
  2015. artistsTracks = artists_tracks
  2016. #: Псевдоним для :attr:`artists_direct_albums`
  2017. artistsDirectAlbums = artists_direct_albums
  2018. #: Псевдоним для :attr:`users_likes_tracks_add`
  2019. usersLikesTracksAdd = users_likes_tracks_add
  2020. #: Псевдоним для :attr:`users_likes_tracks_remove`
  2021. usersLikesTracksRemove = users_likes_tracks_remove
  2022. #: Псевдоним для :attr:`users_likes_artists_add`
  2023. usersLikesArtistsAdd = users_likes_artists_add
  2024. #: Псевдоним для :attr:`users_likes_artists_remove`
  2025. usersLikesArtistsRemove = users_likes_artists_remove
  2026. #: Псевдоним для :attr:`users_likes_playlists_add`
  2027. usersLikesPlaylistsAdd = users_likes_playlists_add
  2028. #: Псевдоним для :attr:`users_likes_playlists_remove`
  2029. usersLikesPlaylistsRemove = users_likes_playlists_remove
  2030. #: Псевдоним для :attr:`users_likes_albums_add`
  2031. usersLikesAlbumsAdd = users_likes_albums_add
  2032. #: Псевдоним для :attr:`users_likes_albums_remove`
  2033. usersLikesAlbumsRemove = users_likes_albums_remove
  2034. #: Псевдоним для :attr:`playlists_list`
  2035. playlistsList = playlists_list
  2036. #: Псевдоним для :attr:`playlists_collective_join`
  2037. playlistsCollectiveJoin = playlists_collective_join
  2038. #: Псевдоним для :attr:`users_playlists_list`
  2039. usersPlaylistsList = users_playlists_list
  2040. #: Псевдоним для :attr:`users_likes_tracks`
  2041. usersLikesTracks = users_likes_tracks
  2042. #: Псевдоним для :attr:`users_likes_albums`
  2043. usersLikesAlbums = users_likes_albums
  2044. #: Псевдоним для :attr:`users_likes_artists`
  2045. usersLikesArtists = users_likes_artists
  2046. #: Псевдоним для :attr:`users_likes_playlists`
  2047. usersLikesPlaylists = users_likes_playlists
  2048. #: Псевдоним для :attr:`users_dislikes_tracks`
  2049. usersDislikesTracks = users_dislikes_tracks
  2050. #: Псевдоним для :attr:`users_dislikes_tracks_add`
  2051. usersDislikesTracksAdd = users_dislikes_tracks_add
  2052. #: Псевдоним для :attr:`users_dislikes_tracks_remove`
  2053. usersDislikesTracksRemove = users_dislikes_tracks_remove
  2054. #: Псевдоним для :attr:`after_track`
  2055. afterTrack = after_track
  2056. #: Псевдоним для :attr:`queues_list`
  2057. queuesList = queues_list
  2058. #: Псевдоним для :attr:`queue_update_position`
  2059. queueUpdatePosition = queue_update_position
  2060. #: Псевдоним для :attr:`queue_create`
  2061. queueCreate = queue_create