Merge pull request #307 from MarshalX/feature/issue-306

Новые поля собранные за 3 недели
このコミットが含まれているのは:
Il'ya 2020-04-30 23:16:47 +03:00 committed by GitHub
コミット 49804ef600
この署名に対応する既知のキーがデータベースに存在しません
GPGキーID: 4AEE18F83AFDEB23
23個のファイルの変更292行の追加102行の削除

ファイルの表示

@ -73,3 +73,4 @@ from .test_vinyl import TestVinyl
from .test_shot_type import TestShotType
from .test_shot_data import TestShotData
from .test_shot import TestShot
from .test_renewable_remainder import TestRenewableRemainder

ファイルの表示

@ -6,7 +6,8 @@ from yandex_music import Counts, TrackId, CaseForms, Ratings, Icon, Album, Lyric
Account, Client, TrackShort, Value, DiscreteScale, PlaylistId, MixLink, Link, PassportPhone, User, Promotion, \
PersonalPlaylistsData, RotorSettings, TrackShortOld, PlayContextsData, Status, Settings, StationResult, Enum, \
TrackWithAds, VideoSupplement, ArtistEvent, ChartItem, Event, AlbumEvent, Day, PlayContext, Plus, Title, Label, \
GeneratedPlaylist, Video, Vinyl, SearchResult, BlockEntity, Block, PlaylistAbsence, ShotType, ShotData, Shot
GeneratedPlaylist, Video, Vinyl, SearchResult, BlockEntity, Block, PlaylistAbsence, ShotType, ShotData, Shot, \
RenewableRemainder
from . import TestCounts, TestTrackId, TestCaseForms, TestRatings, TestIcon, TestAlbum, TestLyrics, \
TestTrack, TestInvocationInfo, TestPlaylist, TestAutoRenewable, TestStation, TestNormalization, TestMajor, \
TestTrackPosition, TestBest, TestChart, TestPermissions, TestPlus, TestProduct, TestCover, TestPlayCounter, \
@ -15,15 +16,16 @@ from . import TestCounts, TestTrackId, TestCaseForms, TestRatings, TestIcon, Tes
TestUser, TestPassportPhone, TestPromotion, TestTitle, TestPersonalPlaylistsData, TestRotorSettings, \
TestTrackShortOld, TestPager, TestStatus, TestSettings, TestStationResult, TestLabel, TestTrackWithAds, \
TestVideoSupplement, TestEvent, TestDay, TestPlayContext, TestGeneratedPlaylist, TestVideo, TestVinyl, \
TestSearchResult, TestBlockEntity, TestBlock, TestPlaylistAbsence, TestShot, TestShotData, TestShotType
TestSearchResult, TestBlockEntity, TestBlock, TestPlaylistAbsence, TestShot, TestShotData, TestShotType, \
TestRenewableRemainder
@pytest.fixture(scope='session')
def artist_factory(cover, counts, ratings, link, description):
class ArtistFactory:
def get(self, popular_tracks):
return Artist(TestArtist.id, TestArtist.error, TestArtist.name, cover, TestArtist.various,
TestArtist.composer, TestArtist.genres, TestArtist.op_image,
return Artist(TestArtist.id, TestArtist.reason, TestArtist.name, cover, TestArtist.various,
TestArtist.composer, TestArtist.genres, TestArtist.og_image, TestArtist.op_image,
TestArtist.no_pictures_from_search, counts, TestArtist.available, ratings, [link],
TestArtist.tickets_available, TestArtist.likes_count, popular_tracks, TestArtist.regions,
TestArtist.decomposed, TestArtist.full_names, description, TestArtist.countries,
@ -48,12 +50,12 @@ def track_factory(major, normalization):
class TrackFactory:
def get(self, artists, albums):
return Track(TestTrack.id, TestTrack.title, TestTrack.available, artists, albums,
TestTrack.available_for_premium_users, TestTrack.lyrics_available, TestTrack.real_id,
TestTrack.og_image, TestTrack.type, TestTrack.cover_uri, major, TestTrack.duration_ms,
TestTrack.storage_dir, TestTrack.file_size, normalization, TestTrack.error, TestTrack.regions,
TestTrack.available_as_rbt, TestTrack.content_warning, TestTrack.explicit,
TestTrack.preview_duration_ms, TestTrack.available_full_without_permission, TestTrack.version,
TestTrack.remember_position)
TestTrack.available_for_premium_users, TestTrack.lyrics_available, TestTrack.best,
TestTrack.real_id, TestTrack.og_image, TestTrack.type, TestTrack.cover_uri, major,
TestTrack.duration_ms, TestTrack.storage_dir, TestTrack.file_size, normalization,
TestTrack.error, TestTrack.regions, TestTrack.available_as_rbt, TestTrack.content_warning,
TestTrack.explicit, TestTrack.preview_duration_ms, TestTrack.available_full_without_permission,
TestTrack.version, TestTrack.remember_position)
return TrackFactory()
@ -85,10 +87,10 @@ def album_factory(label, track_position):
return Album(TestAlbum.id, TestAlbum.error, TestAlbum.title, TestAlbum.track_count, artists, [label],
TestAlbum.available, TestAlbum.available_for_premium_users, TestAlbum.version,
TestAlbum.cover_uri, TestAlbum.content_warning, TestAlbum.original_release_year,
TestAlbum.genre, TestAlbum.og_image, TestAlbum.buy, TestAlbum.recent, TestAlbum.very_important,
TestAlbum.available_for_mobile, TestAlbum.available_partially, TestAlbum.bests,
TestAlbum.prerolls, volumes, TestAlbum.year, TestAlbum.release_date, TestAlbum.type,
track_position, TestAlbum.regions)
TestAlbum.genre, TestAlbum.meta_type, TestAlbum.og_image, TestAlbum.buy, TestAlbum.recent,
TestAlbum.very_important, TestAlbum.available_for_mobile, TestAlbum.available_partially,
TestAlbum.bests, TestAlbum.prerolls, volumes, TestAlbum.year, TestAlbum.release_date,
TestAlbum.type, track_position, TestAlbum.regions)
return AlbumFactory()
@ -164,7 +166,8 @@ def video():
@pytest.fixture(scope='session')
def vinyl():
return Vinyl(TestVinyl.url, TestVinyl.title, TestVinyl.year, TestVinyl.price, TestVinyl.media, TestVinyl.picture)
return Vinyl(TestVinyl.url, TestVinyl.title, TestVinyl.year, TestVinyl.price, TestVinyl.media, TestVinyl.offer_id,
TestVinyl.artist_ids, TestVinyl.picture)
@pytest.fixture(scope='session')
@ -190,8 +193,8 @@ def icon():
@pytest.fixture(scope='session')
def cover():
return Cover(TestCover.type, TestCover.uri, TestCover.items_uri, TestCover.dir,
TestCover.version, TestCover.custom, TestCover.prefix, TestCover.error)
return Cover(TestCover.type, TestCover.uri, TestCover.items_uri, TestCover.dir, TestCover.version,
TestCover.custom, TestCover.is_custom, TestCover.prefix, TestCover.error)
@pytest.fixture(scope='session')
@ -338,6 +341,11 @@ def passport_phone():
return PassportPhone(TestPassportPhone.phone)
@pytest.fixture(scope='session')
def renewable_remainder():
return RenewableRemainder(TestRenewableRemainder.days)
@pytest.fixture(scope='session')
def user():
return User(TestUser.uid, TestUser.login, TestUser.name, TestUser.sex, TestUser.verified)
@ -362,9 +370,9 @@ def price():
@pytest.fixture(scope='session')
def subscription(auto_renewable):
return Subscription([auto_renewable], TestSubscription.can_start_trial, TestSubscription.mcdonalds,
TestSubscription.end)
def subscription(renewable_remainder, auto_renewable):
return Subscription(renewable_remainder, [auto_renewable], TestSubscription.can_start_trial,
TestSubscription.mcdonalds, TestSubscription.end)
@pytest.fixture(scope='session')
@ -376,8 +384,8 @@ def rotor_settings():
@pytest.fixture(scope='session')
def product(price):
return Product(TestProduct.product_id, TestProduct.type, TestProduct.common_period_duration, TestProduct.duration,
TestProduct.trial_duration, price, TestProduct.feature, TestProduct.debug, TestProduct.features,
TestProduct.description, TestProduct.available, TestProduct.trial_available,
TestProduct.trial_duration, price, TestProduct.feature, TestProduct.debug, TestProduct.plus,
TestProduct.features, TestProduct.description, TestProduct.available, TestProduct.trial_available,
TestProduct.vendor_trial_available, TestProduct.button_text, TestProduct.button_additional_text,
TestProduct.payment_method_types)
@ -399,9 +407,9 @@ def track_position():
@pytest.fixture(scope='session')
def status(account, permissions, subscription, plus):
return Status(account, permissions, subscription, TestStatus.cache_limit, TestStatus.subeditor,
TestStatus.subeditor_level, plus, TestStatus.default_email, TestStatus.skips_per_hour,
TestStatus.station_exists, TestStatus.premium_region)
return Status(account, permissions, TestStatus.advertisement, subscription, TestStatus.cache_limit,
TestStatus.subeditor, TestStatus.subeditor_level, plus, TestStatus.default_email,
TestStatus.skips_per_hour, TestStatus.station_exists, TestStatus.premium_region)
@pytest.fixture(scope='session')

ファイルの表示

@ -13,6 +13,7 @@ class TestAlbum:
content_warning = None
original_release_year = None
genre = 'alternative'
meta_type = 'music'
og_image = 'avatars.yandex.net/get-music-content/95061/89c14a7d.a.5239478-1/%%'
buy = []
recent = False
@ -40,6 +41,7 @@ class TestAlbum:
assert album.content_warning == self.content_warning
assert album.original_release_year == self.original_release_year
assert album.genre == self.genre
assert album.meta_type == self.meta_type
assert album.og_image == self.og_image
assert album.buy == self.buy
assert album.recent == self.recent
@ -76,7 +78,8 @@ class TestAlbum:
'og_image': self.og_image, 'recent': self.recent, 'very_important': self.very_important,
'available_for_mobile': self.available_for_mobile, 'available_partially': self.available_partially,
'bests': self.bests, 'prerolls': self.prerolls, 'volumes': [[track.to_dict()]], 'year': self.year,
'release_date': self.release_date, 'type_': self.type, 'track_position': track_position.to_dict()}
'release_date': self.release_date, 'type_': self.type, 'track_position': track_position.to_dict(),
'meta_type': self.meta_type}
album = Album.de_json(json_dict, client)
assert album.id == self.id
@ -92,6 +95,7 @@ class TestAlbum:
assert album.content_warning == self.content_warning
assert album.original_release_year == self.original_release_year
assert album.genre == self.genre
assert album.meta_type == self.meta_type
assert album.og_image == self.og_image
assert album.buy == self.buy
assert album.recent == self.recent

ファイルの表示

@ -3,11 +3,12 @@ from yandex_music import Artist
class TestArtist:
id = 10987
error = 'not-found'
reason = 'not-found'
name = 'Elvis Presley'
various = False
composer = None
genres = None
og_image = ''
op_image = None
no_pictures_from_search = None
available = None
@ -25,12 +26,13 @@ class TestArtist:
def test_expected_values(self, artist, cover, counts, ratings, link, track_without_artists_and_albums, description):
assert artist.id == self.id
assert artist.error == self.error
assert artist.reason == self.reason
assert artist.name == self.name
assert artist.various == self.various
assert artist.composer == self.composer
assert artist.cover == cover
assert artist.genres == self.genres
assert artist.og_image == self.og_image
assert artist.op_image == self.op_image
assert artist.no_pictures_from_search == self.no_pictures_from_search
assert artist.counts == counts
@ -64,10 +66,11 @@ class TestArtist:
assert artist.id == self.id
def test_de_json_all(self, client, cover, counts, ratings, link, track_without_artists, description):
json_dict = {'id_': self.id, 'error': self.error, 'name': self.name, 'various': self.various,
'composer': self.composer, 'cover': cover.to_dict(), 'genres': self.genres,
'op_image': self.op_image, 'no_pictures_from_search': self.no_pictures_from_search,
'counts': counts.to_dict(), 'available': self.available, 'ratings': ratings.to_dict(),
json_dict = {'id_': self.id, 'reason': self.reason, 'name': self.name,
'various': self.various, 'composer': self.composer, 'cover': cover.to_dict(),
'genres': self.genres, 'op_image': self.op_image, 'og_image': self.og_image,
'no_pictures_from_search': self.no_pictures_from_search, 'counts': counts.to_dict(),
'available': self.available, 'ratings': ratings.to_dict(),
'links': [link.to_dict()], 'tickets_available': self.tickets_available,
'likes_count': self.likes_count, 'popular_tracks': [track_without_artists.to_dict()],
'regions': self.regions, 'decomposed': self.decomposed, 'full_names': self.full_names,
@ -77,12 +80,13 @@ class TestArtist:
artist = Artist.de_json(json_dict, client)
assert artist.id == self.id
assert artist.error == self.error
assert artist.reason == self.reason
assert artist.name == self.name
assert artist.various == self.various
assert artist.composer == self.composer
assert artist.cover == cover
assert artist.genres == self.genres
assert artist.og_image == self.og_image
assert artist.op_image == self.op_image
assert artist.no_pictures_from_search == self.no_pictures_from_search
assert artist.counts == counts

ファイルの表示

@ -4,8 +4,8 @@ from yandex_music import BriefInfo
@pytest.fixture(scope='class')
def brief_info(artist, track, album, cover, playlist_id, video, chart, vinyl):
return BriefInfo(artist, [album], [album], TestBriefInfo.last_release_ids, [track], [artist], [cover],
def brief_info(artist, track, album, playlist, cover, playlist_id, video, chart, vinyl):
return BriefInfo(artist, [album], [playlist], [album], TestBriefInfo.last_release_ids, [track], [artist], [cover],
TestBriefInfo.concerts, [video], [vinyl], TestBriefInfo.has_promotions, [playlist_id], [chart])
@ -14,9 +14,10 @@ class TestBriefInfo:
concerts = None
has_promotions = False
def test_expected_values(self, brief_info, artist, track, album, cover, playlist_id, video, chart, vinyl):
def test_expected_values(self, brief_info, artist, track, album, playlist, cover, playlist_id, video, chart, vinyl):
assert brief_info.artist == artist
assert brief_info.albums == [album]
assert brief_info.playlists == [playlist]
assert brief_info.also_albums == [album]
assert brief_info.last_release_ids == self.last_release_ids
assert brief_info.popular_tracks == [track]
@ -32,16 +33,17 @@ class TestBriefInfo:
def test_de_json_none(self, client):
assert BriefInfo.de_json({}, client) is None
def test_de_json_required(self, client, artist, track, album, cover, playlist_id, video, vinyl):
def test_de_json_required(self, client, artist, track, album, playlist, cover, playlist_id, video, vinyl):
json_dict = {'artist': artist.to_dict(), 'albums': [album.to_dict()], 'also_albums': [album.to_dict()],
'last_release_ids': self.last_release_ids, 'popular_tracks': [track.to_dict()],
'similar_artists': [artist.to_dict()], 'all_covers': [cover.to_dict()], 'concerts': self.concerts,
'videos': [video.to_dict()], 'vinyls': [vinyl.to_dict()], 'has_promotions': self.has_promotions,
'playlist_ids': [playlist_id.to_dict()]}
'playlist_ids': [playlist_id.to_dict()], 'playlists': [playlist.to_dict()]}
brief_info = BriefInfo.de_json(json_dict, client)
assert brief_info.artist == artist
assert brief_info.albums == [album]
assert brief_info.playlists == [playlist]
assert brief_info.also_albums == [album]
assert brief_info.last_release_ids == self.last_release_ids
assert brief_info.popular_tracks == [track]
@ -53,16 +55,18 @@ class TestBriefInfo:
assert brief_info.has_promotions == self.has_promotions
assert brief_info.playlist_ids == [playlist_id]
def test_de_json_all(self, client, artist, track, album, cover, playlist_id, video, chart, vinyl):
def test_de_json_all(self, client, artist, track, album, playlist, cover, playlist_id, video, chart, vinyl):
json_dict = {'artist': artist.to_dict(), 'albums': [album.to_dict()], 'also_albums': [album.to_dict()],
'last_release_ids': self.last_release_ids, 'popular_tracks': [track.to_dict()],
'similar_artists': [artist.to_dict()], 'all_covers': [cover.to_dict()], 'concerts': self.concerts,
'videos': [video.to_dict()], 'vinyls': [vinyl.to_dict()], 'has_promotions': self.has_promotions,
'playlist_ids': [playlist_id.to_dict()], 'tracks_in_chart': [chart.to_dict()]}
'playlist_ids': [playlist_id.to_dict()], 'tracks_in_chart': [chart.to_dict()],
'playlists': [playlist.to_dict()]}
brief_info = BriefInfo.de_json(json_dict, client)
assert brief_info.artist == artist
assert brief_info.albums == [album]
assert brief_info.playlists == [playlist]
assert brief_info.also_albums == [album]
assert brief_info.last_release_ids == self.last_release_ids
assert brief_info.popular_tracks == [track]
@ -75,15 +79,15 @@ class TestBriefInfo:
assert brief_info.playlist_ids == [playlist_id]
assert brief_info.tracks_in_chart == [chart]
def test_equality(self, artist, track, album, cover, playlist_id, video, vinyl):
a = BriefInfo(artist, [album], [album], self.last_release_ids, [track], [artist], [cover], self.concerts,
[video], [vinyl], self.has_promotions, [playlist_id])
b = BriefInfo(artist, [album], [album], self.last_release_ids, [], [artist], [cover], self.concerts,
def test_equality(self, artist, track, album, playlist, cover, playlist_id, video, vinyl):
a = BriefInfo(artist, [album], [playlist], [album], self.last_release_ids, [track], [artist], [cover],
self.concerts, [video], [vinyl], self.has_promotions, [playlist_id])
b = BriefInfo(artist, [album], [], [album], self.last_release_ids, [], [artist], [cover], self.concerts,
[video], [vinyl], True, [playlist_id])
c = BriefInfo(artist, [album], [album], [1, 2, 3], [track], [artist], [], self.concerts,
[video], [vinyl], self.has_promotions, [playlist_id])
d = BriefInfo(artist, [album], [album], self.last_release_ids, [track], [artist], [cover], self.concerts,
c = BriefInfo(artist, [album], [playlist], [album], [1, 2, 3], [track], [artist], [], self.concerts,
[video], [vinyl], self.has_promotions, [playlist_id])
d = BriefInfo(artist, [album], [playlist], [album], self.last_release_ids, [track], [artist], [cover],
self.concerts, [video], [vinyl], self.has_promotions, [playlist_id])
assert a != b != c
assert hash(a) != hash(b) != hash(c)

ファイルの表示

@ -8,6 +8,7 @@ class TestCover:
dir = '/get-music-user-playlist/34120/pvg900XixWaHcr/'
version = '1572609906461'
custom = True
is_custom = True
prefix = None
error = None
@ -18,6 +19,7 @@ class TestCover:
assert cover.dir == self.dir
assert cover.version == self.version
assert cover.custom == self.custom
assert cover.is_custom == self.is_custom
assert cover.prefix == self.prefix
assert cover.error == self.error
@ -33,7 +35,8 @@ class TestCover:
def test_de_json_all(self, client):
json_dict = {'type_': self.type, 'uri': self.uri, 'items_uri': self.items_uri, 'dir_': self.dir,
'version': self.version, 'custom': self.custom, 'prefix': self.prefix, 'error': self.error}
'version': self.version, 'custom': self.custom, 'is_custom': self.is_custom, 'prefix': self.prefix,
'error': self.error}
cover = Cover.de_json(json_dict, client)
assert cover.type == self.type
@ -42,6 +45,7 @@ class TestCover:
assert cover.dir == self.dir
assert cover.version == self.version
assert cover.custom == self.custom
assert cover.is_custom == self.is_custom
assert cover.prefix == self.prefix
assert cover.error == self.error

ファイルの表示

@ -10,6 +10,7 @@ class TestProduct:
trial_duration = 0
feature = 'basic-music'
debug = False
plus = False
features = ['basic-music']
available = None
trial_available = None
@ -27,6 +28,7 @@ class TestProduct:
assert product.price == price
assert product.feature == self.feature
assert product.debug == self.debug
assert product.plus == self.plus
assert product.features == self.features
assert product.description == self.description
assert product.available == self.available
@ -46,7 +48,7 @@ class TestProduct:
json_dict = {'product_id': self.product_id, 'type_': self.type,
'common_period_duration': self.common_period_duration, 'duration': self.duration,
'trial_duration': self.trial_duration, 'price': price.to_dict(), 'feature': self.feature,
'debug': self.debug}
'debug': self.debug, 'plus': self.plus}
product = Product.de_json(json_dict, client)
assert product.product_id == self.product_id
@ -57,12 +59,13 @@ class TestProduct:
assert product.price == price
assert product.feature == self.feature
assert product.debug == self.debug
assert product.plus == self.plus
def test_de_json_all(self, client, price):
json_dict = {'product_id': self.product_id, 'type_': self.type,
'common_period_duration': self.common_period_duration, 'duration': self.duration,
'trial_duration': self.trial_duration, 'price': price.to_dict(), 'feature': self.feature,
'debug': self.debug, 'features': self.features, 'description': self.description,
'debug': self.debug, 'plus': self.plus, 'features': self.features, 'description': self.description,
'available': self.available, 'trial_available': self.trial_available,
'vendor_trial_available': self.vendor_trial_available, 'button_text': self.button_text,
'button_additional_text': self.button_additional_text,
@ -77,6 +80,7 @@ class TestProduct:
assert product.price == price
assert product.feature == self.feature
assert product.debug == self.debug
assert product.plus == self.plus
assert product.features == self.features
assert product.description == self.description
assert product.available == self.available
@ -88,11 +92,11 @@ class TestProduct:
def test_equality(self, price):
a = Product(self.product_id, self.type, self.common_period_duration, self.duration, self.trial_duration, price,
self.feature, self.debug)
self.feature, self.debug, self.plus)
b = Product('', self.type, self.common_period_duration, self.duration, self.trial_duration, price,
self.feature, self.debug)
self.feature, self.debug, self.plus)
c = Product(self.product_id, self.type, self.common_period_duration, self.duration, self.trial_duration, price,
self.feature, self.debug)
self.feature, self.debug, self.plus)
assert a != b
assert hash(a) != hash(b)

34
tests/test_renewable_remainder.py ノーマルファイル
ファイルの表示

@ -0,0 +1,34 @@
from yandex_music import RenewableRemainder
class TestRenewableRemainder:
days = 0
def test_expected_values(self, renewable_remainder):
assert renewable_remainder.days == self.days
def test_de_json_none(self, client):
assert RenewableRemainder.de_json({}, client) is None
def test_de_json_required(self, client):
json_dict = {'days': self.days}
renewable_remainder = RenewableRemainder.de_json(json_dict, client)
assert renewable_remainder.days == self.days
def test_de_json_all(self, client):
json_dict = {'days': self.days}
renewable_remainder = RenewableRemainder.de_json(json_dict, client)
assert renewable_remainder.days == self.days
def test_equality(self):
a = RenewableRemainder(self.days)
b = RenewableRemainder(10)
c = RenewableRemainder(self.days)
assert a != b
assert hash(a) != hash(b)
assert a is not b
assert a == c

ファイルの表示

@ -2,6 +2,7 @@ from yandex_music import Status
class TestStatus:
advertisement = 'Оформите постоянную подписку первый месяц бесплатно!'
cache_limit = 99
subeditor = False
subeditor_level = 0
@ -14,6 +15,7 @@ class TestStatus:
assert status.account == account
assert status.permissions == permissions
assert status.subscription == subscription
assert status.advertisement == self.advertisement
assert status.cache_limit == self.cache_limit
assert status.subeditor == self.subeditor
assert status.subeditor_level == self.subeditor_level
@ -27,23 +29,27 @@ class TestStatus:
assert Status.de_json({}, client) is None
def test_de_json_required(self, client, account, permissions):
json_dict = {'account': account.to_dict(), 'permissions': permissions.to_dict()}
json_dict = {'account': account.to_dict(), 'permissions': permissions.to_dict(),
'advertisement': self.advertisement}
status = Status.de_json(json_dict, client)
assert status.account == account
assert status.permissions == permissions
assert status.advertisement == self.advertisement
def test_de_json_all(self, client, account, permissions, subscription, plus):
json_dict = {'account': account.to_dict(), 'permissions': permissions.to_dict(),
'subscription': subscription.to_dict(), 'cache_limit': self.cache_limit,
'subeditor': self.subeditor, 'subeditor_level': self.subeditor_level, 'plus': plus.to_dict(),
'default_email': self.default_email, 'skips_per_hour': self.skips_per_hour,
'station_exists': self.station_exists, 'premium_region': self.premium_region}
'station_exists': self.station_exists, 'premium_region': self.premium_region,
'advertisement': self.advertisement}
status = Status.de_json(json_dict, client)
assert status.account == account
assert status.permissions == permissions
assert status.subscription == subscription
assert status.advertisement == self.advertisement
assert status.cache_limit == self.cache_limit
assert status.subeditor == self.subeditor
assert status.subeditor_level == self.subeditor_level
@ -54,9 +60,9 @@ class TestStatus:
assert status.premium_region == self.premium_region
def test_equality(self, account, permissions, subscription):
a = Status(account, permissions)
b = Status(None, permissions, subscription, self.cache_limit)
c = Status(account, permissions)
a = Status(account, permissions, self.advertisement)
b = Status(None, permissions, '')
c = Status(account, permissions, self.advertisement)
assert a != b
assert hash(a) != hash(b)

ファイルの表示

@ -6,7 +6,8 @@ class TestSubscription:
mcdonalds = False
end = None
def test_expected_values(self, subscription, auto_renewable):
def test_expected_values(self, subscription, renewable_remainder, auto_renewable):
assert subscription.non_auto_renewable_remainder == renewable_remainder
assert subscription.auto_renewable == [auto_renewable]
assert subscription.can_start_trial == self.can_start_trial
assert subscription.mcdonalds == self.mcdonalds
@ -15,23 +16,29 @@ class TestSubscription:
def test_de_json_none(self, client):
assert Subscription.de_json({}, client) is None
def test_de_json_required(self, client):
json_dict = {}
def test_de_json_required(self, client, renewable_remainder, auto_renewable):
json_dict = {'non_auto_renewable_remainder': renewable_remainder.to_dict(),
'auto_renewable': [auto_renewable.to_dict()]}
subscription = Subscription.de_json(json_dict, client)
def test_de_json_all(self, client, auto_renewable):
assert subscription.non_auto_renewable_remainder == renewable_remainder
assert subscription.auto_renewable == [auto_renewable]
def test_de_json_all(self, client, renewable_remainder, auto_renewable):
json_dict = {'auto_renewable': [auto_renewable.to_dict()], 'can_start_trial': self.can_start_trial,
'mcdonalds': self.mcdonalds, 'end': self.end}
'mcdonalds': self.mcdonalds, 'end': self.end, 'non_auto_renewable_remainder':
renewable_remainder.to_dict()}
subscription = Subscription.de_json(json_dict, client)
assert subscription.non_auto_renewable_remainder == renewable_remainder
assert subscription.auto_renewable == [auto_renewable]
assert subscription.can_start_trial == self.can_start_trial
assert subscription.mcdonalds == self.mcdonalds
assert subscription.end == self.end
def test_equality(self, auto_renewable):
a = Subscription([auto_renewable])
b = Subscription(None)
def test_equality(self, renewable_remainder, auto_renewable):
a = Subscription(renewable_remainder, [auto_renewable])
b = Subscription(renewable_remainder, [])
assert a != b != auto_renewable
assert hash(a) != hash(b) != hash(auto_renewable)

ファイルの表示

@ -7,6 +7,7 @@ class TestTrack:
available = True
available_for_premium_users = True
lyrics_available = False
best = False
real_id = '10994777'
og_image = 'avatars.yandex.net/get-music-content/28589/daef4251.a.1193829-1/%%'
type = 'music'
@ -32,6 +33,7 @@ class TestTrack:
assert track.artists == [artist]
assert track.albums == [album]
assert track.lyrics_available == self.lyrics_available
assert track.best == self.best
assert track.real_id == self.real_id
assert track.og_image == self.og_image
assert track.type == self.type
@ -58,21 +60,16 @@ class TestTrack:
assert Track.de_list({}, client) == []
def test_de_json_required(self, client, artist, album):
json_dict = {'id_': self.id, 'title': self.title, 'available': self.available,
'artists': [artist.to_dict()], 'albums': [album.to_dict()]}
json_dict = {'id_': self.id}
track = Track.de_json(json_dict, client)
assert track.id == self.id
assert track.title == self.title
assert track.available == self.available
assert track.artists == [artist]
assert track.albums == [album]
def test_de_json_all(self, client, artist, album, major, normalization):
json_dict = {'id_': self.id, 'title': self.title, 'available': self.available,
'available_for_premium_users': self.available_for_premium_users,
'artists': [artist.to_dict()], 'albums': [album.to_dict()],
'lyrics_available': self.lyrics_available, 'real_id': self.real_id,
'lyrics_available': self.lyrics_available, 'best': self.best, 'real_id': self.real_id,
'og_image': self.og_image, 'type_': self.type, 'cover_uri': self.cover_uri,
'major': major.to_dict(), 'duration_ms': self.duration_ms, 'storage_dir': self.storage_dir,
'file_size': self.file_size, 'normalization': normalization.to_dict(), 'error': self.error,
@ -90,6 +87,7 @@ class TestTrack:
assert track.artists == [artist]
assert track.albums == [album]
assert track.lyrics_available == self.lyrics_available
assert track.best == self.best
assert track.real_id == self.real_id
assert track.og_image == self.og_image
assert track.type == self.type
@ -109,10 +107,10 @@ class TestTrack:
assert track.version == self.version
assert track.remember_position == self.remember_position
def test_equality(self, artist, album):
a = Track(self.id, self.title, self.available, [artist], [album])
b = Track(self.id, '', self.available, [artist], [])
c = Track(self.id, self.title, self.available, [artist], [album])
def test_equality(self):
a = Track(self.id)
b = Track(10)
c = Track(self.id)
assert a != b
assert hash(a) != hash(b)

ファイルの表示

@ -8,6 +8,8 @@ class TestVinyl:
year = 2005
media = '2 Грампластинка (LP)'
price = 4483
offer_id = 28640019
artist_ids = [4, 24326, 618511, 2643503]
def test_expected_values(self, vinyl):
assert vinyl.url == self.url
@ -16,6 +18,8 @@ class TestVinyl:
assert vinyl.year == self.year
assert vinyl.price == self.price
assert vinyl.media == self.media
assert vinyl.offer_id == self.offer_id
assert vinyl.artist_ids == self.artist_ids
def test_de_json_none(self, client):
assert Vinyl.de_json({}, client) is None
@ -24,7 +28,8 @@ class TestVinyl:
assert Vinyl.de_list({}, client) == []
def test_de_json_required(self, client):
json_dict = {'url': self.url, 'title': self.title, 'year': self.year, 'price': self.price, 'media': self.media}
json_dict = {'url': self.url, 'title': self.title, 'year': self.year, 'price': self.price, 'media': self.media,
'offer_id': self.offer_id, 'artist_ids': self.artist_ids}
vinyl = Vinyl.de_json(json_dict, client)
assert vinyl.url == self.url
@ -32,10 +37,12 @@ class TestVinyl:
assert vinyl.year == self.year
assert vinyl.price == self.price
assert vinyl.media == self.media
assert vinyl.offer_id == self.offer_id
assert vinyl.artist_ids == self.artist_ids
def test_de_json_all(self, client):
json_dict = {'url': self.url, 'picture': self.picture, 'title': self.title, 'year': self.year,
'price': self.price, 'media': self.media}
'price': self.price, 'media': self.media, 'offer_id': self.offer_id, 'artist_ids': self.artist_ids}
vinyl = Vinyl.de_json(json_dict, client)
assert vinyl.url == self.url
@ -44,11 +51,13 @@ class TestVinyl:
assert vinyl.year == self.year
assert vinyl.price == self.price
assert vinyl.media == self.media
assert vinyl.offer_id == self.offer_id
assert vinyl.artist_ids == self.artist_ids
def test_equality(self):
a = Vinyl(self.url, self.title, 2020, 200, self.media, self.picture)
b = Vinyl(self.url, self.title, self.year, self.price, self.media, self.picture)
c = Vinyl(self.url, self.title, self.year, self.price, self.media, self.picture)
a = Vinyl(self.url, self.title, 2020, 200, self.media, self.offer_id, [10])
b = Vinyl(self.url, self.title, self.year, self.price, self.media, self.offer_id, self.artist_ids)
c = Vinyl(self.url, self.title, self.year, self.price, self.media, self.offer_id, self.artist_ids)
assert a != b
assert hash(a) != hash(b)

ファイルの表示

@ -12,6 +12,7 @@ from .account.subscription import Subscription
from .account.price import Price
from .account.product import Product
from .account.auto_renewable import AutoRenewable
from .account.renewable_remainder import RenewableRemainder
from .account.passport_phone import PassportPhone
from .account.permissions import Permissions
@ -118,4 +119,4 @@ __all__ = ['YandexMusicObject', 'Client', 'Account', 'PassportPhone', 'Invocatio
'Dashboard', 'RotorSettings', 'AdParams', 'Restrictions', 'Value', 'Enum', 'DiscreteScale', 'StationResult',
'Sequence', 'StationTracksResult', 'BriefInfo', 'Description', 'PlaylistId', 'Vinyl', 'Supplement', 'Lyrics',
'VideoSupplement', 'ArtistTracks', 'Pager', 'ArtistAlbums', 'PlaylistAbsence', 'Shot', 'ShotEvent',
'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings']
'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings', 'RenewableRemainder']

ファイルの表示

@ -18,6 +18,7 @@ class Product(YandexMusicObject):
price (:obj:`yandex_music.Price`): Цена.
feature (:obj:`str`): Предоставляемая возможность.
debug (:obj:`bool`): Отладочный продукт.
plus (:obj:`bool`): Даёт ли подписку "Плюс".
features (:obj:`list` из :obj:`str`): Список предоставляемых возможностей.
description (:obj:`str`): Описание.
available (:obj:`bool`): Доступна ли покупка.
@ -37,6 +38,7 @@ class Product(YandexMusicObject):
price (:obj:`yandex_music.Price`): Цена.
feature (:obj:`str`): Предоставляемая возможность.
debug (:obj:`bool`): Отладочный продукт.
plus (:obj:`bool`): Даёт ли подписку "Плюс".
features (:obj:`list` из :obj:`str`, optional): Список предоставляемых возможностей.
description (:obj:`str`, optional): Описание.
available (:obj:`bool`, optional): Доступна ли покупка.
@ -58,6 +60,7 @@ class Product(YandexMusicObject):
price: Optional['Price'],
feature: str,
debug: bool,
plus: bool,
features: List[str] = None,
description: Optional[str] = None,
available: Optional[bool] = None,
@ -78,6 +81,7 @@ class Product(YandexMusicObject):
self.price = price
self.feature = feature
self.debug = debug
self.plus = plus
self.features = features
self.description = description

49
yandex_music/account/renewable_remainder.py ノーマルファイル
ファイルの表示

@ -0,0 +1,49 @@
from typing import TYPE_CHECKING, Optional
from yandex_music import YandexMusicObject
if TYPE_CHECKING:
from yandex_music import Client
class RenewableRemainder(YandexMusicObject):
"""Класс, представляющий напоминания о продлении подписки.
Attributes:
days (:obj:`int`): Количество дней (до окончания подписки, по всей видимости).
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
Args:
days (:obj:`int`): Количество дней (до окончания подписки, по всей видимости).
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
**kwargs: Произвольные ключевые аргументы полученные от API.
"""
def __init__(self,
days: int,
client: Optional['Client'] = None,
**kwargs) -> None:
super().handle_unknown_kwargs(self, **kwargs)
self.days = days
self.client = client
self._id_attrs = (self.days,)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['RenewableRemainder']:
"""Десериализация объекта.
Args:
data (:obj:`dict`): Поля и значения десериализуемого объекта.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
Returns:
:obj:`yandex_music.PassportPhone`: Напоминание о продлении подписки.
"""
if not data:
return None
data = super(RenewableRemainder, cls).de_json(data, client)
return cls(client=client, **data)

ファイルの表示

@ -12,6 +12,7 @@ class Status(YandexMusicObject):
Attributes:
account (:obj:`yandex_music.Account`): Основная информация об аккаунте.
permissions (:obj:`yandex_music.Permissions`): Информация о правах пользователя.
advertisement (:obj:`str`): Рекламное объявление.
subscription (:obj:`yandex_music.Subscription`): Информация о подписках.
cache_limit (:obj:`int`): Максимальное количество загруженных треков.
subeditor (:obj:`bool`): Наличие статуса модератора проверки корректности информации.
@ -26,7 +27,8 @@ class Status(YandexMusicObject):
Args:
account (:obj:`yandex_music.Account`): Основная информация об аккаунте
permissions (:obj:`yandex_music.Permissions`): Информация о правах пользователя.
subscription (:obj:`yandex_music.Subscription`): Информация о подписках.
advertisement (:obj:`str`): Рекламное объявление.
subscription (:obj:`yandex_music.Subscription`, optional): Информация о подписках.
cache_limit (:obj:`int`, optional): Максимальное количество загруженных треков.
subeditor (:obj:`bool`, optional): Наличие статуса модератора проверки корректности информации.
subeditor_level (:obj:`int`, optional): Уровень статуса модератора.
@ -42,6 +44,7 @@ class Status(YandexMusicObject):
def __init__(self,
account: Optional['Account'],
permissions: Optional['Permissions'],
advertisement: str,
subscription: Optional['Subscription'] = None,
cache_limit: Optional[int] = None,
subeditor: Optional[bool] = None,
@ -57,6 +60,7 @@ class Status(YandexMusicObject):
self.account = account
self.permissions = permissions
self.advertisement = advertisement
self.subscription = subscription
self.cache_limit = cache_limit
@ -69,7 +73,7 @@ class Status(YandexMusicObject):
self.premium_region = premium_region
self.client = client
self._id_attrs = (self.account, self.permissions)
self._id_attrs = (self.account, self.permissions, self.advertisement)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['Status']:

ファイルの表示

@ -3,13 +3,14 @@ from typing import TYPE_CHECKING, Optional, List
from yandex_music import YandexMusicObject
if TYPE_CHECKING:
from yandex_music import Client, AutoRenewable
from yandex_music import Client, AutoRenewable, RenewableRemainder
class Subscription(YandexMusicObject):
"""Класс, представляющий информацию о подписках пользователя.
Attributes:
non_auto_renewable_remainder (:obj:yandex_music.RenewableRemainder`): Напоминание о продлении.
auto_renewable (:obj:`list` из :obj:`yandex_music.AutoRenewable`): Автопродление.
can_start_trial (:obj:`bool`): Есть ли возможность начать пробный период.
mcdonalds (:obj:`bool`): mcdonalds TODO.
@ -17,6 +18,7 @@ class Subscription(YandexMusicObject):
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
Args:
non_auto_renewable_remainder (:obj:yandex_music.RenewableRemainder`): Напоминание о продлении.
auto_renewable (:obj:`list` из :obj:`yandex_music.AutoRenewable`, optional): Автопродление.
can_start_trial (:obj:`bool`, optional): Есть ли возможность начать пробный период.
mcdonalds (:obj:`bool`, optional): mcdonalds TODO.
@ -26,7 +28,8 @@ class Subscription(YandexMusicObject):
"""
def __init__(self,
auto_renewable: List['AutoRenewable'] = None,
non_auto_renewable_remainder: 'RenewableRemainder',
auto_renewable: List['AutoRenewable'],
can_start_trial: Optional[bool] = None,
mcdonalds: Optional[bool] = None,
end: Optional[str] = None,
@ -34,13 +37,14 @@ class Subscription(YandexMusicObject):
**kwargs) -> None:
super().handle_unknown_kwargs(self, **kwargs)
self.non_auto_renewable_remainder = non_auto_renewable_remainder
self.auto_renewable = auto_renewable
self.can_start_trial = can_start_trial
self.mcdonalds = mcdonalds
self.end = end
self.client = client
self._id_attrs = (self.auto_renewable,)
self._id_attrs = (self.non_auto_renewable_remainder, self.auto_renewable)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['Subscription']:
@ -57,7 +61,9 @@ class Subscription(YandexMusicObject):
return None
data = super(Subscription, cls).de_json(data, client)
from yandex_music import AutoRenewable
from yandex_music import AutoRenewable, RenewableRemainder
data['auto_renewable'] = AutoRenewable.de_list(data.get('auto_renewable'), client)
data['non_auto_renewable_remainder'] = RenewableRemainder.de_json(
data.get('non_auto_renewable_remainder'), client)
return cls(client=client, **data)

ファイルの表示

@ -16,6 +16,8 @@ class Album(YandexMusicObject):
Известные ошибки: `not-found` - альбом с таким ID не существует.
Известные значения поля `meta_type`: `music`.
Attributes:
id (:obj:`int`): Идентификатор альбома.
error (:obj:`str`): Ошибка получения альбома.
@ -56,6 +58,7 @@ class Album(YandexMusicObject):
cover_uri (:obj:`str`, optional): Ссылка на обложку.
content_warning (:obj:`str`, optional): Предупреждение о содержимом альбома.
genre (:obj:`str`, optional): Жанр музыки.
meta_type (:obj:`str`, optional): Мета тип TODO.
og_image (:obj:`str`, optional): Ссылка на превью Open Graph.
recent (:obj:`bool`, optional): Является ли альбом новым.
very_important (:obj:`bool`, optional): Популярен ли альбом у слушателей.
@ -86,6 +89,7 @@ class Album(YandexMusicObject):
content_warning: Optional[str] = None,
original_release_year=None,
genre: Optional[str] = None,
meta_type: Optional[str] = None,
og_image: Optional[str] = None,
buy: Optional[list] = None,
recent: Optional[bool] = None,
@ -116,6 +120,7 @@ class Album(YandexMusicObject):
self.version = version
self.cover_uri = cover_uri
self.genre = genre
self.meta_type = meta_type
self.year = year
self.release_date = release_date
self.bests = bests

ファイルの表示

@ -11,12 +11,13 @@ class Artist(YandexMusicObject):
Attributes:
id (:obj:`int`): Уникальный идентификатор.
error (:obj:`str`): Сообщение об ошибке.
reason (:obj:`str`): Причина отсутствия исполнителя (сообщение об ошибке).
name (:obj:`str`): Название.
cover (:obj:`yandex_music.Cover` | :obj:`None`): Обложка.
various (:obj:`bool`): TODO.
composer (:obj:`bool`): TODO.
genres (:obj:`list` из :obj:`str`): Жанры.
og_image (:obj:`str`, optional): Ссылка на изображение для Open Graph.
op_image (:obj:`str`): Ссылка на изображение обложки. Используется когда не указано поле cover.
no_pictures_from_search: TODO.
counts (:obj:`yandex_music.Counts` | :obj:`None`): Счётчики.
@ -40,12 +41,13 @@ class Artist(YandexMusicObject):
Args:
id_ (:obj:`int`): Уникальный идентификатор.
error (:obj:`str`, optional): Сообщение об ошибке.
reason (:obj:`str`, optional): Причина отсутствия исполнителя (сообщение об ошибке).
name (:obj:`str`, optional): Название.
cover (:obj:`yandex_music.Cover`, optional): Обложка.
various (:obj:`bool`, optional): TODO.
composer (:obj:`bool`, optional): TODO.
genres (:obj:`list` из :obj:`str`, optional): Жанры.
og_image (:obj:`str`, optional): Ссылка на изображение для Open Graph.
op_image (:obj:`str`, optional): Ссылка на изображение обложки. Используется когда не указано поле cover.
no_pictures_from_search: TODO.
counts (:obj:`yandex_music.Counts`, optional): Счётчики.
@ -71,12 +73,13 @@ class Artist(YandexMusicObject):
def __init__(self,
id_: int,
error: Optional[str] = None,
reason: Optional[str] = None,
name: Optional[str] = None,
cover: Optional['Cover'] = None,
various: Optional[bool] = None,
composer: Optional[bool] = None,
genres: Optional[List[str]] = None,
og_image: Optional[str] = None,
op_image: Optional[str] = None,
no_pictures_from_search=None,
counts: Optional['Counts'] = None,
@ -102,12 +105,13 @@ class Artist(YandexMusicObject):
self.id = id_
self.error = error
self.reason = reason
self.name = name
self.cover = cover
self.various = various
self.composer = composer
self.genres = genres
self.og_image = og_image
self.op_image = op_image
self.no_pictures_from_search = no_pictures_from_search
self.counts = counts
@ -133,10 +137,20 @@ class Artist(YandexMusicObject):
self.client = client
self._id_attrs = (self.id, self.name, self.cover)
def download_og_image(self, filename: str, size: str = '200x200') -> None:
"""Загрузка изображения для Open Graph.
Args:
filename (:obj:`str`): Путь для сохранения файла с названием и расширением.
size (:obj:`str`, optional): Размер обложки.
"""
self.client.request.download(f'https://{self.og_image.replace("%%", size)}', filename)
def download_op_image(self, filename: str, size: str = '200x200') -> None:
"""Загрузка обложки.
Используйте это только когда нет self.cover!
Notes:
Используйте это только когда нет self.cover!
Args:
filename (:obj:`str`): Путь для сохранения файла с названием и расширением.
@ -220,6 +234,8 @@ class Artist(YandexMusicObject):
# camelCase псевдонимы
#: Псевдоним для :attr:`download_og_image`
downloadOgImage = download_og_image
#: Псевдоним для :attr:`download_op_image`
downloadOpImage = download_op_image
#: Псевдоним для :attr:`get_tracks`

ファイルの表示

@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Optional, List
from yandex_music import YandexMusicObject
if TYPE_CHECKING:
from yandex_music import Client, Artist, Track, Album, Cover, PlaylistId, Video, Chart, Vinyl
from yandex_music import Client, Artist, Track, Album, Cover, PlaylistId, Video, Chart, Vinyl, Playlist
class BriefInfo(YandexMusicObject):
@ -12,6 +12,7 @@ class BriefInfo(YandexMusicObject):
Attributes:
artist (:obj:`yandex_music.Artist` | :obj:`None`): Артист.
albums (:obj:`list` из :obj:`yandex_music.Album`): Альбомы.
playlists (:obj:`list` из :obj:`yandex_music.Playlist`): Плейлисты.
also_albums (:obj:`list` из :obj:`yandex_music.Album`): Сборники.
last_release_ids (:obj:`list` из :obj:`int`): Уникальные идентификаторы последних выпущенных треков.
popular_tracks (:obj:`list` из :obj:`yandex_music.Track`): Популярные треки.
@ -28,6 +29,7 @@ class BriefInfo(YandexMusicObject):
Args:
artist (:obj:`yandex_music.Artist` | :obj:`None`): Артист.
albums (:obj:`list` из :obj:`yandex_music.Album`): Альбомы.
playlists (:obj:`list` из :obj:`yandex_music.Playlist`): Плейлисты.
also_albums (:obj:`list` из :obj:`yandex_music.Album`): Сборники.
last_release_ids (:obj:`list` из :obj:`int`): Уникальные идентификаторы последних выпущенных треков.
popular_tracks (:obj:`list` из :obj:`yandex_music.Track`): Популярные треки.
@ -46,6 +48,7 @@ class BriefInfo(YandexMusicObject):
def __init__(self,
artist: Optional['Artist'],
albums: List['Album'],
playlists: List['Playlist'],
also_albums: List['Album'],
last_release_ids: List[int],
popular_tracks: List['Track'],
@ -63,6 +66,7 @@ class BriefInfo(YandexMusicObject):
self.artist = artist
self.albums = albums
self.playlists = playlists
self.also_albums = also_albums
self.last_release_ids = last_release_ids
self.popular_tracks = popular_tracks
@ -77,9 +81,9 @@ class BriefInfo(YandexMusicObject):
self.tracks_in_chart = tracks_in_chart
self.client = client
self._id_attrs = (self.artist, self.albums, self.also_albums, self.last_release_ids, self.popular_tracks,
self.similar_artists, self.all_covers, self.concerts, self.videos, self.vinyls,
self.has_promotions, self.playlist_ids)
self._id_attrs = (self.artist, self.albums, self.playlists, self.also_albums, self.last_release_ids,
self.popular_tracks, self.similar_artists, self.all_covers, self.concerts, self.videos,
self.vinyls, self.has_promotions, self.playlist_ids)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['BriefInfo']:
@ -96,7 +100,8 @@ class BriefInfo(YandexMusicObject):
return None
data = super(BriefInfo, cls).de_json(data, client)
from yandex_music import Artist, Track, Album, Cover, PlaylistId, Video, Chart, Vinyl
from yandex_music import Artist, Track, Album, Cover, PlaylistId, Video, Chart, Vinyl, Playlist
data['playlists'] = Playlist.de_list(data.get('playlists'), client)
data['artist'] = Artist.de_json(data.get('artist'), client)
data['similar_artists'] = Artist.de_list(data.get('similar_artists'), client)
data['popular_tracks'] = Track.de_list(data.get('popular_tracks'), client)

ファイルの表示

@ -15,6 +15,8 @@ class Vinyl(YandexMusicObject):
year (:obj:`int`): Год выпуска.
price (:obj:`int`): Цена.
media (:obj:`str`): Средство распространения.
offer_id (:obj:`int`): Уникальный идентификатор предложения.
artist_ids (:obj:`list` из :obj:`int`): Перечень уникальный идентификаторов исполнителей.
picture (:obj:`str`): Ссылка на обложку.
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
@ -24,6 +26,8 @@ class Vinyl(YandexMusicObject):
year (:obj:`int`): Год выпуска.
price (:obj:`int`): Цена.
media (:obj:`str`): Средство распространения.
offer_id (:obj:`int`): Уникальный идентификатор предложения.
artist_ids (:obj:`list` из :obj:`int`): Перечень уникальный идентификаторов исполнителей.
picture (:obj:`str`, optional): Ссылка на обложку.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
**kwargs: Произвольные ключевые аргументы полученные от API.
@ -35,6 +39,8 @@ class Vinyl(YandexMusicObject):
year: int,
price: int,
media: str,
offer_id: int,
artist_ids: List[int],
picture: Optional[str] = None,
client: Optional['Client'] = None,
**kwargs) -> None:
@ -46,9 +52,12 @@ class Vinyl(YandexMusicObject):
self.year = year
self.price = price
self.media = media
self.offer_id = offer_id
self.artist_ids = artist_ids
self.client = client
self._id_attrs = (self.title, self.price, self.year, self.url, self.price, self.media)
self._id_attrs = (self.title, self.price, self.year, self.url, self.price,
self.media, self.offer_id, self.artist_ids)
@classmethod
def de_json(cls, data: dict, client: 'Client') -> Optional['Vinyl']:

ファイルの表示

@ -15,6 +15,7 @@ class Cover(YandexMusicObject):
items_uri (:obj:`str`): Список ссылок на изображения.
dir (:obj:`str`): Директория хранения изображения на сервере.
version (:obj:`str`): Версия.
is_custom (:obj:`bool`): Является ли обложка пользовательской.
custom (:obj:`bool`): Является ли обложка пользовательской.
prefix (:obj:`str`): Уникальный идентификатор.
error (:obj:`str`): Сообщение об ошибке.
@ -26,6 +27,7 @@ class Cover(YandexMusicObject):
items_uri (:obj:`str`, optional): Список ссылок на изображения.
dir_ (:obj:`str`, optional): Директория хранения изображения на сервере.
version (:obj:`str`, optional): Версия.
is_custom (:obj:`bool`, optional): Является ли обложка пользовательской.
custom (:obj:`bool`, optional): Является ли обложка пользовательской.
prefix (:obj:`str`, optional): Уникальный идентификатор.
error (:obj:`str`, optional): Сообщение об ошибке.
@ -40,6 +42,7 @@ class Cover(YandexMusicObject):
dir_: Optional[str] = None,
version: Optional[str] = None,
custom: Optional[bool] = None,
is_custom: Optional[bool] = None,
prefix: Optional[str] = None,
error: Optional[str] = None,
client: Optional['Client'] = None,
@ -53,6 +56,7 @@ class Cover(YandexMusicObject):
self.dir = dir_
self.version = version
self.custom = custom
self.is_custom = is_custom
self.error = error
self.client = client

ファイルの表示

@ -23,6 +23,7 @@ class Track(YandexMusicObject):
albums (:obj:`list` из :obj:`yandex_music.Album`): Альбомы.
available_for_premium_users (:obj:`bool`): Доступен ли для пользователей с подпиской.
lyrics_available (:obj:`bool`): Доступен ли текст песни.
best (:obj:`bool`): Лучшей ли трек TODO.
real_id (:obj:`int` | :obj:`str`): TODO.
og_image (:obj:`str`): Ссылка на превью Open Graph.
type (:obj:`str`): Тип.
@ -52,6 +53,7 @@ class Track(YandexMusicObject):
albums (:obj:`list` из :obj:`yandex_music.Album`, optional): Альбомы.
available_for_premium_users (:obj:`bool`, optional): Доступен ли для пользователей с подпиской.
lyrics_available (:obj:`bool`, optional): Доступен ли текст песни.
best (:obj:`bool`, optional): Лучшей ли трек TODO.
real_id (:obj:`int` | :obj:`str`, optional): TODO.
og_image (:obj:`str`, optional): Ссылка на превью Open Graph.
type_ (:obj:`str`, optional): Тип.
@ -82,6 +84,7 @@ class Track(YandexMusicObject):
albums: List['Album'] = None,
available_for_premium_users: Optional[bool] = None,
lyrics_available: Optional[bool] = None,
best: Optional[bool] = None,
real_id: Optional[Union[str, int]] = None,
og_image: Optional[str] = None,
type_: Optional[str] = None,
@ -105,13 +108,14 @@ class Track(YandexMusicObject):
super().handle_unknown_kwargs(self, **kwargs)
self.id = id_
self.title = title
self.available = available
self.artists = artists
self.albums = albums
self.available_for_premium_users = available_for_premium_users
self.lyrics_available = lyrics_available
self.best = best
self.real_id = real_id
self.og_image = og_image
self.type = type_
@ -134,7 +138,7 @@ class Track(YandexMusicObject):
self.download_info = None
self.client = client
self._id_attrs = (self.id, self.title, self.available, self.artists, self.albums)
self._id_attrs = (self.id,)
def get_download_info(self, get_direct_links=False) -> List['DownloadInfo']:
"""Сокращение для::