Merge pull request #152 from MarshalX/bugfix/issue-147

Bugfix/issue #147
このコミットが含まれているのは:
Il'ya 2019-11-24 03:05:40 +03:00 committed by GitHub
コミット 952145c3b8
この署名に対応する既知のキーがデータベースに存在しません
GPGキーID: 4AEE18F83AFDEB23
11個のファイルの変更143行の追加34行の削除

ファイルの表示

@ -0,0 +1,7 @@
yandex_music.PlaylistAbsence
============================
.. autoclass:: yandex_music.PlaylistAbsence
:members:
:undoc-members:
:show-inheritance:

ファイルの表示

@ -6,6 +6,7 @@
yandex_music.playlist.user
yandex_music.playlist.made_for
yandex_music.playlist.play_counter
yandex_music.playlist.playlist_absence
yandex_music.playlist.playlist
yandex_music.playlist.case_forms
yandex_music.playlist.playlist_id

ファイルの表示

@ -39,6 +39,7 @@ from .test_play_context import TestPlayContext
from .test_play_contexts_data import TestPlayContextsData
from .test_play_counter import TestPlayCounter
from .test_playlist import TestPlaylist
from .test_playlist_absence import TestPlaylistAbsence
from .test_playlist_id import TestPlaylistId
from .test_playlist_id import TestPlaylistId
from .test_plus import TestPlus

ファイルの表示

@ -6,7 +6,7 @@ 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
GeneratedPlaylist, Video, Vinyl, SearchResult, BlockEntity, Block, PlaylistAbsence
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,7 +15,7 @@ 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
TestSearchResult, TestBlockEntity, TestBlock, TestPlaylistAbsence
@pytest.fixture(scope='session')
@ -102,11 +102,11 @@ def album_without_tracks(album_factory, artist_without_tracks):
@pytest.fixture(scope='session')
def playlist_factory(user, cover, made_for, track_short, play_counter):
def playlist_factory(user, cover, made_for, track_short, play_counter, playlist_absence):
class PlaylistFactory:
def get(self):
return Playlist(user, TestPlaylist.uid, TestPlaylist.kind, TestPlaylist.title, TestPlaylist.track_count,
cover, made_for, play_counter, TestPlaylist.tags, TestPlaylist.revision,
return Playlist(user, cover, made_for, play_counter, playlist_absence, TestPlaylist.uid, TestPlaylist.kind,
TestPlaylist.title, TestPlaylist.track_count, TestPlaylist.tags, TestPlaylist.revision,
TestPlaylist.snapshot, TestPlaylist.visibility, TestPlaylist.collective,
TestPlaylist.created, TestPlaylist.modified, TestPlaylist.available, TestPlaylist.is_banner,
TestPlaylist.is_premiere, TestPlaylist.duration_ms, TestPlaylist.og_image, [track_short],
@ -255,6 +255,11 @@ def play_counter():
return PlayCounter(TestPlayCounter.value, TestPlayCounter.description, TestPlayCounter.updated)
@pytest.fixture(scope='session')
def playlist_absence():
return PlaylistAbsence(TestPlaylistAbsence.kind, TestPlaylistAbsence.reason)
@pytest.fixture(scope='session')
def results(playlist):
return [playlist]

ファイルの表示

@ -28,7 +28,7 @@ class TestPlaylist:
is_for_from = None
regions = None
def test_expected_values(self, playlist, user, cover, made_for, track_short, play_counter):
def test_expected_values(self, playlist, user, cover, made_for, track_short, play_counter, playlist_absence):
assert playlist.owner == user
assert playlist.uid == self.uid
assert playlist.kind == self.kind
@ -37,6 +37,7 @@ class TestPlaylist:
assert playlist.cover == cover
assert playlist.made_for == made_for
assert playlist.play_counter == play_counter
assert playlist.playlist_absence == playlist_absence
assert playlist.tags == self.tags
assert playlist.revision == self.revision
assert playlist.snapshot == self.snapshot
@ -60,10 +61,10 @@ class TestPlaylist:
assert playlist.is_for_from == self.is_for_from
assert playlist.regions == self.regions
def test_de_json_required(self, client, user, cover, made_for, play_counter):
def test_de_json_required(self, client, user, cover, made_for, play_counter, playlist_absence):
json_dict = {'owner': user.to_dict(), 'uid': self.uid, 'kind': self.kind, 'title': self.title,
'track_count': self.track_count, 'cover': cover.to_dict(), 'made_for': made_for.to_dict(),
'play_counter': play_counter.to_dict()}
'play_counter': play_counter.to_dict(), 'playlist_absence': playlist_absence.to_dict()}
playlist = Playlist.de_json(json_dict, client)
assert playlist.owner == user
@ -75,15 +76,16 @@ class TestPlaylist:
assert playlist.made_for == made_for
assert playlist.play_counter == play_counter
def test_de_json_all(self, client, user, cover, made_for, track_short, play_counter):
def test_de_json_all(self, client, user, cover, made_for, track_short, play_counter, playlist_absence):
json_dict = {'owner': user.to_dict(), 'uid': self.uid, 'kind': self.kind, 'title': self.title,
'track_count': self.track_count, 'cover': cover.to_dict(), 'made_for': made_for.to_dict(),
'play_counter': play_counter.to_dict(), 'tags': self.tags, 'revision': self.revision,
'snapshot': self.snapshot, 'visibility': self.visibility, 'collective': self.collective,
'created': self.created, 'modified': self.modified, 'available': self.available,
'is_banner': self.is_banner, 'is_premiere': self.is_premiere, 'duration_ms': self.duration_ms,
'og_image': self.og_image, 'tracks': [track_short.to_dict()], 'prerolls': self.prerolls,
'likes_count': self.likes_count, 'generated_playlist_type': self.generated_playlist_type,
'play_counter': play_counter.to_dict(), 'playlist_absence': playlist_absence.to_dict(),
'tags': self.tags, 'revision': self.revision, 'snapshot': self.snapshot,
'visibility': self.visibility, 'collective': self.collective, 'created': self.created,
'modified': self.modified, 'available': self.available, 'is_banner': self.is_banner,
'is_premiere': self.is_premiere, 'duration_ms': self.duration_ms, 'og_image': self.og_image,
'tracks': [track_short.to_dict()], 'prerolls': self.prerolls, 'likes_count': self.likes_count,
'generated_playlist_type': self.generated_playlist_type,
'animated_cover_uri': self.animated_cover_uri, 'ever_played': self.ever_played,
'description': self.description, 'description_formatted': self.description_formatted,
'is_for_from': self.is_for_from, 'regions': self.regions}
@ -97,6 +99,7 @@ class TestPlaylist:
assert playlist.cover == cover
assert playlist.made_for == made_for
assert playlist.play_counter == play_counter
assert playlist.playlist_absence == playlist_absence
assert playlist.tags == self.tags
assert playlist.revision == self.revision
assert playlist.snapshot == self.snapshot
@ -120,11 +123,11 @@ class TestPlaylist:
assert playlist.is_for_from == self.is_for_from
assert playlist.regions == self.regions
def test_equality(self, user, cover, made_for, play_counter):
a = Playlist(user, self.uid, self.kind, self.title, self.track_count, cover, made_for, play_counter)
b = Playlist(user, 123, self.kind, self.title, 10, cover, made_for, play_counter)
c = Playlist(user, self.uid, 321, self.title, self.track_count, None, made_for, play_counter)
d = Playlist(user, self.uid, self.kind, self.title, self.track_count, cover, made_for, play_counter)
def test_equality(self, user, cover, made_for, play_counter, playlist_absence):
a = Playlist(user, cover, made_for, play_counter, playlist_absence)
b = Playlist(user, cover, made_for, play_counter, None)
c = Playlist(user, None, made_for, play_counter, playlist_absence)
d = Playlist(user, cover, made_for, play_counter, playlist_absence)
assert a != b != c
assert hash(a) != hash(b) != hash(c)

35
tests/test_playlist_absence.py ノーマルファイル
ファイルの表示

@ -0,0 +1,35 @@
from yandex_music import PlaylistAbsence
class TestPlaylistAbsence:
kind = 1003
reason = 'playlist-is-deleted'
def test_expected_values(self, playlist_absence):
assert playlist_absence.kind == self.kind
assert playlist_absence.reason == self.reason
def test_de_json_required(self, client):
json_dict = {'kind': self.kind, 'reason': self.reason}
playlist_absence = PlaylistAbsence.de_json(json_dict, client)
assert playlist_absence.kind == self.kind
assert playlist_absence.reason == self.reason
def test_de_json_all(self, client):
json_dict = {'kind': self.kind, 'reason': self.reason}
playlist_absence = PlaylistAbsence.de_json(json_dict, client)
assert playlist_absence.kind == self.kind
assert playlist_absence.reason == self.reason
def test_equality(self):
a = PlaylistAbsence(self.kind, self.reason)
b = PlaylistAbsence(10, self.reason)
c = PlaylistAbsence(self.kind, self.reason)
assert a != b
assert hash(a) != hash(b)
assert a is not b
assert a == c

ファイルの表示

@ -32,6 +32,7 @@ from .playlist.made_for import MadeFor
from .playlist.user import User
from .playlist.play_counter import PlayCounter
from .playlist.playlist_id import PlaylistId
from .playlist.playlist_absence import PlaylistAbsence
from .playlist.playlist import Playlist
from .tracks_list import TracksList
@ -113,4 +114,5 @@ __all__ = ['YandexMusicObject', 'Client', 'Account', 'PassportPhone', 'Invocatio
'PersonalPlaylistsData', 'Promotion', 'Landing', 'Chart', 'ChartItem', 'PlayContext', 'Title', 'Genre',
'Icon', 'Images', 'Id', 'Station', 'Dashboard', 'RotorSettings', 'AdParams', 'Restrictions', 'Value', 'Enum',
'DiscreteScale', 'StationResult', 'Sequence', 'StationTracksResult', 'BriefInfo', 'Description', 'PlaylistId',
'Vinyl', 'Supplement', 'Lyrics', 'VideoSupplement', 'ArtistTracks', 'Pager', 'ArtistAlbums']
'Vinyl', 'Supplement', 'Lyrics', 'VideoSupplement', 'ArtistTracks', 'Pager', 'ArtistAlbums',
'PlaylistAbsence']

ファイルの表示

@ -4,13 +4,14 @@ from yandex_music import YandexMusicObject
class Playlist(YandexMusicObject):
def __init__(self,
owner,
uid,
kind,
title,
track_count,
cover,
made_for,
play_counter,
playlist_absence,
uid=None,
kind=None,
title=None,
track_count=None,
tags=None,
revision=None,
snapshot=None,
@ -36,14 +37,15 @@ class Playlist(YandexMusicObject):
client=None,
**kwargs):
self.owner = owner
self.cover = cover
self.made_for = made_for
self.play_counter = play_counter
self.playlist_absence = playlist_absence
self.uid = uid
self.kind = kind
self.title = title
self.track_count = track_count
self.cover = cover
self.made_for = made_for
self.play_counter = play_counter
self.revision = revision
self.snapshot = snapshot
self.visibility = visibility
@ -68,8 +70,7 @@ class Playlist(YandexMusicObject):
self.tags = tags
self.client = client
self._id_attrs = (self.uid, self.kind, self.title, self.track_count, self.cover,
self.made_for, self.play_counter)
self._id_attrs = (self.uid, self.kind, self.title, self.playlist_absence)
@property
def is_mine(self):
@ -127,13 +128,18 @@ class Playlist(YandexMusicObject):
return None
data = super(Playlist, cls).de_json(data, client)
from yandex_music import User, MadeFor, Cover, PlayCounter, TrackShort
from yandex_music import User, MadeFor, Cover, PlayCounter, TrackShort, PlaylistAbsence
data['owner'] = User.de_json(data.get('owner'), client)
data['cover'] = Cover.de_json(data.get('cover'), client)
data['made_for'] = MadeFor.de_json(data.get('made_for'), client)
data['tracks'] = TrackShort.de_list(data.get('tracks'), client)
data['play_counter'] = PlayCounter.de_json(data.get('play_counter'), client)
data['playlist_absence'] = PlaylistAbsence.de_json(data.get('playlist_absence'), client) # на случай фикса
if data.get('playlist_absense'): # очепятка яндуха
data['playlist_absence'] = PlaylistAbsence.de_json(data.get('playlist_absense'), client)
data.pop('playlist_absense')
return cls(client=client, **data)
@classmethod

49
yandex_music/playlist/playlist_absence.py ノーマルファイル
ファイルの表示

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

ファイルの表示

@ -79,7 +79,7 @@ class Request:
except (AttributeError, ValueError):
raise YandexMusicError('Invalid server response')
if not data.get('result'):
if data.get('result') is None:
data = {'result': data, 'error': data.get('error'), 'error_description': data.get('error_description')}
return Response.de_json(data, self.client)

ファイルの表示

@ -24,7 +24,7 @@ class Response(YandexMusicObject):
@property
def result(self):
return self._result or self.data
return self.data if self._result is None else self._result
@classmethod
def de_json(cls, data, client):