New supported objects: Landing, Block, BlockEntity, Chart, ChartItem, MixLink, PersonalPlaylistsData, PlayContext, PlayContextsData, Promotion, TrackId, TrackShorOld (YEAH!)

The following method are wrapped:
- /landing3
Added the ability to download covers
The following field are optional: Playlist.tags
Now, when parsing json, the "client" key is replaced with "client_"
このコミットが含まれているのは:
Marshal 2019-05-24 20:10:39 +03:00
コミット 5cd9818c36
19個のファイルの変更444行の追加4行の削除

ファイルの表示

@ -57,6 +57,19 @@ from search.playlist_search_result import PlaylistSearchResult
from search.track_search_result import TrackSearchResult
from search.video_search_result import VideoSearchResult
from landing.chart_item import ChartItem
from landing.play_context import PlayContext
from landing.track_short_old import TrackShortOld
from landing.mix_link import MixLink
from landing.promotion import Promotion
from landing.block_entity import BlockEntity
from landing.landing import Landing
from landing.block import Block
from landing.track_id import TrackId
from landing.chart import Chart
from landing.play_contexts_data import PlayContextsData
from landing.personal_playlists_data import PersonalPlaylistsData
__all__ = ['YandexMusicObject', 'Account', 'PassportPhone', 'InvocationInfo', 'Permissions', 'Plus', 'Subscription',
'Status', 'Price', 'Product', 'AutoRenewable', 'Settings', 'PermissionAlerts', 'Experiments', 'Cover',
'Ratings', 'Counts', 'Link', 'Artist', 'User', 'CaseForms', 'MadeFor', 'Label', 'Album', 'PlayCounter',
@ -64,4 +77,5 @@ __all__ = ['YandexMusicObject', 'Account', 'PassportPhone', 'InvocationInfo', 'P
'ArtistsLikes', 'PlaylistsLikes', 'GeneratedPlaylist', 'TrackWithAds', 'Day', 'ArtistEvent', 'AlbumEvent',
'Feed', 'Event', 'PromoCodeStatus', 'DownloadInfo', 'Video', 'SearchResult', 'AlbumSearchResult', 'Best',
'ArtistSearchResult', 'PlaylistSearchResult', 'TrackSearchResult', 'VideoSearchResult', 'Search',
'Suggestions']
'Suggestions', 'MixLink', 'BlockEntity', 'Block', 'PlayContextsData', 'TrackId', 'TrackShortOld',
'PersonalPlaylistsData', 'Promotion', 'Landing', 'Chart', 'ChartItem', 'PlayContext']

ファイルの表示

@ -3,7 +3,7 @@ from datetime import datetime
from yandex_music import YandexMusicObject, Status, Settings, PermissionAlerts, Experiments, Artist, Album, Playlist, \
TracksLikes, Track, AlbumsLikes, ArtistsLikes, PlaylistsLikes, Feed, PromoCodeStatus, DownloadInfo, Search, \
Suggestions
Suggestions, Landing
from yandex_music.utils.request import Request
from yandex_music.exceptions import InvalidToken
@ -109,6 +109,13 @@ class Client(YandexMusicObject):
return Feed.de_json(result, self)
def landing(self, blocks: str or list, timeout=None, *args, **kwargs):
url = f'{self.base_url}/landing3'
result = self._request.get(url, {'blocks': blocks}, timeout=timeout, *args, **kwargs)
return Landing.de_json(result, self)
def tracks_download_info(self, track_id: str or int, get_direct_links=False, timeout=None, *args, **kwargs):
url = f'{self.base_url}/tracks/{track_id}/download-info'

ファイルの表示

@ -23,6 +23,9 @@ class Cover(YandexMusicObject):
self.client = client
def download(self, filename):
self.client._request.download(self.uri, filename)
@classmethod
def de_json(cls, data, client):
if not data:

0
yandex_music/landing/__init__.py ノーマルファイル
ファイルの表示

54
yandex_music/landing/block.py ノーマルファイル
ファイルの表示

@ -0,0 +1,54 @@
from yandex_music import YandexMusicObject
class Block(YandexMusicObject):
def __init__(self,
id,
type,
type_for_from,
title,
entities,
description=None,
data=None,
client=None,
**kwargs):
self.id = id
self.type = type
self.type_for_from = type_for_from
self.title = title
self.entities = entities
self.description = description
self.data = data
self.client = client
self._id_attrs = (self.id,)
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(Block, cls).de_json(data, client)
from yandex_music import BlockEntity, PlayContextsData, PersonalPlaylistsData
data['entities'] = BlockEntity.de_list(data.get('entities'), client)
block_type = data.get('type')
if block_type == 'personal-playlists':
data['data'] = PersonalPlaylistsData.de_json(data.get('data'), client)
elif block_type == 'play-contexts':
data['data'] = PlayContextsData.de_json(data.get('data'), client)
return cls(client=client, **data)
@classmethod
def de_list(cls, data, client):
if not data:
return []
blocks = list()
for block in data:
blocks.append(cls.de_json(block, client))
return blocks

49
yandex_music/landing/block_entity.py ノーマルファイル
ファイルの表示

@ -0,0 +1,49 @@
from yandex_music import YandexMusicObject, Promotion, Album, Playlist, MixLink, PlayContext, ChartItem, GeneratedPlaylist
de_json = {
'personal-playlist': GeneratedPlaylist.de_json,
'promotion': Promotion.de_json,
'album': Album.de_json,
'playlist': Playlist.de_json,
'chart-item': ChartItem.de_json,
'play-context': PlayContext.de_json,
'mix-link': MixLink.de_json
}
class BlockEntity(YandexMusicObject):
def __init__(self,
id,
type,
data,
client=None,
**kwargs):
self.id = id
self.type = type
self.data = data
self.client = client
self._id_attrs = (self.id,)
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(BlockEntity, cls).de_json(data, client)
data['data'] = de_json.get(data.get('type'))(data.get('data'), client)
return cls(client=client, **data)
@classmethod
def de_list(cls, data, client):
if not data:
return []
entities = list()
for entity in data:
entities.append(cls.de_json(entity, client))
return entities

26
yandex_music/landing/chart.py ノーマルファイル
ファイルの表示

@ -0,0 +1,26 @@
from yandex_music import YandexMusicObject
class Chart(YandexMusicObject):
def __init__(self,
position,
progress,
listeners,
shift,
client=None,
**kwargs):
self.position = position
self.progress = progress
self.listeners = listeners
self.shift = shift
self.client = client
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(Chart, cls).de_json(data, client)
return cls(client=client, **data)

36
yandex_music/landing/chart_item.py ノーマルファイル
ファイルの表示

@ -0,0 +1,36 @@
from yandex_music import YandexMusicObject
class ChartItem(YandexMusicObject):
def __init__(self,
track,
chart,
client=None,
**kwargs):
self.track = track
self.chart = chart
self.client = client
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(ChartItem, cls).de_json(data, client)
from yandex_music import Chart, Track
data['track'] = Track.de_json(data.get('track'), client)
data['chart'] = Chart.de_json(data.get('chart'), client)
return cls(client=client, **data)
@classmethod
def de_list(cls, data, client):
if not data:
return []
tracks = list()
for track in data:
tracks.append(cls.de_json(track, client))
return tracks

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

@ -0,0 +1,28 @@
from yandex_music import YandexMusicObject
class Landing(YandexMusicObject):
def __init__(self,
pumpkin,
content_id,
blocks,
client=None,
**kwargs):
self.pumpkin = pumpkin
self.content_id = content_id
self.blocks = blocks
self.client = client
self._id_attrs = (self.content_id,)
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(Landing, cls).de_json(data, client)
from yandex_music import Block
data['blocks'] = Block.de_list(data.get('blocks'), client)
return cls(client=client, **data)

43
yandex_music/landing/mix_link.py ノーマルファイル
ファイルの表示

@ -0,0 +1,43 @@
from yandex_music import YandexMusicObject
class MixLink(YandexMusicObject):
def __init__(self,
title,
url,
url_scheme,
text_color,
background_color,
background_image_uri,
cover_white,
client=None,
**kwargs):
self.title = title
self.url = url
self.url_scheme = url_scheme
self.text_color = text_color
self.background_color = background_color
self.background_image_uri = background_image_uri
self.cover_white = cover_white
self.client = client
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(MixLink, cls).de_json(data, client)
return cls(client=client, **data)
@classmethod
def de_list(cls, data, client):
if not data:
return []
mix_links = list()
for mix_link in data:
mix_links.append(cls.de_json(mix_link, client))
return mix_links

ファイルの表示

@ -0,0 +1,20 @@
from yandex_music import YandexMusicObject
class PersonalPlaylistsData(YandexMusicObject):
def __init__(self,
is_wizard_passed,
client=None,
**kwargs):
self.is_wizard_passed = is_wizard_passed
self.client = client
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(PersonalPlaylistsData, cls).de_json(data, client)
return cls(client=client, **data)

28
yandex_music/landing/play_context.py ノーマルファイル
ファイルの表示

@ -0,0 +1,28 @@
from yandex_music import YandexMusicObject
class PlayContext(YandexMusicObject):
def __init__(self,
client_,
context,
context_item,
tracks,
client=None,
**kwargs):
self.client_ = client_
self.context = context
self.context_item = context_item
self.tracks = tracks
self.client = client
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(PlayContext, cls).de_json(data, client)
from yandex_music import TrackShortOld
data['tracks'] = TrackShortOld.de_list(data.get('tracks'), client)
return cls(client=client, **data)

22
yandex_music/landing/play_contexts_data.py ノーマルファイル
ファイルの表示

@ -0,0 +1,22 @@
from yandex_music import YandexMusicObject
class PlayContextsData(YandexMusicObject):
def __init__(self,
other_tracks,
client=None,
**kwargs):
self.other_tracks = other_tracks
self.client = client
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(PlayContextsData, cls).de_json(data, client)
from yandex_music import TrackShortOld
data['other_tracks'] = TrackShortOld.de_list(data.get('other_tracks'), client)
return cls(client=client, **data)

47
yandex_music/landing/promotion.py ノーマルファイル
ファイルの表示

@ -0,0 +1,47 @@
from yandex_music import YandexMusicObject
class Promotion(YandexMusicObject):
def __init__(self,
promo_id,
title,
subtitle,
heading,
url,
url_scheme,
text_color,
gradient,
image,
client=None,
**kwargs):
self.promo_id = promo_id
self.title = title
self.subtitle = subtitle
self.heading = heading
self.url = url
self.url_scheme = url_scheme
self.text_color = text_color
self.gradient = gradient
self.image = image
self.client = client
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(Promotion, cls).de_json(data, client)
return cls(client=client, **data)
@classmethod
def de_list(cls, data, client):
if not data:
return []
promotions = list()
for promotion in data:
promotions.append(cls.de_json(promotion, client))
return promotions

23
yandex_music/landing/track_id.py ノーマルファイル
ファイルの表示

@ -0,0 +1,23 @@
from yandex_music import YandexMusicObject
class TrackId(YandexMusicObject):
def __init__(self,
id,
album_id,
client=None,
**kwargs):
self.id = id
self.album_id = album_id
self.client = client
self._id_attrs = (self.id,)
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(TrackId, cls).de_json(data, client)
return cls(client=client, **data)

36
yandex_music/landing/track_short_old.py ノーマルファイル
ファイルの表示

@ -0,0 +1,36 @@
from yandex_music import YandexMusicObject
class TrackShortOld(YandexMusicObject):
def __init__(self,
track_id,
timestamp,
client=None,
**kwargs):
self.track_id = track_id
self.timestamp = timestamp
self.client = client
self._id_attrs = (self.track_id,)
@classmethod
def de_json(cls, data, client):
if not data:
return None
data = super(TrackShortOld, cls).de_json(data, client)
from yandex_music import TrackId
data['track_id'] = TrackId.de_json(data.get('track_id'), client)
return cls(client=client, **data)
@classmethod
def de_list(cls, data, client):
if not data:
return []
tracks = list()
for track in data:
tracks.append(cls.de_json(track, client))
return tracks

ファイルの表示

@ -11,9 +11,9 @@ class Playlist(YandexMusicObject):
title,
track_count,
cover,
tags,
made_for,
play_counter,
tags=None,
revision=None,
snapshot=None,
visibility=None,
@ -42,7 +42,6 @@ class Playlist(YandexMusicObject):
self.title = title
self.track_count = track_count
self.cover = cover
self.tags = tags
self.made_for = made_for
self.play_counter = play_counter
@ -66,6 +65,7 @@ class Playlist(YandexMusicObject):
self.generated_playlist_type = generated_playlist_type
self.is_for_from = is_for_from
self.regions = regions
self.tags = tags
self.client = client
self._id_attrs = (self.uid,)

ファイルの表示

@ -59,6 +59,9 @@ class Track(YandexMusicObject):
return self.download_info
def download_cover(self, filename):
self.client._request.download(self.cover_uri, filename)
def download(self, filename, codec='mp3', bitrate_in_kbps=192):
if self.download_info is None:
self.get_download_info()

ファイルの表示

@ -45,6 +45,7 @@ class Request(object):
cleaned_object = {}
for key, value in obj.items():
key = Request._convert_camel_to_snake(key.replace('-', '_'))
key = key.replace('client', 'client_')
cleaned_object.update({key: value})
return cleaned_object