Рекомендуемые треки для плейлиста
このコミットが含まれているのは:
コミット
e19b206f3d
|
@ -0,0 +1,7 @@
|
||||||
|
yandex_music.PlaylistRecommendations
|
||||||
|
====================================
|
||||||
|
|
||||||
|
.. autoclass:: yandex_music.PlaylistRecommendations
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
|
@ -10,5 +10,6 @@
|
||||||
yandex_music.playlist.playlist
|
yandex_music.playlist.playlist
|
||||||
yandex_music.playlist.case_forms
|
yandex_music.playlist.case_forms
|
||||||
yandex_music.playlist.playlist_id
|
yandex_music.playlist.playlist_id
|
||||||
|
yandex_music.playlist.playlist_recommendations
|
||||||
yandex_music.playlist.tag_result
|
yandex_music.playlist.tag_result
|
||||||
yandex_music.playlist.tag
|
yandex_music.playlist.tag
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from yandex_music import PlaylistRecommendations
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='class')
|
||||||
|
def playlist_recommendations(track):
|
||||||
|
return PlaylistRecommendations([track], TestPlaylistRecommendations.batch_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestPlaylistRecommendations:
|
||||||
|
batch_id = '1588835234913188-6341822935848536902'
|
||||||
|
|
||||||
|
def test_expected_values(self, playlist_recommendations, track):
|
||||||
|
assert playlist_recommendations.batch_id == self.batch_id
|
||||||
|
assert playlist_recommendations.tracks == [track]
|
||||||
|
|
||||||
|
def test_de_json_none(self, client):
|
||||||
|
assert PlaylistRecommendations.de_json({}, client) is None
|
||||||
|
|
||||||
|
def test_de_json_required(self, client, track):
|
||||||
|
json_dict = {'tracks': [track.to_dict()]}
|
||||||
|
playlist_recommendations = PlaylistRecommendations.de_json(json_dict, client)
|
||||||
|
|
||||||
|
assert playlist_recommendations.tracks == [track]
|
||||||
|
|
||||||
|
def test_de_json_all(self, client, track):
|
||||||
|
json_dict = {'batch_id': self.batch_id, 'tracks': [track.to_dict()]}
|
||||||
|
playlist_recommendations = PlaylistRecommendations.de_json(json_dict, client)
|
||||||
|
|
||||||
|
assert playlist_recommendations.batch_id == self.batch_id
|
||||||
|
assert playlist_recommendations.tracks == [track]
|
||||||
|
|
||||||
|
def test_equality(self, track):
|
||||||
|
a = PlaylistRecommendations([track])
|
||||||
|
b = PlaylistRecommendations([])
|
||||||
|
c = PlaylistRecommendations([track])
|
||||||
|
|
||||||
|
assert a != b
|
||||||
|
assert hash(a) != hash(b)
|
||||||
|
assert a is not b
|
||||||
|
|
||||||
|
assert a == c
|
|
@ -38,6 +38,7 @@ from .playlist.tag import Tag
|
||||||
from .playlist.tag_result import TagResult
|
from .playlist.tag_result import TagResult
|
||||||
from .playlist.playlist_absence import PlaylistAbsence
|
from .playlist.playlist_absence import PlaylistAbsence
|
||||||
from .playlist.playlist import Playlist
|
from .playlist.playlist import Playlist
|
||||||
|
from .playlist.playlist_recommendation import PlaylistRecommendations
|
||||||
|
|
||||||
from .shot.shot_type import ShotType
|
from .shot.shot_type import ShotType
|
||||||
from .shot.shot_data import ShotData
|
from .shot.shot_data import ShotData
|
||||||
|
@ -125,4 +126,4 @@ __all__ = ['YandexMusicObject', 'Client', 'Account', 'PassportPhone', 'Invocatio
|
||||||
'Sequence', 'StationTracksResult', 'BriefInfo', 'Description', 'PlaylistId', 'Vinyl', 'Supplement', 'Lyrics',
|
'Sequence', 'StationTracksResult', 'BriefInfo', 'Description', 'PlaylistId', 'Vinyl', 'Supplement', 'Lyrics',
|
||||||
'VideoSupplement', 'ArtistTracks', 'Pager', 'ArtistAlbums', 'PlaylistAbsence', 'Shot', 'ShotEvent',
|
'VideoSupplement', 'ArtistTracks', 'Pager', 'ArtistAlbums', 'PlaylistAbsence', 'Shot', 'ShotEvent',
|
||||||
'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings', 'RenewableRemainder', 'ChartInfo', 'ChartInfoMenu',
|
'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings', 'RenewableRemainder', 'ChartInfo', 'ChartInfoMenu',
|
||||||
'ChartInfoMenuItem', 'Tag', 'TagResult']
|
'ChartInfoMenuItem', 'Tag', 'TagResult', 'PlaylistRecommendations']
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Callable, Dict, List, Optional, Union
|
||||||
from yandex_music import Album, Artist, ArtistAlbums, ArtistTracks, BriefInfo, Dashboard, DownloadInfo, Experiments, \
|
from yandex_music import Album, Artist, ArtistAlbums, ArtistTracks, BriefInfo, Dashboard, DownloadInfo, Experiments, \
|
||||||
Feed, Genre, Landing, Like, PermissionAlerts, Playlist, PromoCodeStatus, Search, Settings, ShotEvent, Supplement, \
|
Feed, Genre, Landing, Like, PermissionAlerts, Playlist, PromoCodeStatus, Search, Settings, ShotEvent, Supplement, \
|
||||||
StationResult, StationTracksResult, Status, Suggestions, SimilarTracks, Track, TracksList, UserSettings, \
|
StationResult, StationTracksResult, Status, Suggestions, SimilarTracks, Track, TracksList, UserSettings, \
|
||||||
YandexMusicObject, ChartInfo, TagResult
|
YandexMusicObject, ChartInfo, TagResult, PlaylistRecommendations
|
||||||
from yandex_music.exceptions import Captcha, InvalidToken
|
from yandex_music.exceptions import Captcha, InvalidToken
|
||||||
from yandex_music.utils.difference import Difference
|
from yandex_music.utils.difference import Difference
|
||||||
from yandex_music.utils.request import Request
|
from yandex_music.utils.request import Request
|
||||||
|
@ -823,6 +823,33 @@ class Client(YandexMusicObject):
|
||||||
|
|
||||||
return Playlist.de_json(result, self)
|
return Playlist.de_json(result, self)
|
||||||
|
|
||||||
|
@log
|
||||||
|
def users_playlists_recommendations(self, kind: Union[str, int], user_id: Union[str, int] = None,
|
||||||
|
timeout: Union[int, float] = None, *args, **kwargs):
|
||||||
|
"""Получение рекомендаций для плейлиста.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
kind (:obj:`str` | :obj:`int`): Уникальный идентификатор плейлиста.
|
||||||
|
user_id (:obj:`str` | :obj:`int`): Уникальный идентификатор пользователя владеющим плейлистом.
|
||||||
|
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания
|
||||||
|
ответа от сервера вместо указанного при создании пула.
|
||||||
|
**kwargs (:obj:`dict`, optional): Произвольные аргументы (будут переданы в запрос).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`yandex_music.PlaylistRecommendations` | :obj:`None`: Рекомендации для плейлиста или :obj:`None`.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
:class:`yandex_music.exceptions.YandexMusicError`: Базовое исключение библиотеки.
|
||||||
|
"""
|
||||||
|
if user_id is None and self.me is not None:
|
||||||
|
user_id = self.me.account.uid
|
||||||
|
|
||||||
|
url = f'{self.base_url}/users/{user_id}/playlists/{kind}/recommendations'
|
||||||
|
|
||||||
|
result = self._request.get(url, timeout=timeout, *args, **kwargs)
|
||||||
|
|
||||||
|
return PlaylistRecommendations.de_json(result, self)
|
||||||
|
|
||||||
@log
|
@log
|
||||||
def users_playlists_create(self, title: str, visibility: str = 'public', user_id: Union[str, int] = None,
|
def users_playlists_create(self, title: str, visibility: str = 'public', user_id: Union[str, int] = None,
|
||||||
timeout: Union[int, float] = None, *args, **kwargs) -> Optional[Playlist]:
|
timeout: Union[int, float] = None, *args, **kwargs) -> Optional[Playlist]:
|
||||||
|
@ -2134,6 +2161,10 @@ class Client(YandexMusicObject):
|
||||||
generateTokenByUsernameAndPassword = generate_token_by_username_and_password
|
generateTokenByUsernameAndPassword = generate_token_by_username_and_password
|
||||||
#: Псевдоним для :attr:`account_status`
|
#: Псевдоним для :attr:`account_status`
|
||||||
accountStatus = account_status
|
accountStatus = account_status
|
||||||
|
#: Псевдоним для :attr:`account_settings`
|
||||||
|
accountSettings = account_settings
|
||||||
|
#: Псевдоним для :attr:`account_settings_set`
|
||||||
|
accountSettingsSet = account_settings_set
|
||||||
#: Псевдоним для :attr:`permission_alerts`
|
#: Псевдоним для :attr:`permission_alerts`
|
||||||
permissionAlerts = permission_alerts
|
permissionAlerts = permission_alerts
|
||||||
#: Псевдоним для :attr:`account_experiments`
|
#: Псевдоним для :attr:`account_experiments`
|
||||||
|
@ -2154,8 +2185,12 @@ class Client(YandexMusicObject):
|
||||||
albumsWithTracks = albums_with_tracks
|
albumsWithTracks = albums_with_tracks
|
||||||
#: Псевдоним для :attr:`search_suggest`
|
#: Псевдоним для :attr:`search_suggest`
|
||||||
searchSuggest = search_suggest
|
searchSuggest = search_suggest
|
||||||
|
#: Псевдоним для :attr:`users_settings`
|
||||||
|
usersSettings = users_settings
|
||||||
#: Псевдоним для :attr:`users_playlists`
|
#: Псевдоним для :attr:`users_playlists`
|
||||||
usersPlaylists = users_playlists
|
usersPlaylists = users_playlists
|
||||||
|
#: Псевдоним для :attr:`users_playlists_recommendations`
|
||||||
|
usersPlaylistsRecommendations = users_playlists_recommendations
|
||||||
#: Псевдоним для :attr:`users_playlists_create`
|
#: Псевдоним для :attr:`users_playlists_create`
|
||||||
usersPlaylistsCreate = users_playlists_create
|
usersPlaylistsCreate = users_playlists_create
|
||||||
#: Псевдоним для :attr:`users_playlists_delete`
|
#: Псевдоним для :attr:`users_playlists_delete`
|
||||||
|
|
|
@ -3,7 +3,8 @@ from typing import TYPE_CHECKING, Optional, List
|
||||||
from yandex_music import YandexMusicObject
|
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
|
||||||
|
|
||||||
|
|
||||||
class Playlist(YandexMusicObject):
|
class Playlist(YandexMusicObject):
|
||||||
|
@ -168,6 +169,13 @@ class Playlist(YandexMusicObject):
|
||||||
def playlist_id(self) -> str:
|
def playlist_id(self) -> str:
|
||||||
return f'{self.owner.uid}:{self.kind}'
|
return f'{self.owner.uid}:{self.kind}'
|
||||||
|
|
||||||
|
def get_recommendations(self, *args, **kwargs) -> Optional['PlaylistRecommendations']:
|
||||||
|
"""Сокращение для::
|
||||||
|
|
||||||
|
client.users_playlists_recommendations(playlist.kind, playlist.owner.uid, *args, **kwargs)
|
||||||
|
"""
|
||||||
|
return self.client.users_playlists_recommendations(self.kind, self.owner.uid, *args, **kwargs)
|
||||||
|
|
||||||
def download_animated_cover(self, filename: str, size: str = '200x200') -> None:
|
def download_animated_cover(self, filename: str, size: str = '200x200') -> None:
|
||||||
"""Загрузка анимированной обложки.
|
"""Загрузка анимированной обложки.
|
||||||
|
|
||||||
|
@ -263,6 +271,8 @@ class Playlist(YandexMusicObject):
|
||||||
isMine = is_mine
|
isMine = is_mine
|
||||||
#: Псевдоним для :attr:`playlist_id`
|
#: Псевдоним для :attr:`playlist_id`
|
||||||
playlistId = playlist_id
|
playlistId = playlist_id
|
||||||
|
#: Псевдоним для :attr:`get_recommendations`
|
||||||
|
getRecommendations = get_recommendations
|
||||||
#: Псевдоним для :attr:`download_animated_cover`
|
#: Псевдоним для :attr:`download_animated_cover`
|
||||||
downloadAnimatedCover = download_animated_cover
|
downloadAnimatedCover = download_animated_cover
|
||||||
#: Псевдоним для :attr:`download_og_image`
|
#: Псевдоним для :attr:`download_og_image`
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
from typing import TYPE_CHECKING, Optional, List
|
||||||
|
|
||||||
|
from yandex_music import YandexMusicObject
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from yandex_music import Client, Track
|
||||||
|
|
||||||
|
|
||||||
|
class PlaylistRecommendations(YandexMusicObject):
|
||||||
|
"""Класс, представляющий рекомендации для плейлиста.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
tracks (:obj:`list` из :obj:`yandex_music.Track`): Список рекомендованных треков.
|
||||||
|
batch_id (:obj:`str`): Уникальный идентификатор партии треков.
|
||||||
|
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tracks (:obj:`list` из :obj:`yandex_music.Track`): Список рекомендованных треков.
|
||||||
|
batch_id (:obj:`str`, optional): Уникальный идентификатор партии треков.
|
||||||
|
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
|
||||||
|
**kwargs: Произвольные ключевые аргументы полученные от API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
tracks: List['Track'],
|
||||||
|
batch_id: Optional[str] = None,
|
||||||
|
client: Optional['Client'] = None,
|
||||||
|
**kwargs) -> None:
|
||||||
|
super().handle_unknown_kwargs(self, **kwargs)
|
||||||
|
|
||||||
|
self.batch_id = batch_id
|
||||||
|
self.tracks = tracks
|
||||||
|
|
||||||
|
self.client = client
|
||||||
|
self._id_attrs = (self.batch_id, self.tracks)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def de_json(cls, data: dict, client: 'Client') -> Optional['PlaylistRecommendations']:
|
||||||
|
"""Десериализация объекта.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (:obj:`dict`): Поля и значения десериализуемого объекта.
|
||||||
|
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`yandex_music.PlaylistRecommendations`: Рекомендации для плейлиста.
|
||||||
|
"""
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
data = super(PlaylistRecommendations, cls).de_json(data, client)
|
||||||
|
from yandex_music import Track
|
||||||
|
data['tracks'] = Track.de_list(data.get('tracks'), client)
|
||||||
|
|
||||||
|
return cls(client=client, **data)
|
読み込み中…
新しいイシューから参照