Добавлен новый класс: LandingList.
Добавлены новые методы: new_releases, new_playlists, podcasts.
このコミットが含まれているのは:
コミット
f96732d674
|
@ -0,0 +1,7 @@
|
|||
yandex_music.LandingList
|
||||
========================
|
||||
|
||||
.. autoclass:: yandex_music.LandingList
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
|
@ -18,3 +18,4 @@
|
|||
yandex_music.landing.chart_info
|
||||
yandex_music.landing.chart_info_menu
|
||||
yandex_music.landing.chart_info_menu_item
|
||||
yandex_music.landing.landing_list
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import pytest
|
||||
|
||||
from yandex_music import LandingList
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
def landing_list(playlist_id):
|
||||
return LandingList(TestLandingList.type, TestLandingList.type_for_from, TestLandingList.title, TestLandingList.id,
|
||||
TestLandingList.new_releases, [playlist_id], TestLandingList.podcasts)
|
||||
|
||||
|
||||
class TestLandingList:
|
||||
id = 'fNdCYuAs'
|
||||
title = 'Новые треки, альбомы и сборники'
|
||||
type = 'new-releases'
|
||||
type_for_from = 'new-releases'
|
||||
new_releases = [10704986, 10527291, 9479589]
|
||||
podcasts = [10532030, 8693523, 10509632]
|
||||
|
||||
def test_expected_values(self, landing_list, playlist_id):
|
||||
assert landing_list.id == self.id
|
||||
assert landing_list.title == self.title
|
||||
assert landing_list.type == self.type
|
||||
assert landing_list.type_for_from == self.type_for_from
|
||||
assert landing_list.new_releases == self.new_releases
|
||||
assert landing_list.podcasts == self.podcasts
|
||||
assert landing_list.new_playlists == [playlist_id]
|
||||
|
||||
def test_de_json_none(self, client):
|
||||
assert LandingList.de_json({}, client) is None
|
||||
|
||||
def test_de_json_required(self, client):
|
||||
json_dict = {'title': self.title, 'type_': self.type, 'type_for_from': self.type_for_from}
|
||||
landing_list = LandingList.de_json(json_dict, client)
|
||||
|
||||
assert landing_list.title == self.title
|
||||
assert landing_list.type == self.type
|
||||
assert landing_list.type_for_from == self.type_for_from
|
||||
|
||||
def test_de_json_all(self, client, playlist_id):
|
||||
json_dict = {'title': self.title, 'type_': self.type, 'type_for_from': self.type_for_from, 'id_': self.id,
|
||||
'new_releases': self.new_releases, 'podcasts': self.podcasts,
|
||||
'new_playlists': [playlist_id.to_dict()]}
|
||||
landing_list = LandingList.de_json(json_dict, client)
|
||||
|
||||
assert landing_list.id == self.id
|
||||
assert landing_list.title == self.title
|
||||
assert landing_list.type == self.type
|
||||
assert landing_list.type_for_from == self.type_for_from
|
||||
assert landing_list.new_releases == self.new_releases
|
||||
assert landing_list.podcasts == self.podcasts
|
||||
assert landing_list.new_playlists == [playlist_id]
|
||||
|
||||
def test_equality(self, playlist_id):
|
||||
a = LandingList(self.type, self.type_for_from, self.title, self.id, self.new_releases, [playlist_id], [])
|
||||
b = LandingList(self.type, self.type_for_from, self.title, self.id, self.new_releases, [], [])
|
||||
c = LandingList(self.type, self.type_for_from, self.title, '', self.new_releases, [playlist_id], [])
|
||||
d = LandingList(self.type, self.type_for_from, self.title, self.id, self.new_releases, [playlist_id], [])
|
||||
|
||||
assert a != b != c
|
||||
assert hash(a) != hash(b) != hash(c)
|
||||
assert a is not b is not c
|
||||
|
||||
assert a == d
|
|
@ -76,6 +76,7 @@ from .landing.promotion import Promotion
|
|||
from .landing.block_entity import BlockEntity
|
||||
from .landing.landing import Landing
|
||||
from .landing.block import Block
|
||||
from .landing.landing_list import LandingList
|
||||
from .landing.chart_info_menu_item import ChartInfoMenuItem
|
||||
from .landing.chart_info_menu import ChartInfoMenu
|
||||
from .landing.chart_info import ChartInfo
|
||||
|
@ -126,4 +127,4 @@ __all__ = ['YandexMusicObject', 'Client', 'Account', 'PassportPhone', 'Invocatio
|
|||
'Sequence', 'StationTracksResult', 'BriefInfo', 'Description', 'PlaylistId', 'Vinyl', 'Supplement', 'Lyrics',
|
||||
'VideoSupplement', 'ArtistTracks', 'Pager', 'ArtistAlbums', 'PlaylistAbsence', 'Shot', 'ShotEvent',
|
||||
'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings', 'RenewableRemainder', 'ChartInfo', 'ChartInfoMenu',
|
||||
'ChartInfoMenuItem', 'Tag', 'TagResult', 'PlaylistRecommendations']
|
||||
'ChartInfoMenuItem', 'Tag', 'TagResult', 'PlaylistRecommendations', 'LandingList']
|
||||
|
|
|
@ -6,7 +6,7 @@ from typing import Callable, Dict, List, Optional, Union
|
|||
from yandex_music import Album, Artist, ArtistAlbums, ArtistTracks, BriefInfo, Dashboard, DownloadInfo, Experiments, \
|
||||
Feed, Genre, Landing, Like, PermissionAlerts, Playlist, PromoCodeStatus, Search, Settings, ShotEvent, Supplement, \
|
||||
StationResult, StationTracksResult, Status, Suggestions, SimilarTracks, Track, TracksList, UserSettings, \
|
||||
YandexMusicObject, ChartInfo, TagResult, PlaylistRecommendations
|
||||
YandexMusicObject, ChartInfo, TagResult, PlaylistRecommendations, LandingList
|
||||
from yandex_music.exceptions import Captcha, InvalidToken
|
||||
from yandex_music.utils.difference import Difference
|
||||
from yandex_music.utils.request import Request
|
||||
|
@ -473,6 +473,72 @@ class Client(YandexMusicObject):
|
|||
|
||||
return ChartInfo.de_json(result, self)
|
||||
|
||||
@log
|
||||
def new_releases(self, timeout: Union[int, float] = None, *args, **kwargs) -> Optional[LandingList]:
|
||||
"""Получение полного списка всех новых релизов (альбомов).
|
||||
|
||||
Args:
|
||||
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
||||
ответа от сервера вместо указанного при создании пула.
|
||||
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
||||
|
||||
Returns:
|
||||
:obj:`yandex_music.LandingList`: Список новых альбомов.
|
||||
|
||||
Raises:
|
||||
:class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
|
||||
"""
|
||||
|
||||
url = f'{self.base_url}/landing3/new-releases'
|
||||
|
||||
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
||||
|
||||
return LandingList.de_json(result, self)
|
||||
|
||||
@log
|
||||
def new_playlists(self, timeout: Union[int, float] = None, *args, **kwargs) -> Optional[LandingList]:
|
||||
"""Получение полного списка всех новых плейлистов.
|
||||
|
||||
Args:
|
||||
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
||||
ответа от сервера вместо указанного при создании пула.
|
||||
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
||||
|
||||
Returns:
|
||||
:obj:`yandex_music.LandingList`: Список новых плейлистов.
|
||||
|
||||
Raises:
|
||||
:class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
|
||||
"""
|
||||
|
||||
url = f'{self.base_url}/landing3/new-playlists'
|
||||
|
||||
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
||||
|
||||
return LandingList.de_json(result, self)
|
||||
|
||||
@log
|
||||
def podcasts(self, timeout: Union[int, float] = None, *args, **kwargs) -> Optional[LandingList]:
|
||||
"""Получение подкастов с лендинга.
|
||||
|
||||
Args:
|
||||
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
||||
ответа от сервера вместо указанного при создании пула.
|
||||
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
||||
|
||||
Returns:
|
||||
:obj:`yandex_music.LandingList`: Список подскастов.
|
||||
|
||||
Raises:
|
||||
:class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
|
||||
"""
|
||||
|
||||
url = f'{self.base_url}/landing3/podcasts'
|
||||
|
||||
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
||||
|
||||
return LandingList.de_json(result, self)
|
||||
|
||||
@log
|
||||
def genres(self, timeout: Union[int, float] = None, *args, **kwargs) -> List[Genre]:
|
||||
"""Получение жанров музыки.
|
||||
|
@ -2212,6 +2278,10 @@ class Client(YandexMusicObject):
|
|||
consumePromoCode = consume_promo_code
|
||||
#: Псевдоним для :attr:`feed_wizard_is_passed`
|
||||
feedWizardIsPassed = feed_wizard_is_passed
|
||||
#: Псевдоним для :attr:`new_releases`
|
||||
newReleases = new_releases
|
||||
#: Псевдоним для :attr:`new_playlists`
|
||||
newPlaylists = new_playlists
|
||||
#: Псевдоним для :attr:`tracks_download_info`
|
||||
tracksDownloadInfo = tracks_download_info
|
||||
#: Псевдоним для :attr:`track_supplement`
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
from typing import TYPE_CHECKING, Optional, List
|
||||
|
||||
from yandex_music import YandexMusicObject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from yandex_music import Client
|
||||
|
||||
|
||||
class LandingList(YandexMusicObject):
|
||||
"""Класс, представляющий список объектов лендинга.
|
||||
|
||||
Note:
|
||||
Известные значения поля `type`: `new-playlists`, `new-releases`, `podcasts`.
|
||||
|
||||
В зависимости от типа будет заполнено то, или иное поле.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Тип результата.
|
||||
type_for_from (:obj:`str`): Откуда пришло событие.
|
||||
title (:obj:`str`): Заголовок страницы.
|
||||
id (:obj:`str`): Уникальный идентификатор списка.
|
||||
new_releases (:obj:`list` из :obj:`int`): Новые альбомы.
|
||||
new_playlists (:obj:`list` из :obj:`int`): Новые плейлисты.
|
||||
podcasts (:obj:`list` из :obj:`int`): Подкасты.
|
||||
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Тип результата.
|
||||
type_for_from (:obj:`str`): Откуда пришло событие.
|
||||
title (:obj:`str`): Заголовок страницы.
|
||||
id (:obj:`str`, optional): Уникальный идентификатор списка.
|
||||
new_releases (:obj:`list` из :obj:`int`, optional): Новые альбомы.
|
||||
new_playlists (:obj:`list` из :obj:`int`, optional): Новые плейлисты.
|
||||
podcasts (:obj:`list` из :obj:`int`, optional): Подкасты.
|
||||
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
|
||||
**kwargs: Произвольные ключевые аргументы полученные от API.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
type_: str,
|
||||
type_for_from: str,
|
||||
title: str,
|
||||
id_: Optional[str] = None,
|
||||
new_releases: List[int] = None,
|
||||
new_playlists: List[int] = None,
|
||||
podcasts: List[int] = None,
|
||||
client: Optional['Client'] = None,
|
||||
**kwargs) -> None:
|
||||
self.type = type_
|
||||
self.type_for_from = type_for_from
|
||||
self.title = title
|
||||
|
||||
self.id = id_
|
||||
self.new_releases = new_releases
|
||||
self.new_playlists = new_playlists
|
||||
self.podcasts = podcasts
|
||||
|
||||
self.client = client
|
||||
self._id_attrs = (self.id, self.new_releases, self.new_playlists, self.podcasts)
|
||||
|
||||
super().handle_unknown_kwargs(self, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: dict, client: 'Client') -> Optional['Chart']:
|
||||
"""Десериализация объекта.
|
||||
|
||||
Args:
|
||||
data (:obj:`dict`): Поля и значения десериализуемого объекта.
|
||||
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
|
||||
|
||||
Returns:
|
||||
:obj:`yandex_music.LandingList`: Список объектов лендинга.
|
||||
"""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(LandingList, cls).de_json(data, client)
|
||||
from yandex_music import PlaylistId
|
||||
data['new_playlists'] = PlaylistId.de_list(data.get('new_playlists'), client)
|
||||
|
||||
return cls(client=client, **data)
|
読み込み中…
新しいイシューから参照