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_"
このコミットが含まれているのは:
コミット
5cd9818c36
|
@ -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,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
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
||||
|
|
読み込み中…
新しいイシューから参照