Добавлены новые классы: Brand, Contest, OpenGraphData.
Поля contest, dummy_description, dummy_page_description, dummy_cover, dummy_rollover_cover, og_data, branding классу Playlist. Добавлена информацию по поводу запуска потока по треку, плейлисту и т.д. Документация и тесты к новым полям, классам #339
このコミットが含まれているのは:
コミット
a6c0c709fd
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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` трека, что был до этого (первый в цепочки).
|
||||||
|
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
||||||
|
|
読み込み中…
新しいイシューから参照