예제 #1
0
    def test_initialization(self):
        playlist = PlaylistFixture.one()
        actual = playlist.asdict()
        expected = {
            "type": "type_a",
            "provider": "provider_a",
            "arguments": {
                "a": 0
            },
            "id": "id_a",
            "title": "title_a",
            "youtube_id": None,
            "tracks": [],
            "synced": None,
            "uploaded": None,
        }
        self.assertDictEqual(expected, actual)
        expected = (
            "eyJhcmd1bWVudHMiOiB7ImEiOiAwfSwgInByb3ZpZGVyIjogInByb3ZpZG"
            "VyX2EiLCAidHlwZSI6ICJ0eXBlX2EiLCAidGl0bGUiOiAidGl0bGVfYSJ9")
        self.assertEqual(expected, playlist.mime)

        expected = {
            "arguments": {
                "a": 0
            },
            "provider": "provider_a",
            "type": "type_a",
            "title": "title_a",
        }
        self.assertEqual(expected,
                         json.loads(base64.b64decode(playlist.mime.encode())))
예제 #2
0
    def test_artist_playlist(self, create_playlist, artist_param,
                             fetch_tracks):
        artist_param.return_value = "Queen"
        create_playlist.return_value = PlaylistFixture.one()
        result = self.runner.invoke(
            cli,
            ["add", "lastfm", "artist-playlist"],
            input="Queen\n50\nQueen....",
            catch_exceptions=False,
        )

        expected_output = (
            "Artist: Queen",
            "Maximum tracks [50]: 50",
            "Title: Queen....",
            "Added playlist: id_a!",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)
        create_playlist.assert_called_once_with(
            dict(
                type=PlaylistType.ARTIST,
                provider=Provider.lastfm,
                arguments=dict(limit=50, artist="Queen"),
                title="Queen....",
            ))
        fetch_tracks.assert_called_once_with("id_a")
예제 #3
0
    def test_get_playlists(self, get_client):
        playlist = PlaylistFixture.one()
        list = get_client.return_value.playlists.return_value.list
        list.return_value.execute.side_effect = [
            {
                "nextPageToken": 2,
                "items": [
                    {
                        "id": "a",
                        "snippet": {
                            "description": playlist.mime,
                            "title": "One",
                        },
                    },
                    {"snippet": {"description": "", "title": ""}},
                ],
            },
            {"items": [{"snippet": {"description": "", "title": ""}}]},
        ]

        actual = YouService.get_playlists()
        self.assertEqual(1, len(actual))
        self.assertEqual("One", actual[0].title)
        list.assert_has_calls(
            [
                mock.call(part="snippet", mine=True, maxResults=2),
                mock.call().execute(),
                mock.call(
                    part="snippet", mine=True, maxResults=2, pageToken=2
                ),
                mock.call().execute(),
            ]
        )
        self.assertEqual(6, YouService.get_quota_usage())
예제 #4
0
    def test_show_playlist(self, get_playlist, get_track):
        playlist = PlaylistFixture.one(tracks=[1, 2, 3])

        get_playlist.return_value = playlist
        get_track.side_effect = TrackFixture.get(3, youtube_id=[None, "a", ""])

        result = self.runner.invoke(cli, ["show", playlist.id])

        expected_output = (
            "ID:  id_a",
            " Provider:  provider_a",
            "    Title:  title_a",
            "     Type:  type_a",
            "Arguments:  a: 0",
            "   Synced:  -",
            " Uploaded:  -",
            "  Youtube:  -",
            "   Tracks:",
            "",
            "No    Artist    Track Name     Youtube",
            "----  --------  ------------  ---------",
            "0     artist_a  name_a            -",
            "1     artist_b  name_b            ✔",
            "2     artist_c  name_c            -",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)
        get_playlist.assert_called_once_with(playlist.id)
        get_track.assert_has_calls([mock.call(id) for id in playlist.tracks])
예제 #5
0
    def test_show_playlist_mime(self, get_playlist):
        playlist = PlaylistFixture.one(tracks=[1, 2, 3])

        get_playlist.return_value = playlist
        result = self.runner.invoke(cli, ["show", playlist.id, "--mime"])

        expected_output = (
            "ID:  id_a",
            " Provider:  provider_a",
            "    Title:  title_a",
            "     Type:  type_a",
            "Arguments:  a: 0",
            "   Synced:  -",
            " Uploaded:  -",
            "  Youtube:  -",
            "     Mime:  eyJhcmd1bWVudHMiOiB7ImEiOiAwfSwgInByb3ZpZGVyIjogInByb3ZpZGVyX2EiLCAidHlwZSI6ICJ0eXBlX2EiLCAidGl0bGUiOiAidGl0bGVfYSJ9",
            "",
            "You reached the 10 playlists limit per day on youtube?",
            "Create a playlist manually and add in the bottom the above mime string",
            "The mime is base64 signature that pytuber uses to link with youtube playlists",
            'Use "pytuber fetch youtube --playlists" to sync, before you try to push any tracks',
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)
        get_playlist.assert_called_once_with(playlist.id)
예제 #6
0
    def test_user_playlist(self, create_playlist, convert, fetch_tracks):
        convert.return_value = "bbb"
        create_playlist.return_value = PlaylistFixture.one()
        result = self.runner.invoke(
            cli,
            ["add", "lastfm", "user-playlist"],
            input="\n".join(("aaa", "2", "50", "My Favorite  ")),
            catch_exceptions=False,
        )

        expected_output = (
            "Last.fm username: aaa",
            "Playlist Types",
            "[1] User Loved Tracks",
            "[2] User Top Tracks",
            "[3] User Recent Tracks",
            "[4] User Friends Recent Tracks",
            "Select a playlist type 1-4: 2",
            "Maximum tracks [50]: 50",
            "Title: My Favorite  ",
            "Added playlist: id_a!",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)
        create_playlist.assert_called_once_with(
            dict(
                type=UserPlaylistType.USER_TOP_TRACKS,
                provider=Provider.lastfm,
                arguments=dict(limit=50, username="******"),
                title="My Favorite",
            ))
        fetch_tracks.assert_called_once_with("id_a")
예제 #7
0
    def test_get_playlist_items(self, get_client):
        playlist = PlaylistFixture.one()
        list = get_client.return_value.playlistItems.return_value.list
        list.return_value.execute.side_effect = [
            {
                "nextPageToken": 3,
                "items": [
                    {
                        "id": "a",
                        "contentDetails": {"videoId": "va"},
                        "snippet": {"title": "foo - bar"},
                    },
                    {
                        "id": "b",
                        "contentDetails": {"videoId": "vb"},
                        "snippet": {"title": "thug life"},
                    },
                ],
            },
            {
                "items": [
                    {
                        "id": "c",
                        "contentDetails": {"videoId": "vc"},
                        "snippet": {"title": "a-b-c"},
                    }
                ]
            },
        ]

        actual = YouService.get_playlist_items(playlist)
        expected = [
            {"artist": "foo", "id": "a", "name": "bar", "video_id": "va"},
            {"artist": "", "id": "b", "name": "thug life", "video_id": "vb"},
            {"artist": "a", "id": "c", "name": "b-c", "video_id": "vc"},
        ]
        self.assertEqual(expected, [a.asdict() for a in actual])

        list.assert_has_calls(
            [
                mock.call(
                    part="contentDetails,snippet",
                    maxResults=2,
                    playlistId=playlist.youtube_id,
                ),
                mock.call().execute(),
                mock.call(
                    part="contentDetails,snippet",
                    maxResults=2,
                    playlistId=playlist.youtube_id,
                    pageToken=3,
                ),
                mock.call().execute(),
            ]
        )
        self.assertEqual(10, YouService.get_quota_usage())
예제 #8
0
    def test_with_tracks(
        self,
        find_playlists,
        update_playlist,
        find_tracks,
        get_playlist_items,
        create_playlist_item,
        remove_playlist_item,
        timestamp,
    ):

        timestamp.return_value = 101
        items = PlaylistItemFixture.get(4, video_id=["$a", "$d", "$e", "$f"])

        tracks = TrackFixture.get(
            6, youtube_id=["$a", "$b", "$c", "$d", "$e", "$f"])
        p_one, p_two = PlaylistFixture.get(2,
                                           tracks=[["id_a", "id_b", "id_c"],
                                                   ["id_d", "id_e", "id_f"]])

        find_playlists.return_value = [p_one, p_two]
        find_tracks.side_effect = [tracks[:3], tracks[3:]]

        get_playlist_items.side_effect = [
            [items[0], items[2]],
            [items[1], items[2], items[3]],
        ]

        result = self.runner.invoke(cli, ["push", "youtube", "--tracks"],
                                    catch_exceptions=False)

        expected_output = (
            "Syncing playlists",
            "Fetching playlist items: title_a",
            "Adding new playlist items: 2",
            "Removing playlist items: 1",
            "Fetching playlist items: title_b",
            "Adding new playlist items",
            "Removing playlist items",
        )

        self.assertEqual(0, result.exit_code)
        self.assertOutputContains(expected_output, result.output)

        get_playlist_items.assert_has_calls(
            [mock.call(p_one), mock.call(p_two)])

        create_playlist_item.assert_has_calls([
            mock.call(p_one, tracks[1].youtube_id),
            mock.call(p_one, tracks[2].youtube_id),
        ])
        remove_playlist_item.assert_called_once_with(items[2])
        update_playlist.assert_called_once_with(p_one, dict(uploaded=101))
예제 #9
0
    def test_removes_orphan_tracks_and_empty_playlists(self):
        [TrackManager.set(t.asdict()) for t in TrackFixture.get(2)]
        [PlaylistManager.set(p.asdict()) for p in PlaylistFixture.get(3)]

        playlist = PlaylistFixture.one(num=50)
        track = TrackFixture.one(num=5)
        playlist.tracks = [track.id]
        PlaylistManager.set(playlist.asdict())
        TrackManager.set(track.asdict())

        result = self.runner.invoke(cli, ["clean"])

        expected_output = (
            "Cleanup removed:",
            "   Tracks:  2",
            "Playlists:  3",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)

        self.assertEqual(track.id, TrackManager.find()[0].id)
        self.assertEqual(playlist.id, PlaylistManager.find()[0].id)
예제 #10
0
    def test_create_playlist(self, get_client):
        playlist = PlaylistFixture.one()
        insert = get_client.return_value.playlists.return_value.insert
        insert.return_value.execute.return_value = {"id": "101"}

        self.assertEqual("101", YouService.create_playlist(playlist))
        insert.assert_called_once_with(
            body=dict(
                snippet=dict(title=playlist.title, description=playlist.mime),
                status=dict(privacyStatus="private"),
            ),
            part="snippet,status",
        )
        self.assertEqual(55, YouService.get_quota_usage())
예제 #11
0
    def test_with_playlists(self, find, update, create_playlist):
        p_one, p_two = PlaylistFixture.get(2)
        find.return_value = [p_one, p_two]
        create_playlist.side_effect = ["y1", "y2"]
        result = self.runner.invoke(cli, ["push", "youtube", "--playlists"],
                                    catch_exceptions=False)

        expected_messages = ("Creating playlists: 2/2", )
        self.assertEqual(0, result.exit_code)
        self.assertOutputContains(expected_messages, result.output)

        create_playlist.assert_has_calls([mock.call(p_one), mock.call(p_two)])
        update.assert_has_calls([
            mock.call(p_one, dict(youtube_id="y1")),
            mock.call(p_two, dict(youtube_id="y2")),
        ])
예제 #12
0
    def test_create_playlist_item(self, get_client):
        playlist = PlaylistFixture.one(youtube_id="b")
        insert = get_client.return_value.playlistItems.return_value.insert
        insert.return_value.execute.return_value = "foo"

        self.assertEqual(
            "foo", YouService.create_playlist_item(playlist, "aa")
        )
        insert.assert_called_once_with(
            body=dict(
                snippet=dict(
                    playlistId=playlist.youtube_id,
                    resourceId=dict(kind="youtube#video", videoId="aa"),
                )
            ),
            part="snippet",
        )
        self.assertEqual(53, YouService.get_quota_usage())
예제 #13
0
    def test_list_playlists(self, find):
        find.return_value = PlaylistFixture.get(
            2,
            youtube_id=["456ybnm", None],
            synced=[None, 1546727285],
            uploaded=[None, 1546727385],
            tracks=[[], list(range(0, 99))],
        )
        result = self.runner.invoke(cli, ["list"])

        expected_output = (
            "ID    Title    Provider     Youtube     Tracks",
            "----  -------  ----------  ---------  --------",
            "id_a  title_a  provider_a      ✔             0",
            "id_b  title_b  provider_b      -            99",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)
        find.assert_called_once_with()
예제 #14
0
    def test_with_tracks(self, find, update, get_tracks, get_tags, set):

        tracks = TrackFixture.get(6)
        playlists = PlaylistFixture.get(2)
        last_tracks = [
            pydrag.Track.from_dict(dict(name=track.name, artist=track.artist))
            for track in tracks
        ]

        set.side_effect = tracks
        find.return_value = playlists
        get_tracks.side_effect = [
            [last_tracks[0], last_tracks[1], last_tracks[2]],
            [last_tracks[3], last_tracks[4], last_tracks[5]],
        ]

        result = self.runner.invoke(cli, ["fetch", "lastfm", "--tracks"])

        self.assertEqual(0, result.exit_code)
        get_tags.assert_called_once_with()
        find.assert_called_once_with(provider=Provider.lastfm)
        get_tracks.assert_has_calls(
            [mock.call(a=0, type="type_a"), mock.call(b=1, type="type_b")]
        )
        set.assert_has_calls(
            [
                mock.call({"artist": "artist_a", "name": "name_a"}),
                mock.call({"artist": "artist_b", "name": "name_b"}),
                mock.call({"artist": "artist_c", "name": "name_c"}),
                mock.call({"artist": "artist_d", "name": "name_d"}),
                mock.call({"artist": "artist_e", "name": "name_e"}),
                mock.call({"artist": "artist_f", "name": "name_f"}),
            ]
        )

        update.assert_has_calls(
            [
                mock.call(playlists[0], dict(tracks=["id_a", "id_b", "id_c"])),
                mock.call(playlists[1], dict(tracks=["id_d", "id_e", "id_f"])),
            ]
        )
예제 #15
0
    def test_chart_playlist(self, create_playlist, fetch_tracks):
        create_playlist.return_value = PlaylistFixture.one()
        result = self.runner.invoke(cli, ["add", "lastfm", "chart-playlist"],
                                    input="50\n ")

        expected_output = (
            "Maximum tracks [50]: 50",
            "Title:  ",
            "Added playlist: id_a!",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)

        create_playlist.assert_called_once_with(
            dict(
                type=PlaylistType.CHART,
                provider=Provider.lastfm,
                arguments=dict(limit=50),
                title="",
            ))
        fetch_tracks.assert_called_once_with("id_a")
예제 #16
0
    def test_fetch_playlists(
        self,
        get_playlists,
        get_playlist_items,
        set_playlist,
        exists,
        set_tracks,
    ):
        exists.side_effect = [True, False]
        p_one, p_two = PlaylistFixture.get(2)
        v_one, v_two = PlaylistItemFixture.get(2)
        get_playlists.return_value = [p_one, p_two]
        get_playlist_items.return_value = [v_one, v_two]
        set_tracks.side_effect = TrackFixture.get(2)

        result = self.runner.invoke(cli, ["fetch", "youtube", "--playlists"],
                                    catch_exceptions=False)

        expected_messages = ("Fetching playlists info", )
        self.assertEqual(0, result.exit_code)
        self.assertOutputContains(expected_messages, result.output)

        p_two.tracks = ["id_a", "id_b"]
        get_playlists.assert_called_once_with()
        set_playlist.assert_has_calls(
            [mock.call(p_one.asdict()),
             mock.call(p_two.asdict())])
        set_tracks.assert_has_calls([
            mock.call({
                "artist": "artist_a",
                "name": "name_a",
                "youtube_id": "video_id_a",
            }),
            mock.call({
                "artist": "artist_b",
                "name": "name_b",
                "youtube_id": "video_id_b",
            }),
        ])
예제 #17
0
    def test_create_playlist(self, clear, secho, confirm, set, magenta):
        magenta.side_effect = lambda x: x
        set.return_value = PlaylistFixture.one()
        tracks = [
            ("Queen", "Bohemian Rhapsody"),
            ("Queen", "I want to break free"),
        ]
        create_playlist(
            title="My Cool Playlist",
            tracks=tracks,
            type="foo",
            arguments=dict(foo="bar"),
        )

        expected_ouput = (
            "Title:  My Cool Playlist",
            "Tracks:  2",
            "",
            "  No  Artist    Track Name",
            "----  --------  --------------------",
            "   1  Queen     Bohemian Rhapsody",
            "   2  Queen     I want to break free",
        )

        self.assertOutput(expected_ouput, secho.call_args_list[0][0][0])
        self.assertEqual("Added playlist: id_a!",
                         secho.call_args_list[1][0][0])

        clear.assert_called_once_with()
        confirm.assert_called_once_with(
            "Are you sure you want to save this playlist?", abort=True)
        set.assert_called_once_with(
            dict(
                type="foo",
                arguments=dict(foo="bar"),
                provider=Provider.user,
                title="My Cool Playlist",
                tracks=["55a4d2b", "b045fee"],
            ))
예제 #18
0
    def test_tag_playlist(self, create_playlist, convert, fetch_tracks):
        convert.return_value = "rock"
        create_playlist.return_value = PlaylistFixture.one(synced=111)
        result = self.runner.invoke(cli, ["add", "lastfm", "tag-playlist"],
                                    input="rock\n50\n ")

        expected_output = (
            "Tag: rock",
            "Maximum tracks [50]: 50",
            "Title:  ",
            "Updated playlist: id_a!",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)
        create_playlist.assert_called_once_with(
            dict(
                type=PlaylistType.TAG,
                provider=Provider.lastfm,
                arguments=dict(limit=50, tag="rock"),
                title="",
            ))
        fetch_tracks.assert_called_once_with("id_a")
예제 #19
0
    def test_country_playlist(self, create_playlist, country_param_type,
                              fetch_tracks):
        country_param_type.return_value = "greece"
        create_playlist.return_value = PlaylistFixture.one()
        result = self.runner.invoke(cli, ["add", "lastfm", "country-playlist"],
                                    input=b"gr\n50\n ")

        expected_output = (
            "Country Code: gr",
            "Maximum tracks [50]: 50",
            "Title:  ",
            "Added playlist: id_a!",
        )
        self.assertEqual(0, result.exit_code)
        self.assertOutput(expected_output, result.output)
        create_playlist.assert_called_once_with(
            dict(
                type=PlaylistType.COUNTRY,
                provider=Provider.lastfm,
                arguments=dict(limit=50, country="greece"),
                title="",
            ))
        fetch_tracks.assert_called_once_with("id_a")
예제 #20
0
    def test_complete(self):
        [PlaylistManager.set(p.asdict()) for p in PlaylistFixture.get(2)]

        self.assertEqual(["id_a", "id_b"], self.param.complete(None, ""))
        self.assertEqual(["id_a"], self.param.complete(None, "id_a"))