Добавлены новые классы: Brand, Contest, OpenGraphData.

Поля contest, dummy_description, dummy_page_description, dummy_cover, dummy_rollover_cover, og_data, branding классу Playlist.
Добавлена информацию по поводу запуска потока по треку, плейлисту и т.д.
Документация и тесты к новым полям, классам #339
このコミットが含まれているのは:
Il`ya Semyonov 2020-06-14 22:11:38 +03:00
コミット a6c0c709fd
16個のファイルの変更487行の追加16行の削除

7
docs/source/yandex_music.playlist.brand.rst ノーマルファイル
ファイルの表示

@ -0,0 +1,7 @@
yandex_music.Brand
==================
.. autoclass:: yandex_music.Brand
:members:
:undoc-members:
:show-inheritance:

ファイルの表示

@ -0,0 +1,7 @@
yandex_music.Contest
====================
.. autoclass:: yandex_music.Contest
:members:
:undoc-members:
:show-inheritance:

ファイルの表示

@ -0,0 +1,7 @@
yandex_music.OpenGraphData
==========================
.. autoclass:: yandex_music.OpenGraphData
:members:
:undoc-members:
:show-inheritance:

ファイルの表示

@ -13,3 +13,6 @@
yandex_music.playlist.playlist_recommendations yandex_music.playlist.playlist_recommendations
yandex_music.playlist.tag_result yandex_music.playlist.tag_result
yandex_music.playlist.tag yandex_music.playlist.tag
yandex_music.playlist.contest
yandex_music.playlist.open_graph_data
yandex_music.playlist.brand

ファイルの表示

@ -87,3 +87,6 @@ from .test_non_auto_renewable import TestNonAutoRenewable
from .test_poetry_lover_match import TestPoetryLoverMatch from .test_poetry_lover_match import TestPoetryLoverMatch
from .test_deactivation import TestDeactivation from .test_deactivation import TestDeactivation
from .test_operator import TestOperator from .test_operator import TestOperator
from .test_contest import TestContest
from .test_open_graph_data import TestOpenGraphData
from .test_brand import TestBrand

ファイルの表示

@ -8,7 +8,8 @@ from yandex_music import Account, AdParams, Album, AlbumEvent, Artist, ArtistEve
PlaylistId, Plus, Price, Product, Promotion, Ratings, RenewableRemainder, Restrictions, RotorSettings, \ PlaylistId, Plus, Price, Product, Promotion, Ratings, RenewableRemainder, Restrictions, RotorSettings, \
SearchResult, Sequence, Settings, Shot, ShotData, ShotType, Station, StationResult, Status, Subscription, Tag, \ SearchResult, Sequence, Settings, Shot, ShotData, ShotType, Station, StationResult, Status, Subscription, Tag, \
Title, Track, TrackId, TrackPosition, TrackShort, TrackShortOld, TrackWithAds, User, Value, Video, \ Title, Track, TrackId, TrackPosition, TrackShort, TrackShortOld, TrackWithAds, User, Value, Video, \
VideoSupplement, Vinyl, StationData, AlertButton, Alert, NonAutoRenewable, PoetryLoverMatch, Deactivation, Operator VideoSupplement, Vinyl, StationData, AlertButton, Alert, NonAutoRenewable, PoetryLoverMatch, Deactivation, \
Operator, Contest, OpenGraphData, Brand
from . import TestAccount, TestAdParams, TestAlbum, TestArtist, TestAutoRenewable, TestBest, TestBlock, \ from . import TestAccount, TestAdParams, TestAlbum, TestArtist, TestAutoRenewable, TestBest, TestBlock, \
TestBlockEntity, TestCaseForms, TestChart, TestChartInfo, TestChartInfoMenuItem, TestCounts, TestCover, TestDay, \ TestBlockEntity, TestCaseForms, TestChart, TestChartInfo, TestChartInfoMenuItem, TestCounts, TestCover, TestDay, \
TestDescription, TestDiscreteScale, TestEnum, TestEvent, TestGeneratedPlaylist, TestIcon, TestId, TestImages, \ TestDescription, TestDiscreteScale, TestEnum, TestEvent, TestGeneratedPlaylist, TestIcon, TestId, TestImages, \
@ -20,7 +21,7 @@ from . import TestAccount, TestAdParams, TestAlbum, TestArtist, TestAutoRenewabl
TestTag, TestTitle, TestTrack, TestTrackId, TestTrackPosition, TestTrackShort, TestTrackShortOld, \ TestTag, TestTitle, TestTrack, TestTrackId, TestTrackPosition, TestTrackShort, TestTrackShortOld, \
TestTrackWithAds, TestUser, TestValue, TestVideo, TestVideoSupplement, TestVinyl, TestArtistEvent, \ TestTrackWithAds, TestUser, TestValue, TestVideo, TestVideoSupplement, TestVinyl, TestArtistEvent, \
TestStationData, TestAlertButton, TestAlert, TestNonAutoRenewable, TestPoetryLoverMatch, TestDeactivation, \ TestStationData, TestAlertButton, TestAlert, TestNonAutoRenewable, TestPoetryLoverMatch, TestDeactivation, \
TestOperator TestOperator, TestContest, TestOpenGraphData, TestBrand
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
@ -133,7 +134,8 @@ def album_without_nested_albums(album_factory, artist_without_tracks, track_with
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def playlist_factory(user, cover, made_for, track_short, play_counter, playlist_absence, artist, track_id): def playlist_factory(user, cover, made_for, track_short, play_counter, playlist_absence,
artist, track_id, contest, open_graph_data, brand):
class PlaylistFactory: class PlaylistFactory:
def get(self, similar_playlists, last_owner_playlists): def get(self, similar_playlists, last_owner_playlists):
return Playlist(user, cover, made_for, play_counter, playlist_absence, TestPlaylist.uid, TestPlaylist.kind, return Playlist(user, cover, made_for, play_counter, playlist_absence, TestPlaylist.uid, TestPlaylist.kind,
@ -142,13 +144,14 @@ def playlist_factory(user, cover, made_for, track_short, play_counter, playlist_
TestPlaylist.url_part, TestPlaylist.created, TestPlaylist.modified, TestPlaylist.url_part, TestPlaylist.created, TestPlaylist.modified,
TestPlaylist.available, TestPlaylist.is_banner, TestPlaylist.is_premiere, TestPlaylist.available, TestPlaylist.is_banner, TestPlaylist.is_premiere,
TestPlaylist.duration_ms, TestPlaylist.og_image, TestPlaylist.og_title, TestPlaylist.duration_ms, TestPlaylist.og_image, TestPlaylist.og_title,
TestPlaylist.og_description, TestPlaylist.image, cover, TestPlaylist.background_color, TestPlaylist.og_description, TestPlaylist.image, cover, contest,
TestPlaylist.text_color, TestPlaylist.id_for_from, TestPlaylist.metrika_id, TestPlaylist.background_color, TestPlaylist.text_color, TestPlaylist.id_for_from,
TestPlaylist.coauthors, [artist], [track_id], [track_short], TestPlaylist.prerolls, TestPlaylist.dummy_description, TestPlaylist.dummy_page_description, cover, cover,
TestPlaylist.likes_count, similar_playlists, last_owner_playlists, open_graph_data, brand, TestPlaylist.metrika_id, TestPlaylist.coauthors, [artist],
TestPlaylist.generated_playlist_type, TestPlaylist.animated_cover_uri, [track_id], [track_short], TestPlaylist.prerolls, TestPlaylist.likes_count,
TestPlaylist.ever_played, TestPlaylist.description, TestPlaylist.description_formatted, similar_playlists, last_owner_playlists, TestPlaylist.generated_playlist_type,
TestPlaylist.is_for_from, TestPlaylist.regions) TestPlaylist.animated_cover_uri, TestPlaylist.ever_played, TestPlaylist.description,
TestPlaylist.description_formatted, TestPlaylist.is_for_from, TestPlaylist.regions)
return PlaylistFactory() return PlaylistFactory()
@ -179,6 +182,12 @@ def tag():
return Tag(TestTag.id_, TestTag.value, TestTag.name, TestTag.og_description, TestTag.og_image) return Tag(TestTag.id_, TestTag.value, TestTag.name, TestTag.og_description, TestTag.og_image)
@pytest.fixture(scope='session')
def brand():
return Brand(TestBrand.image, TestBrand.background, TestBrand.reference, TestBrand.pixels,
TestBrand.theme, TestBrand.playlist_theme, TestBrand.button)
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def track_with_ads(track): def track_with_ads(track):
return TrackWithAds(TestTrackWithAds.type, track) return TrackWithAds(TestTrackWithAds.type, track)
@ -240,6 +249,11 @@ def cover():
TestCover.prefix, TestCover.error) TestCover.prefix, TestCover.error)
@pytest.fixture(scope='session')
def open_graph_data(cover):
return OpenGraphData(TestOpenGraphData.title, TestOpenGraphData.description, cover)
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def meta_data(): def meta_data():
return MetaData(TestMetaData.album, TestMetaData.volume, TestMetaData.year, TestMetaData.number, TestMetaData.genre) return MetaData(TestMetaData.album, TestMetaData.volume, TestMetaData.year, TestMetaData.number, TestMetaData.genre)
@ -475,6 +489,12 @@ def playlist_id():
return PlaylistId(TestPlaylistId.uid, TestPlaylistId.kind) return PlaylistId(TestPlaylistId.uid, TestPlaylistId.kind)
@pytest.fixture(scope='session')
def contest():
return Contest(TestContest.contest_id, TestContest.status, TestContest.can_edit,
TestContest.sent, TestContest.withdrawn)
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def label(): def label():
return Label(TestLabel.id, TestLabel.name) return Label(TestLabel.id, TestLabel.name)

67
tests/test_brand.py ノーマルファイル
ファイルの表示

@ -0,0 +1,67 @@
from yandex_music import Brand
class TestBrand:
image = 'https://avatars.mds.yandex.net/get-music-misc/2419084/img.5dbb0478e482b01822a89af8/%%'
background = '#2A2A2A'
reference = 'yandexmusic://post/5c94a7bf433f8221feac3fa6'
pixels = [
'http://ads6.adfox.ru/256152/event?hash=84862c423eb&rand=eo=hdxqd&pr=deyq&p1=bwzel',
'http://banners.adfox.ru/transparent.gif'
]
theme = 'dark'
playlist_theme = ''
button = 'Больше подкастов'
def test_expected_values(self, brand):
assert brand.image == self.image
assert brand.background == self.background
assert brand.reference == self.reference
assert brand.pixels == self.pixels
assert brand.theme == self.theme
assert brand.playlist_theme == self.playlist_theme
assert brand.button == self.button
def test_de_json_none(self, client):
assert Brand.de_json({}, client) is None
def test_de_json_required(self, client):
json_dict = {'image': self.image, 'background': self.background, 'reference': self.reference,
'pixels': self.pixels, 'theme': self.theme, 'playlist_theme': self.playlist_theme,
'button': self.button}
brand = Brand.de_json(json_dict, client)
assert brand.image == self.image
assert brand.background == self.background
assert brand.reference == self.reference
assert brand.pixels == self.pixels
assert brand.theme == self.theme
assert brand.playlist_theme == self.playlist_theme
assert brand.button == self.button
def test_de_json_all(self, client):
json_dict = {'image': self.image, 'background': self.background, 'reference': self.reference,
'pixels': self.pixels, 'theme': self.theme, 'playlist_theme': self.playlist_theme,
'button': self.button}
brand = Brand.de_json(json_dict, client)
assert brand.image == self.image
assert brand.background == self.background
assert brand.reference == self.reference
assert brand.pixels == self.pixels
assert brand.theme == self.theme
assert brand.playlist_theme == self.playlist_theme
assert brand.button == self.button
def test_equality(self):
a = Brand(self.image, self.background, self.reference, self.pixels,
self.theme, self.playlist_theme, self.button)
b = Brand('', self.background, self.reference, ['link'], self.theme, self.playlist_theme, self.button)
c = Brand(self.image, self.background, self.reference, self.pixels,
self.theme, self.playlist_theme, self.button)
assert a != b
assert hash(a) != hash(b)
assert a is not b
assert a == c

49
tests/test_contest.py ノーマルファイル
ファイルの表示

@ -0,0 +1,49 @@
from yandex_music import Contest
class TestContest:
contest_id = 'disco_contest'
status = 'withdrew-moderator'
can_edit = True
sent = '2019-10-22T09:41:54+00:00'
withdrawn = '2019-10-23T07:02:03+00:00'
def test_expected_values(self, contest):
assert contest.contest_id == self.contest_id
assert contest.status == self.status
assert contest.can_edit == self.can_edit
assert contest.sent == self.sent
assert contest.withdrawn == self.withdrawn
def test_de_json_none(self, client):
assert Contest.de_json({}, client) is None
def test_de_json_required(self, client):
json_dict = {'contest_id': self.contest_id, 'status': self.status, 'can_edit': self.can_edit}
contest = Contest.de_json(json_dict, client)
assert contest.contest_id == self.contest_id
assert contest.status == self.status
assert contest.can_edit == self.can_edit
def test_de_json_all(self, client):
json_dict = {'contest_id': self.contest_id, 'status': self.status, 'can_edit': self.can_edit,
'sent': self.sent, 'withdrawn': self.withdrawn}
contest = Contest.de_json(json_dict, client)
assert contest.contest_id == self.contest_id
assert contest.status == self.status
assert contest.can_edit == self.can_edit
assert contest.sent == self.sent
assert contest.withdrawn == self.withdrawn
def test_equality(self):
a = Contest(self.contest_id, self.status, self.can_edit)
b = Contest('', self.status, self.can_edit)
c = Contest(self.contest_id, self.status, self.can_edit)
assert a != b
assert hash(a) != hash(b)
assert a is not b
assert a == c

41
tests/test_open_graph_data.py ノーマルファイル
ファイルの表示

@ -0,0 +1,41 @@
from yandex_music import OpenGraphData
class TestOpenGraphData:
title = 'Подкасты недели'
description = 'Чтобы собрать для вас этот плейлист, мы должны узнать вас ' \
'чуточку поближе. Заходите на Музыку и слушайте больше!'
def test_expected_values(self, open_graph_data, cover):
assert open_graph_data.title == self.title
assert open_graph_data.description == self.description
def test_de_json_none(self, client):
assert OpenGraphData.de_json({}, client) is None
def test_de_json_required(self, client, cover):
json_dict = {'title': self.title, 'description': self.description, 'image': cover.to_dict()}
open_graph_data = OpenGraphData.de_json(json_dict, client)
assert open_graph_data.title == self.title
assert open_graph_data.description == self.description
assert open_graph_data.image == cover
def test_de_json_all(self, client, cover):
json_dict = {'title': self.title, 'description': self.description, 'image': cover.to_dict()}
open_graph_data = OpenGraphData.de_json(json_dict, client)
assert open_graph_data.title == self.title
assert open_graph_data.description == self.description
assert open_graph_data.image == cover
def test_equality(self, cover):
a = OpenGraphData(self.title, self.description, cover)
b = OpenGraphData('', self.description, cover)
c = OpenGraphData(self.title, self.description, cover)
assert a != b
assert hash(a) != hash(b)
assert a is not b
assert a == c

ファイルの表示

@ -25,6 +25,9 @@ class TestPlaylist:
background_color = '' background_color = ''
text_color = '' text_color = ''
id_for_from = 'playlist_of_the_day' id_for_from = 'playlist_of_the_day'
dummy_description = 'Слушайте интересные подкасты, чтобы мы могли узнать вас получше и\\xa0собрать этот плейлист'
dummy_page_description = 'Чтобы собрать для вас этот плейлист, мы должны узнать ' \
'вас чуточку поближе. Слушайте больше!'
metrika_id = 666666 metrika_id = 666666
coauthors = [1130000003905541] coauthors = [1130000003905541]
prerolls = [] prerolls = []
@ -38,7 +41,7 @@ class TestPlaylist:
regions = None regions = None
def test_expected_values(self, playlist, user, cover, made_for, track_short, play_counter, playlist_absence, def test_expected_values(self, playlist, user, cover, made_for, track_short, play_counter, playlist_absence,
playlist_without_nested_playlists, artist, track_id): playlist_without_nested_playlists, artist, track_id, contest, open_graph_data, brand):
assert playlist.owner == user assert playlist.owner == user
assert playlist.uid == self.uid assert playlist.uid == self.uid
assert playlist.kind == self.kind assert playlist.kind == self.kind
@ -65,9 +68,16 @@ class TestPlaylist:
assert playlist.og_description == self.og_description assert playlist.og_description == self.og_description
assert playlist.image == self.image assert playlist.image == self.image
assert playlist.cover_without_text == cover assert playlist.cover_without_text == cover
assert playlist.contest == contest
assert playlist.background_color == self.background_color assert playlist.background_color == self.background_color
assert playlist.text_color == self.text_color assert playlist.text_color == self.text_color
assert playlist.id_for_from == self.id_for_from assert playlist.id_for_from == self.id_for_from
assert playlist.dummy_description == self.dummy_description
assert playlist.dummy_page_description == self.dummy_page_description
assert playlist.dummy_cover == cover
assert playlist.dummy_rollover_cover == cover
assert playlist.og_data == open_graph_data
assert playlist.branding == brand
assert playlist.metrika_id == self.metrika_id assert playlist.metrika_id == self.metrika_id
assert playlist.coauthors == self.coauthors assert playlist.coauthors == self.coauthors
assert playlist.top_artist == [artist] assert playlist.top_artist == [artist]
@ -103,7 +113,7 @@ class TestPlaylist:
assert playlist.playlist_absence == playlist_absence assert playlist.playlist_absence == playlist_absence
def test_de_json_all(self, client, user, cover, made_for, track_short, play_counter, playlist_absence, def test_de_json_all(self, client, user, cover, made_for, track_short, play_counter, playlist_absence,
playlist_without_nested_playlists, artist, track_id): playlist_without_nested_playlists, artist, track_id, contest, open_graph_data, brand):
json_dict = {'owner': user.to_dict(), 'uid': self.uid, 'kind': self.kind, 'title': self.title, json_dict = {'owner': user.to_dict(), 'uid': self.uid, 'kind': self.kind, 'title': self.title,
'track_count': self.track_count, 'cover': cover.to_dict(), 'made_for': made_for.to_dict(), 'track_count': self.track_count, 'cover': cover.to_dict(), 'made_for': made_for.to_dict(),
'play_counter': play_counter.to_dict(), 'playlist_absence': playlist_absence.to_dict(), 'play_counter': play_counter.to_dict(), 'playlist_absence': playlist_absence.to_dict(),
@ -121,7 +131,11 @@ class TestPlaylist:
'similar_playlists': [playlist_without_nested_playlists.to_dict()], 'similar_playlists': [playlist_without_nested_playlists.to_dict()],
'last_owner_playlists': [playlist_without_nested_playlists.to_dict()], 'last_owner_playlists': [playlist_without_nested_playlists.to_dict()],
'og_description': self.og_description, 'top_artist': [artist.to_dict()], 'og_description': self.og_description, 'top_artist': [artist.to_dict()],
'recent_tracks': [track_id.to_dict()], 'metrika_id': self.metrika_id} 'recent_tracks': [track_id.to_dict()], 'metrika_id': self.metrika_id,
'contest': contest.to_dict(), 'dummy_description': self.dummy_description,
'dummy_page_description': self.dummy_page_description, 'dummy_cover': cover.to_dict(),
'dummy_rollover_cover': cover.to_dict(), 'og_data': open_graph_data.to_dict(),
'branding': brand.to_dict()}
playlist = Playlist.de_json(json_dict, client) playlist = Playlist.de_json(json_dict, client)
assert playlist.owner == user assert playlist.owner == user
@ -150,9 +164,16 @@ class TestPlaylist:
assert playlist.og_description == self.og_description assert playlist.og_description == self.og_description
assert playlist.image == self.image assert playlist.image == self.image
assert playlist.cover_without_text == cover assert playlist.cover_without_text == cover
assert playlist.contest == contest
assert playlist.background_color == self.background_color assert playlist.background_color == self.background_color
assert playlist.text_color == self.text_color assert playlist.text_color == self.text_color
assert playlist.id_for_from == self.id_for_from assert playlist.id_for_from == self.id_for_from
assert playlist.dummy_description == self.dummy_description
assert playlist.dummy_page_description == self.dummy_page_description
assert playlist.dummy_cover == cover
assert playlist.dummy_rollover_cover == cover
assert playlist.og_data == open_graph_data
assert playlist.branding == brand
assert playlist.metrika_id == self.metrika_id assert playlist.metrika_id == self.metrika_id
assert playlist.coauthors == self.coauthors assert playlist.coauthors == self.coauthors
assert playlist.top_artist == [artist] assert playlist.top_artist == [artist]

ファイルの表示

@ -37,6 +37,9 @@ from .artist.vinyl import Vinyl
from .playlist.case_forms import CaseForms from .playlist.case_forms import CaseForms
from .playlist.made_for import MadeFor from .playlist.made_for import MadeFor
from .playlist.user import User from .playlist.user import User
from .playlist.contest import Contest
from .playlist.open_graph_data import OpenGraphData
from .playlist.brand import Brand
from .playlist.play_counter import PlayCounter from .playlist.play_counter import PlayCounter
from .playlist.playlist_id import PlaylistId from .playlist.playlist_id import PlaylistId
from .playlist.tag import Tag from .playlist.tag import Tag
@ -138,4 +141,4 @@ __all__ = ['YandexMusicObject', 'Client', 'Account', 'PassportPhone', 'Invocatio
'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings', 'RenewableRemainder', 'ChartInfo', 'ChartInfoMenu', 'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings', 'RenewableRemainder', 'ChartInfo', 'ChartInfoMenu',
'ChartInfoMenuItem', 'Tag', 'TagResult', 'PlaylistRecommendations', 'LandingList', 'MetaData', 'ChartInfoMenuItem', 'Tag', 'TagResult', 'PlaylistRecommendations', 'LandingList', 'MetaData',
'LicenceTextPart', 'StationData', 'AlertButton', 'Alert', 'NonAutoRenewable', 'PoetryLoverMatch', 'LicenceTextPart', 'StationData', 'AlertButton', 'Alert', 'NonAutoRenewable', 'PoetryLoverMatch',
'Operator', 'Deactivation'] 'Operator', 'Deactivation', 'Contest', 'OpenGraphData', 'Brand']

ファイルの表示

@ -1456,6 +1456,9 @@ class Client(YandexMusicObject):
"""Получение цепочки треков определённой станции. """Получение цепочки треков определённой станции.
Note: Note:
Запуск потока по сущности сервиса осуществляется через станцию `<type>:<id>`.
Например, станцией для запуска потока по треку будет `track:1234`.
Для продолжения цепочки треков необходимо: Для продолжения цепочки треков необходимо:
1. Передавать `ID` трека, что был до этого (первый в цепочки). 1. Передавать `ID` трека, что был до этого (первый в цепочки).

76
yandex_music/playlist/brand.py ノーマルファイル
ファイルの表示

@ -0,0 +1,76 @@
from typing import TYPE_CHECKING, Optional, List
from yandex_music import YandexMusicObject
if TYPE_CHECKING:
from yandex_music import Client
class Brand(YandexMusicObject):
"""Класс, представляющий бренд плейлиста.
Note:
Отслеживание просмотров на сторонник сервисах бренда, рекомендация следующего контента.
Attributes:
image (:obj:`str`): Ссылка на изображение.
background (:obj:`str`): Цвет заднего фона.
reference (:obj:`str`): URI ссылка на содержимое.
pixels (:obj:`list` из :obj:`str`): Ссылки на gif изображения для отслеживания просмотров (web beacon).
theme (:obj:`str`): Тема оформления.
playlist_theme (:obj:`str`): Тема плейлиста TODO.
button (:obj:`str`): Текст кнопки.
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
Args:
image (:obj:`str`): Ссылка на изображение.
background (:obj:`str`): Цвет заднего фона.
reference (:obj:`str`): URI ссылка на содержимое.
pixels (:obj:`list` из :obj:`str`): Ссылки на gif изображения для отслеживания просмотров (web beacon).
theme (:obj:`str`): Тема оформления.
playlist_theme (:obj:`str`): Тема плейлиста TODO.
button (:obj:`str`): Текст кнопки.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
**kwargs: Произвольные ключевые аргументы полученные от API.
"""
def __init__(self,
image: str,
background: str,
reference: str,
pixels: List[str],
theme: str,
playlist_theme: str,
button: str,
client: Optional['Client'] = None,
**kwargs) -> None:
self.image = image
self.background = background
self.reference = reference
self.pixels = pixels
self.theme = theme
self.playlist_theme = playlist_theme
self.button = button
self.client = client
self._id_attrs = (self.image, self.reference, self.pixels)
super().handle_unknown_kwargs(self, **kwargs)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['Brand']:
"""Десериализация объекта.
Args:
data (:obj:`dict`): Поля и значения десериализуемого объекта.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
Returns:
:obj:`yandex_music.Brand`: Бренд плейлиста.
"""
if not data:
return None
data = super(Brand, cls).de_json(data, client)
return cls(client=client, **data)

68
yandex_music/playlist/contest.py ノーマルファイル
ファイルの表示

@ -0,0 +1,68 @@
from typing import TYPE_CHECKING, Optional
from yandex_music import YandexMusicObject
if TYPE_CHECKING:
from yandex_music import Client
class Contest(YandexMusicObject):
"""Класс, представляющий контест TODO.
Note:
Известные значения поля `status`: `editing`, `withdrew-moderator`.
Attributes:
contest_id (:obj:`str`): Уникальный идентификатор.
status (:obj:`str`): Статус.
can_edit (:obj:`bool`): Разрешено ли редактирование.
sent (:obj:`str`): Дата отправки.
withdrawn (:obj:`str`): Дата вывода (окончания).
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
Args:
contest_id (:obj:`str`): Уникальный идентификатор.
status (:obj:`str`): Статус.
can_edit (:obj:`bool`): Разрешено ли редактирование.
sent (:obj:`str`, optional): Дата отправки.
withdrawn (:obj:`str`, optional): Дата вывода (окончания).
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
**kwargs: Произвольные ключевые аргументы полученные от API.
"""
def __init__(self,
contest_id: str,
status: str,
can_edit: bool,
sent: Optional[str] = None,
withdrawn: Optional[str] = None,
client: Optional['Client'] = None,
**kwargs) -> None:
self.contest_id = contest_id
self.status = status
self.can_edit = can_edit
self.sent = sent
self.withdrawn = withdrawn
self.client = client
self._id_attrs = (self.contest_id, self.status)
super().handle_unknown_kwargs(self, **kwargs)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['Contest']:
"""Десериализация объекта.
Args:
data (:obj:`dict`): Поля и значения десериализуемого объекта.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
Returns:
:obj:`yandex_music.Contest`: Контест.
"""
if not data:
return None
data = super(Contest, cls).de_json(data, client)
return cls(client=client, **data)

59
yandex_music/playlist/open_graph_data.py ノーマルファイル
ファイルの表示

@ -0,0 +1,59 @@
from typing import TYPE_CHECKING, Optional, List
from yandex_music import YandexMusicObject
if TYPE_CHECKING:
from yandex_music import Client, Cover
class OpenGraphData(YandexMusicObject):
"""Класс, представляющий данные для Open Graph.
Attributes:
title (:obj:`str`): Заголовок.
description (:obj:`str`): Описание.
image (:obj:`yandex_music.Cover`): Изображение.
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
Args:
title (:obj:`str`): Заголовок.
description (:obj:`str`): Описание.
image (:obj:`yandex_music.Cover`): Изображение.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
**kwargs: Произвольные ключевые аргументы полученные от API.
"""
def __init__(self,
title: str,
description: str,
image: 'Cover',
client: Optional['Client'] = None,
**kwargs) -> None:
self.title = title
self.description = description
self.image = image
self.client = client
self._id_attrs = (self.title, self.description, self.image)
super().handle_unknown_kwargs(self, **kwargs)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['OpenGraphData']:
"""Десериализация объекта.
Args:
data (:obj:`dict`): Поля и значения десериализуемого объекта.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
Returns:
:obj:`yandex_music.OpenGraphData`: Данные для Open Graph.
"""
if not data:
return None
data = super(OpenGraphData, cls).de_json(data, client)
from yandex_music import Cover
data['image'] = Cover.de_json(data.get('image'), client)
return cls(client=client, **data)

ファイルの表示

@ -4,13 +4,16 @@ from yandex_music import YandexMusicObject
if TYPE_CHECKING: if TYPE_CHECKING:
from yandex_music import Client, User, Cover, MadeFor, TrackShort, PlaylistAbsence, PlayCounter,\ from yandex_music import Client, User, Cover, MadeFor, TrackShort, PlaylistAbsence, PlayCounter,\
PlaylistRecommendations, Artist, TrackId PlaylistRecommendations, Artist, TrackId, Contest, OpenGraphData, Brand
class Playlist(YandexMusicObject): class Playlist(YandexMusicObject):
"""Класс, представляющий плейлист. """Класс, представляющий плейлист.
Note: Note:
Под полями с заглушками понимаются поля, которые доступны у умных плейлистов тогда, когда у сервиса мало
данных для генерации плейлиста.
Известные значения `visibility`: `public` - публичный плейлист, `private` - приватный плейлист. Известные значения `visibility`: `public` - публичный плейлист, `private` - приватный плейлист.
Известные значения `generated_playlist_type`: `playlistOfTheDay` - Плейлист дня, `recentTracks` - Премьера, Известные значения `generated_playlist_type`: `playlistOfTheDay` - Плейлист дня, `recentTracks` - Премьера,
@ -44,9 +47,16 @@ class Playlist(YandexMusicObject):
og_description (:obj:`str`, optional): Описание Open Graph. og_description (:obj:`str`, optional): Описание Open Graph.
image (:obj:`str`): Изображение TODO. image (:obj:`str`): Изображение TODO.
cover_without_text (:obj:`yandex_music.Cover`): Обложка без текста. cover_without_text (:obj:`yandex_music.Cover`): Обложка без текста.
contest (:obj:`yandex_music.Contest`): Контест TODO.
background_color (:obj:`str`): Цвет заднего фона TODO. background_color (:obj:`str`): Цвет заднего фона TODO.
text_color (:obj:`str`): Цвет текста TODO. text_color (:obj:`str`): Цвет текста TODO.
id_for_from (:obj:`str`): Откуда пришло событие (уникальный идентификатор объекта) TODO. id_for_from (:obj:`str`): Откуда пришло событие (уникальный идентификатор объекта) TODO.
dummy_description (:obj:`str`): Описание-заглушка плейлиста.
dummy_page_description (:obj:`str`): Описание-заглушка страницы.
dummy_cover (:obj:`str`): Обложка-заглушка.
dummy_rollover_cover (:obj:`str`): Обложка-заглушка TODO.
og_data (:obj:`yandex_music.OpenGraphData`): Данные для OpenGraph.
branding (:obj:`yandex_music.Brand`): Бренд.
metrika_id (:obj:`int`): Уникальный идентификатор счётчика на Яндекс.Метрика. metrika_id (:obj:`int`): Уникальный идентификатор счётчика на Яндекс.Метрика.
coauthors (:obj:`list` из :obj:`int`): Перечень ID аккаунтов соавторов плейлиста. coauthors (:obj:`list` из :obj:`int`): Перечень ID аккаунтов соавторов плейлиста.
top_artist (:obj:`list` из :obj:`yandex_music.Artist`): Топ артистов TODO. top_artist (:obj:`list` из :obj:`yandex_music.Artist`): Топ артистов TODO.
@ -93,9 +103,16 @@ class Playlist(YandexMusicObject):
og_description (:obj:`str`, optional): Описание Open Graph. og_description (:obj:`str`, optional): Описание Open Graph.
image (:obj:`str`, optional): Изображение TODO. image (:obj:`str`, optional): Изображение TODO.
cover_without_text (:obj:`yandex_music.Cover`, optional): Обложка без текста. cover_without_text (:obj:`yandex_music.Cover`, optional): Обложка без текста.
contest (:obj:`yandex_music.Contest`, optional): Контест TODO.
background_color (:obj:`str`, optional): Цвет заднего фона TODO. background_color (:obj:`str`, optional): Цвет заднего фона TODO.
text_color (:obj:`str`, optional): Цвет текста TODO. text_color (:obj:`str`, optional): Цвет текста TODO.
id_for_from (:obj:`str`, optional): Откуда пришло событие (уникальный идентификатор объекта) TODO. id_for_from (:obj:`str`, optional): Откуда пришло событие (уникальный идентификатор объекта) TODO.
dummy_description (:obj:`str`, optional): Описание-заглушка плейлиста.
dummy_page_description (:obj:`str`, optional): Описание-заглушка страницы.
dummy_cover (:obj:`str`, optional): Обложка-заглушка.
dummy_rollover_cover (:obj:`str`, optional): Обложка-заглушка TODO.
og_data (:obj:`yandex_music.OpenGraphData`, optional): Данные для OpenGraph.
branding (:obj:`yandex_music.Brand`): Бренд.
metrika_id (:obj:`int`, optional): Уникальный идентификатор счётчика на Яндекс.Метрика. metrika_id (:obj:`int`, optional): Уникальный идентификатор счётчика на Яндекс.Метрика.
coauthors (:obj:`list` из :obj:`int`, optional): Перечень ID аккаунтов соавторов плейлиста. coauthors (:obj:`list` из :obj:`int`, optional): Перечень ID аккаунтов соавторов плейлиста.
top_artist (:obj:`list` из :obj:`yandex_music.Artist`, optional): Топ артистов TODO. top_artist (:obj:`list` из :obj:`yandex_music.Artist`, optional): Топ артистов TODO.
@ -144,9 +161,16 @@ class Playlist(YandexMusicObject):
og_description: Optional[str] = None, og_description: Optional[str] = None,
image: Optional[str] = None, image: Optional[str] = None,
cover_without_text: Optional['Cover'] = None, cover_without_text: Optional['Cover'] = None,
contest: Optional['Contest'] = None,
background_color: Optional[str] = None, background_color: Optional[str] = None,
text_color: Optional[str] = None, text_color: Optional[str] = None,
id_for_from: Optional[str] = None, id_for_from: Optional[str] = None,
dummy_description: Optional[str] = None,
dummy_page_description: Optional[str] = None,
dummy_cover: Optional['Cover'] = None,
dummy_rollover_cover: Optional['Cover'] = None,
og_data: Optional['OpenGraphData'] = None,
branding: Optional['Brand'] = None,
metrika_id: Optional[int] = None, metrika_id: Optional[int] = None,
coauthors: List[int] = None, coauthors: List[int] = None,
top_artist: List['Artist'] = None, top_artist: List['Artist'] = None,
@ -191,9 +215,16 @@ class Playlist(YandexMusicObject):
self.og_description = og_description self.og_description = og_description
self.image = image self.image = image
self.cover_without_text = cover_without_text self.cover_without_text = cover_without_text
self.contest = contest
self.background_color = background_color self.background_color = background_color
self.text_color = text_color self.text_color = text_color
self.id_for_from = id_for_from self.id_for_from = id_for_from
self.dummy_description = dummy_description
self.dummy_page_description = dummy_page_description
self.dummy_cover = dummy_cover
self.dummy_rollover_cover = dummy_rollover_cover
self.og_data = og_data
self.branding = branding
self.metrika_id = metrika_id self.metrika_id = metrika_id
self.coauthors = coauthors self.coauthors = coauthors
self.top_artist = top_artist self.top_artist = top_artist
@ -294,7 +325,8 @@ class Playlist(YandexMusicObject):
return None return None
data = super(Playlist, cls).de_json(data, client) data = super(Playlist, cls).de_json(data, client)
from yandex_music import User, MadeFor, Cover, PlayCounter, TrackShort, PlaylistAbsence, Artist, TrackId from yandex_music import User, MadeFor, Cover, PlayCounter, TrackShort, \
PlaylistAbsence, Artist, TrackId, Contest, OpenGraphData, Brand
data['owner'] = User.de_json(data.get('owner'), client) data['owner'] = User.de_json(data.get('owner'), client)
data['cover'] = Cover.de_json(data.get('cover'), client) data['cover'] = Cover.de_json(data.get('cover'), client)
data['cover_without_text'] = Cover.de_json(data.get('cover_without_text'), client) data['cover_without_text'] = Cover.de_json(data.get('cover_without_text'), client)
@ -303,6 +335,11 @@ class Playlist(YandexMusicObject):
data['recent_tracks'] = TrackId.de_list(data.get('recent_tracks'), client) data['recent_tracks'] = TrackId.de_list(data.get('recent_tracks'), client)
data['play_counter'] = PlayCounter.de_json(data.get('play_counter'), client) data['play_counter'] = PlayCounter.de_json(data.get('play_counter'), client)
data['top_artist'] = Artist.de_list(data.get('top_artist'), client) data['top_artist'] = Artist.de_list(data.get('top_artist'), client)
data['contest'] = Contest.de_json(data.get('contest'), client)
data['og_data'] = OpenGraphData.de_json(data.get('og_data'), client)
data['dummy_cover'] = Cover.de_json(data.get('dummy_cover'), client)
data['dummy_rollover_cover'] = Cover.de_json(data.get('dummy_rollover_cover'), client)
data['branding'] = Brand.de_json(data.get('branding'), client)
data['similar_playlists'] = Playlist.de_list(data.get('similar_playlists'), client) data['similar_playlists'] = Playlist.de_list(data.get('similar_playlists'), client)
data['last_owner_playlists'] = Playlist.de_list(data.get('last_owner_playlists'), client) data['last_owner_playlists'] = Playlist.de_list(data.get('last_owner_playlists'), client)