playlist.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. from dataclasses import field
  2. from typing import TYPE_CHECKING, Any, List, Optional
  3. from yandex_music import YandexMusicModel
  4. from yandex_music.utils import model
  5. if TYPE_CHECKING:
  6. from yandex_music import (
  7. Artist,
  8. Brand,
  9. ClientType,
  10. Contest,
  11. Cover,
  12. CustomWave,
  13. JSONType,
  14. MadeFor,
  15. OpenGraphData,
  16. Pager,
  17. PlayCounter,
  18. PlaylistAbsence,
  19. PlaylistRecommendations,
  20. TrackId,
  21. TrackShort,
  22. User,
  23. )
  24. @model
  25. class Playlist(YandexMusicModel):
  26. """Класс, представляющий плейлист.
  27. Note:
  28. Под полями с заглушками понимаются поля, которые доступны у умных плейлистов тогда, когда у сервиса мало
  29. данных для генерации плейлиста.
  30. Известные значения `visibility`: `public` - публичный плейлист, `private` - приватный плейлист.
  31. Известные значения `generated_playlist_type`: `playlistOfTheDay` - Плейлист дня, `recentTracks` - Премьера,
  32. `neverHeard` - Дежавю, `podcasts` - Подкасты недели, `missedLikes` - Тайник, `origin` - Плейлист с Алисой.
  33. Известные значения `type`: `missedLikes`, `recentTracks`.
  34. Attributes:
  35. owner (:obj:`yandex_music.User`, optional): Владелец плейлиста.
  36. cover (:obj:`yandex_music.Cover`, optional): Обложка альбома.
  37. made_for (:obj:`yandex_music.MadeFor`, optional): Пользователь для которого был создан плейлист. Присутствует
  38. только у персональных плейлистов.
  39. play_counter (:obj:`yandex_music.PlayCounter`, optional): Счётчик дней. Присутствует только у плейлиста дня.
  40. playlist_absence (:obj:`yandex_music.PlaylistAbsence`, optional): Причина отсутствия плейлиста.
  41. uid (:obj:`int`, optional): Идентификатор владельца плейлиста.
  42. kind (:obj:`int`, optional): Идентификатор плейлиста.
  43. title (:obj:`str`, optional): Название плейлиста.
  44. track_count (:obj:`int`, optional): Количество треков.
  45. tags (:obj:`list`, optional): Список тегов плейлиста.
  46. revision (:obj:`int`, optional): Актуальность данных TODO.
  47. snapshot (:obj:`int`, optional): Версия плейлиста. Увеличивается на 1 при каждом изменении.
  48. visibility (:obj:`str`, optional): Видимость плейлиста.
  49. collective (:obj:`bool`, optional): Есть ли у плейлиста соавторы.
  50. url_part (:obj:`str`, optional): Часть ссылки на плейлист ('daily`).
  51. created (:obj:`str`, optional): Дата создания в формате ISO 8601.
  52. modified (:obj:`str`, optional): Дата последнего изменения в формате ISO 8601.
  53. available (:obj:`bool`, optional): Доступен TODO.
  54. is_banner (:obj:`bool`, optional): Является ли банером TODO.
  55. is_premiere (:obj:`bool`, optional): Является ли премьерой TODO.
  56. duration_ms (:obj:`int`, optional): Длительность в миллисекундах.
  57. og_image (:obj:`str`, optional): Ссылка на превью Open Graph.
  58. og_title (:obj:`str`, optional): Заголовок Open Graph.
  59. og_description (:obj:`str`, optional): Описание Open Graph.
  60. image (:obj:`str`, optional): Изображение TODO.
  61. cover_without_text (:obj:`yandex_music.Cover`, optional): Обложка без текста.
  62. contest (:obj:`yandex_music.Contest`, optional): Контест TODO.
  63. background_color (:obj:`str`, optional): Цвет заднего фона TODO.
  64. text_color (:obj:`str`, optional): Цвет текста TODO.
  65. id_for_from (:obj:`str`, optional): Откуда пришло событие (уникальный идентификатор объекта) TODO.
  66. dummy_description (:obj:`str`, optional): Описание-заглушка плейлиста.
  67. dummy_page_description (:obj:`str`, optional): Описание-заглушка страницы.
  68. dummy_cover (:obj:`str`, optional): Обложка-заглушка.
  69. dummy_rollover_cover (:obj:`str`, optional): Обложка-заглушка TODO.
  70. og_data (:obj:`yandex_music.OpenGraphData`, optional): Данные для OpenGraph.
  71. branding (:obj:`yandex_music.Brand`): Бренд.
  72. metrika_id (:obj:`int`, optional): Уникальный идентификатор счётчика на Яндекс.Метрика.
  73. coauthors (:obj:`list` из :obj:`int`, optional): Перечень ID аккаунтов соавторов плейлиста.
  74. top_artist (:obj:`list` из :obj:`yandex_music.Artist`, optional): Топ артистов TODO.
  75. recent_tracks (:obj:`list` из :obj:`yandex_music.TrackId`, optional): Список ID недавних треков.
  76. tracks (:obj:`list` из :obj:`yandex_music.TrackShort`, optional): Список треков.
  77. prerolls (:obj:`list`, optional): Прерол, проигрываемый перед плейлистом. Присутствует только у персональных
  78. плейлистов.
  79. likes_count (:obj:`int`, optional): Количество лайков.
  80. similar_playlists (:obj:`list` из :obj:`yandex_music.Playlist`, optional): Похожие плейлисты.
  81. last_owner_playlists (:obj:`list` из :obj:`yandex_music.Playlist`, optional): Последние плейлисты владельца.
  82. generated_playlist_type (:obj:`str`, optional): Тип генерируемого плейлиста.
  83. animated_cover_uri (:obj:`str`, optional): Ссылка на анимированную обложку.
  84. ever_played (:obj:`str`, optional): Играл ли этот плейлист. Присутствует только у персональных плейлистов. TODO
  85. description (:obj:`str`, optional): Описание плейлиста с разметкой Markdown.
  86. description_formatted (:obj:`str`, optional): Описание плейлиста. Только текст, без разметки.
  87. playlist_uuid (:obj:`str`, optional): TODO.
  88. type (:obj:`str`, optional): TODO.
  89. ready (:obj:`bool`, optional): Готовность TODO.
  90. is_for_from: TODO.
  91. regions: Регион TODO.
  92. custom_wave (:obj:'yandex_music.CustomWave`, optional): Описание плейлиста. TODO.
  93. pager (:obj:`yandex_music.Pager`, optional): Пагинатор.
  94. client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
  95. """
  96. owner: Optional['User']
  97. cover: Optional['Cover']
  98. made_for: Optional['MadeFor']
  99. play_counter: Optional['PlayCounter']
  100. playlist_absence: Optional['PlaylistAbsence']
  101. uid: Optional[int] = None
  102. kind: Optional[int] = None
  103. title: Optional[str] = None
  104. track_count: Optional[int] = None
  105. tags: Optional[list] = None
  106. revision: Optional[int] = None
  107. snapshot: Optional[int] = None
  108. visibility: Optional[str] = None
  109. collective: Optional[bool] = None
  110. url_part: Optional[str] = None
  111. created: Optional[str] = None
  112. modified: Optional[str] = None
  113. available: Optional[bool] = None
  114. is_banner: Optional[bool] = None
  115. is_premiere: Optional[bool] = None
  116. duration_ms: Optional[int] = None
  117. og_image: Optional[str] = None
  118. og_title: Optional[str] = None
  119. og_description: Optional[str] = None
  120. image: Optional[str] = None
  121. cover_without_text: Optional['Cover'] = None
  122. contest: Optional['Contest'] = None
  123. background_color: Optional[str] = None
  124. text_color: Optional[str] = None
  125. id_for_from: Optional[str] = None
  126. dummy_description: Optional[str] = None
  127. dummy_page_description: Optional[str] = None
  128. dummy_cover: Optional['Cover'] = None
  129. dummy_rollover_cover: Optional['Cover'] = None
  130. og_data: Optional['OpenGraphData'] = None
  131. branding: Optional['Brand'] = None
  132. metrika_id: Optional[int] = None
  133. coauthors: List[int] = field(default_factory=list)
  134. top_artist: List['Artist'] = field(default_factory=list)
  135. recent_tracks: List['TrackId'] = field(default_factory=list)
  136. tracks: List['TrackShort'] = field(default_factory=list)
  137. prerolls: Optional[list] = None
  138. likes_count: Optional[int] = None
  139. similar_playlists: List['Playlist'] = field(default_factory=list)
  140. last_owner_playlists: List['Playlist'] = field(default_factory=list)
  141. generated_playlist_type: Optional[str] = None
  142. animated_cover_uri: Optional[str] = None
  143. ever_played: Optional[bool] = None
  144. description: Optional[str] = None
  145. description_formatted: Optional[str] = None
  146. playlist_uuid: Optional[str] = None
  147. type: Optional[str] = None
  148. ready: Optional[bool] = None
  149. is_for_from: Any = None
  150. regions: Any = None
  151. custom_wave: Optional['CustomWave'] = None
  152. pager: Optional['Pager'] = None
  153. client: Optional['ClientType'] = None
  154. def __post_init__(self) -> None:
  155. self._id_attrs = (self.uid, self.kind, self.title, self.playlist_absence)
  156. @property
  157. def is_mine(self) -> bool:
  158. """Является ли плейлист моим."""
  159. if not self.owner or not self.client:
  160. return False
  161. return str(self.owner.uid) == self.client.account_uid
  162. @property
  163. def playlist_id(self) -> str:
  164. """Полный ID плейлиста."""
  165. if self.owner:
  166. return f'{self.owner.uid}:{self.kind}'
  167. return str(self.kind)
  168. def get_recommendations(self, *args: Any, **kwargs: Any) -> Optional['PlaylistRecommendations']:
  169. """Сокращение для::
  170. client.users_playlists_recommendations(playlist.kind, playlist.owner.uid, *args, **kwargs)
  171. """
  172. assert self.owner
  173. assert isinstance(self.kind, int)
  174. assert self.valid_client(self.client)
  175. return self.client.users_playlists_recommendations(self.kind, self.owner.uid, *args, **kwargs)
  176. async def get_recommendations_async(self, *args: Any, **kwargs: Any) -> Optional['PlaylistRecommendations']:
  177. """Сокращение для::
  178. await client.users_playlists_recommendations(playlist.kind, playlist.owner.uid, *args, **kwargs)
  179. """
  180. assert self.owner
  181. assert isinstance(self.kind, int)
  182. assert self.valid_async_client(self.client)
  183. return await self.client.users_playlists_recommendations(self.kind, self.owner.uid, *args, **kwargs)
  184. def get_animated_cover_url(self, size: str = '300x300') -> str:
  185. """Возвращает URL анимированной обложки.
  186. Args:
  187. size (:obj:`str`, optional): Размер анимированной обложки.
  188. Returns:
  189. :obj:`str`: URL анимированной обложки.
  190. """
  191. assert isinstance(self.animated_cover_uri, str)
  192. return f'https://{self.animated_cover_uri.replace("%%", size)}'
  193. def get_og_image_url(self, size: str = '300x300') -> str:
  194. """Возвращает URL обложки.
  195. Args:
  196. size (:obj:`str`, optional): Размер обложки.
  197. Returns:
  198. :obj:`str`: URL обложки.
  199. """
  200. assert isinstance(self.og_image, str)
  201. return f'https://{self.og_image.replace("%%", size)}'
  202. def download_animated_cover(self, filename: str, size: str = '200x200') -> None:
  203. """Загрузка анимированной обложки.
  204. Args:
  205. filename (:obj:`str`): Путь для сохранения файла с названием и расширением (GIF).
  206. size (:obj:`str`, optional): Размер анимированной обложки.
  207. """
  208. assert self.valid_client(self.client)
  209. self.client.request.download(self.get_animated_cover_url(size), filename)
  210. async def download_animated_cover_async(self, filename: str, size: str = '200x200') -> None:
  211. """Загрузка анимированной обложки.
  212. Args:
  213. filename (:obj:`str`): Путь для сохранения файла с названием и расширением (GIF).
  214. size (:obj:`str`, optional): Размер анимированной обложки.
  215. """
  216. assert self.valid_async_client(self.client)
  217. await self.client.request.download(self.get_animated_cover_url(size), filename)
  218. def download_og_image(self, filename: str, size: str = '200x200') -> None:
  219. """Загрузка обложки.
  220. Используйте это только когда нет self.cover!
  221. Args:
  222. filename (:obj:`str`): Путь для сохранения файла с названием и расширением.
  223. size (:obj:`str`, optional): Размер обложки.
  224. """
  225. assert self.valid_client(self.client)
  226. self.client.request.download(self.get_og_image_url(size), filename)
  227. async def download_og_image_async(self, filename: str, size: str = '200x200') -> None:
  228. """Загрузка обложки.
  229. Используйте это только когда нет self.cover!
  230. Args:
  231. filename (:obj:`str`): Путь для сохранения файла с названием и расширением.
  232. size (:obj:`str`, optional): Размер обложки.
  233. """
  234. assert self.valid_async_client(self.client)
  235. await self.client.request.download(self.get_og_image_url(size), filename)
  236. def download_animated_cover_bytes(self, size: str = '200x200') -> bytes:
  237. """Загрузка анимированной обложки и возврат в виде байтов.
  238. Args:
  239. size (:obj:`str`, optional): Размер анимированной обложки.
  240. Returns:
  241. :obj:`bytes`: Анимированная обложка в виде байтов.
  242. """
  243. assert self.valid_client(self.client)
  244. return self.client.request.retrieve(self.get_animated_cover_url(size))
  245. async def download_animated_cover_bytes_async(self, size: str = '200x200') -> bytes:
  246. """Загрузка анимированной обложки и возврат в виде байтов.
  247. Args:
  248. size (:obj:`str`, optional): Размер анимированной обложки.
  249. Returns:
  250. :obj:`bytes`: Анимированная обложка в виде байтов.
  251. """
  252. assert self.valid_async_client(self.client)
  253. return await self.client.request.retrieve(self.get_animated_cover_url(size))
  254. def download_og_image_bytes(self, size: str = '200x200') -> bytes:
  255. """Загрузка обложки и возврат в виде байтов.
  256. Используйте это только когда нет self.cover!
  257. Args:
  258. size (:obj:`str`, optional): Размер обложки.
  259. Returns:
  260. :obj:`bytes`: Обложка в виде байтов.
  261. """
  262. assert self.valid_client(self.client)
  263. return self.client.request.retrieve(self.get_og_image_url(size))
  264. async def download_og_image_bytes_async(self, size: str = '200x200') -> bytes:
  265. """Загрузка обложки и возврат в виде байтов.
  266. Используйте это только когда нет self.cover!
  267. Args:
  268. size (:obj:`str`, optional): Размер обложки.
  269. Returns:
  270. :obj:`bytes`: Обложка в виде байтов.
  271. """
  272. assert self.valid_async_client(self.client)
  273. return await self.client.request.retrieve(self.get_og_image_url(size))
  274. def rename(self, name: str, *args: Any, **kwargs: Any) -> None:
  275. """Сокращение для::
  276. client.users_playlists_name(playlist.kind, name, *args, **kwargs)
  277. """
  278. assert self.valid_client(self.client)
  279. assert isinstance(self.kind, int)
  280. client, kind = self.client, self.kind
  281. self.__dict__.clear()
  282. self.__dict__.update(client.users_playlists_name(kind, name, *args, **kwargs).__dict__)
  283. async def rename_async(self, name: str, *args: Any, **kwargs: Any) -> None:
  284. """Сокращение для::
  285. client.users_playlists_name(playlist.kind, name, *args, **kwargs)
  286. """
  287. assert self.valid_async_client(self.client)
  288. assert isinstance(self.kind, int)
  289. client, kind = self.client, self.kind
  290. self.__dict__.clear()
  291. self.__dict__.update((await client.users_playlists_name(kind, name, *args, **kwargs)).__dict__)
  292. def like(self, *args: Any, **kwargs: Any) -> bool:
  293. """Сокращение для::
  294. client.users_likes_playlists_add(playlist.playlist_id, user.id, *args, **kwargs)
  295. """
  296. assert self.valid_client(self.client)
  297. return self.client.users_likes_playlists_add(self.playlist_id, self.client.account_uid, *args, **kwargs)
  298. async def like_async(self, *args: Any, **kwargs: Any) -> bool:
  299. """Сокращение для::
  300. await client.users_likes_playlists_add(playlist.playlist_id, user.id, *args, **kwargs)
  301. """
  302. assert self.valid_async_client(self.client)
  303. return await self.client.users_likes_playlists_add(self.playlist_id, self.client.account_uid, *args, **kwargs)
  304. def dislike(self, *args: Any, **kwargs: Any) -> bool:
  305. """Сокращение для::
  306. client.users_likes_playlists_remove(playlist.playlist_id, user.id, *args, **kwargs)
  307. """
  308. assert self.valid_client(self.client)
  309. return self.client.users_likes_playlists_remove(self.playlist_id, self.client.account_uid, *args, **kwargs)
  310. async def dislike_async(self, *args: Any, **kwargs: Any) -> bool:
  311. """Сокращение для::
  312. await client.users_likes_playlists_remove(playlist.playlist_id, user.id, *args, **kwargs)
  313. """
  314. assert self.valid_async_client(self.client)
  315. return await self.client.users_likes_playlists_remove(
  316. self.playlist_id, self.client.account_uid, *args, **kwargs
  317. )
  318. def fetch_tracks(self, *args: Any, **kwargs: Any) -> List['TrackShort']:
  319. """Сокращение для::
  320. client.users_playlists(playlist.kind, playlist.owner.id, *args, **kwargs).tracks
  321. """
  322. assert self.owner
  323. assert isinstance(self.kind, int)
  324. assert self.valid_client(self.client)
  325. playlist = self.client.users_playlists(self.kind, self.owner.uid, *args, **kwargs)
  326. assert isinstance(playlist, Playlist)
  327. return playlist.tracks
  328. async def fetch_tracks_async(self, *args: Any, **kwargs: Any) -> List['TrackShort']:
  329. """Сокращение для::
  330. await client.users_playlists(playlist.kind, playlist.owner.id, *args, **kwargs).tracks
  331. """
  332. assert self.owner
  333. assert isinstance(self.kind, int)
  334. assert self.valid_async_client(self.client)
  335. playlist = await self.client.users_playlists(self.kind, self.owner.uid, *args, **kwargs)
  336. assert isinstance(playlist, Playlist)
  337. return playlist.tracks
  338. def insert_track(self, track_id: int, album_id: int, **kwargs: Any) -> Optional['Playlist']:
  339. """Сокращение для::
  340. client.users_playlists_insert_track(self.kind, track_id, album_id, user_id=self.owner.uid,
  341. revision=self.revision, *args, **kwargs)
  342. """
  343. assert self.owner
  344. assert isinstance(self.kind, int)
  345. assert isinstance(self.revision, int)
  346. assert self.valid_client(self.client)
  347. return self.client.users_playlists_insert_track(
  348. self.kind, track_id, album_id, user_id=self.owner.uid, revision=self.revision, **kwargs
  349. )
  350. async def insert_track_async(self, track_id: int, album_id: int, **kwargs: Any) -> Optional['Playlist']:
  351. """Сокращение для::
  352. await client.users_playlists_insert_track(self.kind, track_id, album_id, user_id=self.owner.uid,
  353. revision=self.revision, *args, **kwargs)
  354. """
  355. assert self.owner
  356. assert isinstance(self.kind, int)
  357. assert isinstance(self.revision, int)
  358. assert self.valid_async_client(self.client)
  359. return await self.client.users_playlists_insert_track(
  360. self.kind, track_id, album_id, user_id=self.owner.uid, revision=self.revision, **kwargs
  361. )
  362. def delete_tracks(self, from_: int, to: int, *args: Any, **kwargs: Any) -> Optional['Playlist']:
  363. """Сокращение для::
  364. client.users_playlists_delete_track(self.kind, from_, to, self.revision, self.owner.uid, *args, **kwargs)
  365. """
  366. assert self.owner
  367. assert isinstance(self.kind, int)
  368. assert isinstance(self.revision, int)
  369. assert self.valid_client(self.client)
  370. return self.client.users_playlists_delete_track(
  371. self.kind, from_, to, self.revision, self.owner.uid, *args, **kwargs
  372. )
  373. async def delete_tracks_async(self, from_: int, to: int, *args: Any, **kwargs: Any) -> Optional['Playlist']:
  374. """Сокращение для::
  375. await client.users_playlists_delete_track(self.kind, from_, to, self.revision, self.owner.uid, *args, **kwargs)
  376. """
  377. assert self.owner
  378. assert isinstance(self.kind, int)
  379. assert isinstance(self.revision, int)
  380. assert self.valid_async_client(self.client)
  381. return await self.client.users_playlists_delete_track(
  382. self.kind, from_, to, self.revision, self.owner.uid, *args, **kwargs
  383. )
  384. def delete(self, *args: Any, **kwargs: Any) -> bool:
  385. """Сокращение для::
  386. client.users_playlists_delete(self.kind, self.owner.uid)
  387. """
  388. assert self.owner
  389. assert isinstance(self.kind, int)
  390. assert self.valid_client(self.client)
  391. return self.client.users_playlists_delete(self.kind, self.owner.uid, *args, **kwargs)
  392. async def delete_async(self, *args: Any, **kwargs: Any) -> bool:
  393. """Сокращение для::
  394. await client.users_playlists_delete(self.kind, self.owner.uid)
  395. """
  396. assert self.owner
  397. assert isinstance(self.kind, int)
  398. assert self.valid_async_client(self.client)
  399. return await self.client.users_playlists_delete(self.kind, self.owner.uid, *args, **kwargs)
  400. @classmethod
  401. def de_json(cls, data: 'JSONType', client: 'ClientType') -> Optional['Playlist']:
  402. """Десериализация объекта.
  403. Args:
  404. data (:obj:`dict`): Поля и значения десериализуемого объекта.
  405. client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
  406. Returns:
  407. :obj:`yandex_music.Playlist`: Плейлист.
  408. """
  409. if not cls.is_dict_model_data(data):
  410. return None
  411. cls_data = cls.cleanup_data(data, client)
  412. from yandex_music import (
  413. Artist,
  414. Brand,
  415. Contest,
  416. Cover,
  417. CustomWave,
  418. MadeFor,
  419. OpenGraphData,
  420. Pager,
  421. PlayCounter,
  422. PlaylistAbsence,
  423. TrackId,
  424. TrackShort,
  425. User,
  426. )
  427. cls_data['owner'] = User.de_json(data.get('owner'), client)
  428. cls_data['cover'] = Cover.de_json(data.get('cover'), client)
  429. cls_data['cover_without_text'] = Cover.de_json(data.get('cover_without_text'), client)
  430. cls_data['made_for'] = MadeFor.de_json(data.get('made_for'), client)
  431. cls_data['tracks'] = TrackShort.de_list(data.get('tracks'), client)
  432. cls_data['recent_tracks'] = TrackId.de_list(data.get('recent_tracks'), client)
  433. cls_data['play_counter'] = PlayCounter.de_json(data.get('play_counter'), client)
  434. cls_data['top_artist'] = Artist.de_list(data.get('top_artist'), client)
  435. cls_data['contest'] = Contest.de_json(data.get('contest'), client)
  436. cls_data['og_data'] = OpenGraphData.de_json(data.get('og_data'), client)
  437. cls_data['dummy_cover'] = Cover.de_json(data.get('dummy_cover'), client)
  438. cls_data['dummy_rollover_cover'] = Cover.de_json(data.get('dummy_rollover_cover'), client)
  439. cls_data['branding'] = Brand.de_json(data.get('branding'), client)
  440. cls_data['similar_playlists'] = Playlist.de_list(data.get('similar_playlists'), client)
  441. cls_data['last_owner_playlists'] = Playlist.de_list(data.get('last_owner_playlists'), client)
  442. cls_data['playlist_absence'] = PlaylistAbsence.de_json(data.get('playlist_absence'), client) # на случай фикса
  443. if data.get('playlist_absense'): # очепятка яндуха
  444. cls_data['playlist_absence'] = PlaylistAbsence.de_json(data.get('playlist_absense'), client)
  445. cls_data.pop('playlist_absense')
  446. cls_data['custom_wave'] = CustomWave.de_json(data.get('custom_wave'), client)
  447. cls_data['pager'] = Pager.de_json(data.get('pager'), client)
  448. return cls(client=client, **cls_data) # type: ignore
  449. # camelCase псевдонимы
  450. #: Псевдоним для :attr:`is_mine`
  451. isMine = is_mine
  452. #: Псевдоним для :attr:`playlist_id`
  453. playlistId = playlist_id
  454. #: Псевдоним для :attr:`get_recommendations`
  455. getRecommendations = get_recommendations
  456. #: Псевдоним для :attr:`get_recommendations_async`
  457. getRecommendationsAsync = get_recommendations_async
  458. #: Псевдоним для :attr:`get_animated_cover_url`
  459. getAnimatedCoverUrl = get_animated_cover_url
  460. #: Псевдоним для :attr:`get_og_image_url`
  461. getOgImageUrl = get_og_image_url
  462. #: Псевдоним для :attr:`download_animated_cover`
  463. downloadAnimatedCover = download_animated_cover
  464. #: Псевдоним для :attr:`download_animated_cover_async`
  465. downloadAnimatedCoverAsync = download_animated_cover_async
  466. #: Псевдоним для :attr:`download_og_image`
  467. downloadOgImage = download_og_image
  468. #: Псевдоним для :attr:`download_og_image_async`
  469. downloadOgImageAsync = download_og_image_async
  470. #: Псевдоним для :attr:`download_animated_cover_bytes`
  471. downloadAnimatedCoverBytes = download_animated_cover_bytes
  472. #: Псевдоним для :attr:`download_animated_cover_bytes_async`
  473. downloadAnimatedCoverBytesAsync = download_animated_cover_bytes_async
  474. #: Псевдоним для :attr:`download_og_image_bytes`
  475. downloadOgImageBytes = download_og_image_bytes
  476. #: Псевдоним для :attr:`download_og_image_bytes_async`
  477. downloadOgImageBytesAsync = download_og_image_bytes_async
  478. #: Псевдоним для :attr:`rename_async`
  479. renameAsync = rename_async
  480. #: Псевдоним для :attr:`like_async`
  481. likeAsync = like_async
  482. #: Псевдоним для :attr:`dislike_async`
  483. dislikeAsync = dislike_async
  484. #: Псевдоним для :attr:`fetch_tracks`
  485. fetchTracks = fetch_tracks
  486. #: Псевдоним для :attr:`fetch_tracks_async`
  487. fetchTracksAsync = fetch_tracks_async
  488. #: Псевдоним для :attr:`insert_track`
  489. insertTrack = insert_track
  490. #: Псевдоним для :attr:`insert_track_async`
  491. insertTrackAsync = insert_track_async
  492. #: Псевдоним для :attr:`delete_tracks`
  493. deleteTracks = delete_tracks
  494. #: Псевдоним для :attr:`delete_tracks_async`
  495. deleteTracksAsync = delete_tracks_async
  496. #: Псевдоним для :attr:`delete_async`
  497. deleteAsync = delete_async