diff --git a/docs/source/yandex_music.playlist.playlist_absence.rst b/docs/source/yandex_music.playlist.playlist_absence.rst new file mode 100644 index 0000000..b5408ba --- /dev/null +++ b/docs/source/yandex_music.playlist.playlist_absence.rst @@ -0,0 +1,7 @@ +yandex_music.PlaylistAbsence +============================ + +.. autoclass:: yandex_music.PlaylistAbsence + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/yandex_music.playlist.rst b/docs/source/yandex_music.playlist.rst index 4593619..29a8455 100644 --- a/docs/source/yandex_music.playlist.rst +++ b/docs/source/yandex_music.playlist.rst @@ -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 diff --git a/tests/__init__.py b/tests/__init__.py index 6c942b1..4609f79 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -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 diff --git a/tests/conftest.py b/tests/conftest.py index 398741b..c3c7b4e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -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] diff --git a/tests/test_playlist.py b/tests/test_playlist.py index e19cbc0..879da40 100644 --- a/tests/test_playlist.py +++ b/tests/test_playlist.py @@ -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) diff --git a/tests/test_playlist_absence.py b/tests/test_playlist_absence.py new file mode 100644 index 0000000..4ce6ca3 --- /dev/null +++ b/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 diff --git a/yandex_music/__init__.py b/yandex_music/__init__.py index a81b5b5..8a16d51 100644 --- a/yandex_music/__init__.py +++ b/yandex_music/__init__.py @@ -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'] diff --git a/yandex_music/playlist/playlist.py b/yandex_music/playlist/playlist.py index ddcd82e..ad2bf47 100644 --- a/yandex_music/playlist/playlist.py +++ b/yandex_music/playlist/playlist.py @@ -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 diff --git a/yandex_music/playlist/playlist_absence.py b/yandex_music/playlist/playlist_absence.py new file mode 100644 index 0000000..ef6d855 --- /dev/null +++ b/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) diff --git a/yandex_music/utils/request.py b/yandex_music/utils/request.py index dae18b4..6c2dd4f 100644 --- a/yandex_music/utils/request.py +++ b/yandex_music/utils/request.py @@ -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) diff --git a/yandex_music/utils/response.py b/yandex_music/utils/response.py index 6978393..650de28 100644 --- a/yandex_music/utils/response.py +++ b/yandex_music/utils/response.py @@ -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):