Добавлен новый класс: LandingList.

Добавлены новые методы: new_releases, new_playlists, podcasts.
このコミットが含まれているのは:
Il`ya Semyonov 2020-05-16 01:00:52 +03:00
コミット f96732d674
6個のファイルの変更226行の追加2行の削除

ファイルの表示

@ -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

64
tests/test_landing_list.py ノーマルファイル
ファイルの表示

@ -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`

81
yandex_music/landing/landing_list.py ノーマルファイル
ファイルの表示

@ -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)