commit: 70b71a5584b9d40d8df84ac717c73128ef687fec Author: Andrew Ammerlaan <andrewammerlaan <AT> riseup <DOT> net> AuthorDate: Tue Jan 21 14:34:31 2020 +0000 Commit: Andrew Ammerlaan <andrewammerlaan <AT> riseup <DOT> net> CommitDate: Tue Jan 21 14:34:31 2020 +0000 URL: https://gitweb.gentoo.org/repo/proj/guru.git/commit/?id=70b71a55
dev-python/spotipy: A light weight Py library for Spotify Web API Package-Manager: Portage-2.3.84, Repoman-2.3.20 Signed-off-by: Andrew Ammerlaan <andrewammerlaan <AT> riseup.net> dev-python/spotipy/Manifest | 1 + .../files/spotipy-2.7.1-skip-online-test.patch | 515 +++++++++++++++++++++ dev-python/spotipy/metadata.xml | 13 + dev-python/spotipy/spotipy-2.7.1.ebuild | 41 ++ 4 files changed, 570 insertions(+) diff --git a/dev-python/spotipy/Manifest b/dev-python/spotipy/Manifest new file mode 100644 index 0000000..b3343ca --- /dev/null +++ b/dev-python/spotipy/Manifest @@ -0,0 +1 @@ +DIST spotipy-2.7.1.tar.gz 80050 BLAKE2B f4c4be4c8284a0c1fe12d7f963dc1a92c0c9f73ac9981debc193f21502b9106e13311a7ca97bfe00384892da73df7f964a8e8d786371551079902aebf3c32815 SHA512 8751f78e51778ff595ddf4f511bfd9c81b7c46789d91a86c1a6dcd169b55668d48b812e6c6e2befd85a12a3e622127a9ba466c6a5008b1e3cafe25939f26e705 diff --git a/dev-python/spotipy/files/spotipy-2.7.1-skip-online-test.patch b/dev-python/spotipy/files/spotipy-2.7.1-skip-online-test.patch new file mode 100644 index 0000000..0386b96 --- /dev/null +++ b/dev-python/spotipy/files/spotipy-2.7.1-skip-online-test.patch @@ -0,0 +1,515 @@ +diff --git a/tests/test_auth.py b/tests/test_auth.py +deleted file mode 100644 +index 438e88f..0000000 +--- a/tests/test_auth.py ++++ /dev/null +@@ -1,363 +0,0 @@ +-# -*- coding: utf-8 -*- +- +-""" +-These tests require user authentication - provide client credentials using the +-following environment variables +- +-:: +- +- 'SPOTIPY_CLIENT_USERNAME' +- 'SPOTIPY_CLIENT_ID' +- 'SPOTIPY_CLIENT_SECRET' +- 'SPOTIPY_REDIRECT_URI' +-""" +- +-from __future__ import print_function +- +-from spotipy import ( +- CLIENT_CREDS_ENV_VARS as CCEV, +- prompt_for_user_token, +- Spotify, +- SpotifyException, +-) +-import os +-import sys +-import unittest +-import warnings +-import requests +- +-sys.path.insert(0, os.path.abspath(os.pardir)) +- +- +-class AuthTestSpotipy(unittest.TestCase): +- """ +- These tests require user authentication - provide client credentials using +- the following environment variables +- +- :: +- +- 'SPOTIPY_CLIENT_USERNAME' +- 'SPOTIPY_CLIENT_ID' +- 'SPOTIPY_CLIENT_SECRET' +- 'SPOTIPY_REDIRECT_URI' +- """ +- +- playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx" +- playlist_new_id = "spotify:playlist:7GlxpQjjxRjmbb3RP2rDqI" +- four_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp", +- "spotify:track:7IHOIqZUUInxjVkko181PB", +- "4VrWlk8IQxevMvERoX08iC", +- "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"] +- +- two_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp", +- "spotify:track:7IHOIqZUUInxjVkko181PB"] +- +- other_tracks = ["spotify:track:2wySlB6vMzCbQrRnNGOYKa", +- "spotify:track:29xKs5BAHlmlX1u4gzQAbJ", +- "spotify:track:1PB7gRWcvefzu7t3LJLUlf"] +- +- album_ids = ["spotify:album:6kL09DaURb7rAoqqaA51KU", +- "spotify:album:6RTzC0rDbvagTSJLlY7AKl"] +- +- bad_id = 'BAD_ID' +- +- @classmethod +- def setUpClass(self): +- if sys.version_info >= (3, 2): +- # >= Python3.2 only +- warnings.filterwarnings( +- "ignore", +- category=ResourceWarning, +- message="unclosed.*<ssl.SSLSocket.*>") +- +- missing = list(filter(lambda var: not os.getenv(CCEV[var]), CCEV)) +- +- if missing: +- raise Exception( +- ('Please set the client credentials for the test application' +- ' using the following environment variables: {}').format( +- CCEV.values())) +- +- self.username = os.getenv(CCEV['client_username']) +- +- self.scope = ( +- 'playlist-modify-public ' +- 'user-library-read ' +- 'user-follow-read ' +- 'user-library-modify ' +- 'user-read-private ' +- 'user-top-read ' +- 'user-follow-modify ' +- 'ugc-image-upload' +- ) +- +- self.token = prompt_for_user_token(self.username, scope=self.scope) +- +- self.spotify = Spotify(auth=self.token) +- +- # Helper +- def get_or_create_spotify_playlist(self, playlist_name): +- playlists = self.spotify.user_playlists(self.username) +- while playlists: +- for item in playlists['items']: +- if item['name'] == playlist_name: +- return item +- playlists = self.spotify.next(playlists) +- return self.spotify.user_playlist_create( +- self.username, playlist_name) +- +- # Helper +- def get_as_base64(self, url): +- import base64 +- return base64.b64encode(requests.get(url).content).decode("utf-8") +- +- def test_track_bad_id(self): +- try: +- self.spotify.track(self.bad_id) +- self.assertTrue(False) +- except SpotifyException: +- self.assertTrue(True) +- +- def test_basic_user_profile(self): +- user = self.spotify.user(self.username) +- self.assertTrue(user['id'] == self.username.lower()) +- +- def test_current_user(self): +- user = self.spotify.current_user() +- self.assertTrue(user['id'] == self.username.lower()) +- +- def test_me(self): +- user = self.spotify.me() +- self.assertTrue(user['id'] == self.username.lower()) +- +- def test_user_playlists(self): +- playlists = self.spotify.user_playlists(self.username, limit=5) +- self.assertTrue('items' in playlists) +- self.assertTrue(len(playlists['items']) == 5) +- +- def test_user_playlist_tracks(self): +- playlists = self.spotify.user_playlists(self.username, limit=5) +- self.assertTrue('items' in playlists) +- for playlist in playlists['items']: +- user = playlist['owner']['id'] +- pid = playlist['id'] +- results = self.spotify.user_playlist_tracks(user, pid) +- self.assertTrue(len(results['items']) >= 0) +- +- def test_current_user_saved_albums(self): +- # List +- albums = self.spotify.current_user_saved_albums() +- self.assertTrue(len(albums['items']) > 1) +- +- # Add +- self.spotify.current_user_saved_albums_add(self.album_ids) +- +- # Contains +- self.assertTrue( +- self.spotify.current_user_saved_albums_contains( +- self.album_ids) == [ +- True, True]) +- +- # Remove +- self.spotify.current_user_saved_albums_delete(self.album_ids) +- albums = self.spotify.current_user_saved_albums() +- self.assertTrue(len(albums['items']) > 1) +- +- def test_current_user_playlists(self): +- playlists = self.spotify.current_user_playlists(limit=10) +- self.assertTrue('items' in playlists) +- self.assertTrue(len(playlists['items']) == 10) +- +- def test_user_playlist_follow(self): +- self.spotify.user_playlist_follow_playlist( +- 'plamere', '4erXB04MxwRAVqcUEpu30O') +- follows = self.spotify.user_playlist_is_following( +- 'plamere', '4erXB04MxwRAVqcUEpu30O', [ +- self.spotify.current_user()['id']]) +- +- self.assertTrue(len(follows) == 1, 'proper follows length') +- self.assertTrue(follows[0], 'is following') +- self.spotify.user_playlist_unfollow( +- 'plamere', '4erXB04MxwRAVqcUEpu30O') +- +- follows = self.spotify.user_playlist_is_following( +- 'plamere', '4erXB04MxwRAVqcUEpu30O', [ +- self.spotify.current_user()['id']]) +- self.assertTrue(len(follows) == 1, 'proper follows length') +- self.assertFalse(follows[0], 'is no longer following') +- +- def test_current_user_saved_tracks(self): +- tracks = self.spotify.current_user_saved_tracks() +- self.assertTrue(len(tracks['items']) > 0) +- +- def test_current_user_save_and_unsave_tracks(self): +- tracks = self.spotify.current_user_saved_tracks() +- total = tracks['total'] +- self.spotify.current_user_saved_tracks_add(self.four_tracks) +- +- tracks = self.spotify.current_user_saved_tracks() +- new_total = tracks['total'] +- self.assertTrue(new_total - total == len(self.four_tracks)) +- +- tracks = self.spotify.current_user_saved_tracks_delete( +- self.four_tracks) +- tracks = self.spotify.current_user_saved_tracks() +- new_total = tracks['total'] +- self.assertTrue(new_total == total) +- +- def test_categories(self): +- response = self.spotify.categories() +- self.assertTrue(len(response['categories']) > 0) +- +- def test_category_playlists(self): +- response = self.spotify.categories() +- for cat in response['categories']['items']: +- cat_id = cat['id'] +- response = self.spotify.category_playlists(category_id=cat_id) +- if len(response['playlists']["items"]) > 0: +- break +- self.assertTrue(True) +- +- def test_new_releases(self): +- response = self.spotify.new_releases() +- self.assertTrue(len(response['albums']) > 0) +- +- def test_featured_releases(self): +- response = self.spotify.featured_playlists() +- self.assertTrue(len(response['playlists']) > 0) +- +- def test_current_user_follows(self): +- response = self.spotify.current_user_followed_artists() +- artists = response['artists'] +- self.assertTrue(len(artists['items']) > 0) +- +- def test_current_user_top_tracks(self): +- response = self.spotify.current_user_top_tracks() +- items = response['items'] +- self.assertTrue(len(items) > 0) +- +- def test_current_user_top_artists(self): +- response = self.spotify.current_user_top_artists() +- items = response['items'] +- self.assertTrue(len(items) > 0) +- +- def test_user_playlist_ops(self): +- sp = self.spotify +- # create empty playlist +- playlist = self.get_or_create_spotify_playlist( +- 'spotipy-testing-playlist-1') +- playlist_id = playlist['id'] +- +- # remove all tracks from it +- sp.user_playlist_replace_tracks( +- self.username, playlist_id, []) +- playlist = sp.user_playlist(self.username, playlist_id) +- self.assertTrue(playlist['tracks']['total'] == 0) +- self.assertTrue(len(playlist['tracks']['items']) == 0) +- +- # add tracks to it +- sp.user_playlist_add_tracks( +- self.username, playlist_id, self.four_tracks) +- playlist = sp.user_playlist(self.username, playlist_id) +- self.assertTrue(playlist['tracks']['total'] == 4) +- self.assertTrue(len(playlist['tracks']['items']) == 4) +- +- # remove two tracks from it +- +- sp.user_playlist_remove_all_occurrences_of_tracks(self.username, +- playlist_id, +- self.two_tracks) +- playlist = sp.user_playlist(self.username, playlist_id) +- self.assertTrue(playlist['tracks']['total'] == 2) +- self.assertTrue(len(playlist['tracks']['items']) == 2) +- +- # replace with 3 other tracks +- sp.user_playlist_replace_tracks(self.username, +- playlist_id, +- self.other_tracks) +- playlist = sp.user_playlist(self.username, playlist_id) +- self.assertTrue(playlist['tracks']['total'] == 3) +- self.assertTrue(len(playlist['tracks']['items']) == 3) +- +- def test_playlist(self): +- # New playlist ID +- pl = self.spotify.playlist(self.playlist_new_id) +- self.assertTrue(pl["tracks"]["total"] > 0) +- +- # Old playlist ID +- pl = self.spotify.playlist(self.playlist) +- self.assertTrue(pl["tracks"]["total"] > 0) +- +- def test_playlist_tracks(self): +- # New playlist ID +- pl = self.spotify.playlist_tracks(self.playlist_new_id, limit=2) +- self.assertTrue(len(pl["items"]) == 2) +- self.assertTrue(pl["total"] > 0) +- +- # Old playlist ID +- pl = self.spotify.playlist_tracks(self.playlist, limit=2) +- self.assertTrue(len(pl["items"]) == 2) +- self.assertTrue(pl["total"] > 0) +- +- def test_playlist_upload_cover_image(self): +- pl1 = self.get_or_create_spotify_playlist('spotipy-testing-playlist-1') +- plid = pl1['uri'] +- old_b64 = pl1['images'][0]['url'] +- +- # Upload random dog image +- r = requests.get('https://dog.ceo/api/breeds/image/random') +- dog_base64 = self.get_as_base64(r.json()['message']) +- self.spotify.playlist_upload_cover_image(plid, dog_base64) +- +- # Image must be different +- pl1 = self.spotify.playlist(plid) +- new_b64 = self.get_as_base64(pl1['images'][0]['url']) +- self.assertTrue(old_b64 != new_b64) +- +- def test_user_follows_and_unfollows_artist(self): +- # Initially follows 1 artist +- res = self.spotify.current_user_followed_artists() +- self.assertTrue(res['artists']['total'] == 1) +- +- # Follow 2 more artists +- artists = ["6DPYiyq5kWVQS4RGwxzPC7", "0NbfKEOTQCcwd6o7wSDOHI"] +- self.spotify.user_follow_artists(artists) +- res = self.spotify.current_user_followed_artists() +- self.assertTrue(res['artists']['total'] == 3) +- +- # Unfollow these 2 artists +- self.spotify.user_unfollow_artists(artists) +- res = self.spotify.current_user_followed_artists() +- self.assertTrue(res['artists']['total'] == 1) +- +- def test_user_follows_and_unfollows_user(self): +- # TODO improve after implementing `me/following/contains` +- users = ["11111204", "xlqeojt6n7on0j7coh9go8ifd"] +- +- # Follow 2 more users +- self.spotify.user_follow_users(users) +- +- # Unfollow these 2 users +- self.spotify.user_unfollow_users(users) +- +- def test_deprecated_starred(self): +- pl = self.spotify.user_playlist(self.username) +- self.assertTrue(pl["tracks"] is None) +- self.assertTrue(pl["owner"] is None) +- +- def test_deprecated_user_playlist(self): +- # Test without user due to change from +- # https://developer.spotify.com/community/news/2018/06/12/changes-to-playlist-uris/ +- pl = self.spotify.user_playlist(None, self.playlist) +- self.assertTrue(pl["tracks"]["total"] > 0) +- +- def test_deprecated_user_playlis(self): +- # Test without user due to change from +- # https://developer.spotify.com/community/news/2018/06/12/changes-to-playlist-uris/ +- pl = self.spotify.user_playlist_tracks(None, self.playlist, limit=2) +- self.assertTrue(len(pl["items"]) == 2) +- self.assertTrue(pl["total"] > 0) +- +- +-if __name__ == '__main__': +- unittest.main() +diff --git a/tests/test_auth2.py b/tests/test_auth2.py +deleted file mode 100644 +index 47cf798..0000000 +--- a/tests/test_auth2.py ++++ /dev/null +@@ -1,91 +0,0 @@ +-# -*- coding: utf-8 -*- +- +-""" +-These tests require user authentication - provide client credentials using the +-following environment variables +- +-:: +- +- 'SPOTIPY_CLIENT_USERNAME' +- 'SPOTIPY_CLIENT_ID' +- 'SPOTIPY_CLIENT_SECRET' +- 'SPOTIPY_REDIRECT_URI' +-""" +- +-from spotipy import ( +- Spotify, +- SpotifyClientCredentials, +-) +-import os +-import sys +-import unittest +- +-sys.path.insert(0, os.path.abspath(os.pardir)) +- +- +-class AuthTestSpotipy(unittest.TestCase): +- """ +- These tests require user authentication - provide client credentials using +- the following environment variables +- +- :: +- +- 'SPOTIPY_CLIENT_USERNAME' +- 'SPOTIPY_CLIENT_ID' +- 'SPOTIPY_CLIENT_SECRET' +- 'SPOTIPY_REDIRECT_URI' +- """ +- +- playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx" +- four_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp", +- "spotify:track:7IHOIqZUUInxjVkko181PB", +- "4VrWlk8IQxevMvERoX08iC", +- "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"] +- +- two_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp", +- "spotify:track:7IHOIqZUUInxjVkko181PB"] +- +- other_tracks = ["spotify:track:2wySlB6vMzCbQrRnNGOYKa", +- "spotify:track:29xKs5BAHlmlX1u4gzQAbJ", +- "spotify:track:1PB7gRWcvefzu7t3LJLUlf"] +- +- bad_id = 'BAD_ID' +- +- @classmethod +- def setUpClass(self): +- self.spotify = Spotify( +- client_credentials_manager=SpotifyClientCredentials()) +- self.spotify.trace = False +- +- def test_audio_analysis(self): +- result = self.spotify.audio_analysis(self.four_tracks[0]) +- assert('beats' in result) +- +- def test_audio_features(self): +- results = self.spotify.audio_features(self.four_tracks) +- self.assertTrue(len(results) == len(self.four_tracks)) +- for track in results: +- assert('speechiness' in track) +- +- def test_audio_features_with_bad_track(self): +- bad_tracks = [] +- bad_tracks = ['spotify:track:bad'] +- input = self.four_tracks + bad_tracks +- results = self.spotify.audio_features(input) +- self.assertTrue(len(results) == len(input)) +- for track in results[:-1]: +- if track is not None: +- assert('speechiness' in track) +- self.assertTrue(results[-1] is None) +- +- def test_recommendations(self): +- results = self.spotify.recommendations( +- seed_tracks=self.four_tracks, +- min_danceability=0, +- max_loudness=0, +- target_popularity=50) +- self.assertTrue(len(results['tracks']) == 20) +- +- +-if __name__ == '__main__': +- unittest.main() +diff --git a/tests/test_client_credentials.py b/tests/test_client_credentials.py +deleted file mode 100644 +index acbda5c..0000000 +--- a/tests/test_client_credentials.py ++++ /dev/null +@@ -1,43 +0,0 @@ +-# -*- coding: utf-8 -*- +- +-""" Client Credentials Requests Tests """ +- +-from spotipy import ( +- Spotify, +- SpotifyClientCredentials, +-) +-import os +-import sys +-import unittest +- +-sys.path.insert(0, os.path.abspath(os.pardir)) +- +- +-class ClientCredentialsTestSpotipy(unittest.TestCase): +- """ +- These tests require user authentication - provide client credentials using +- the following environment variables +- +- :: +- +- 'SPOTIPY_CLIENT_USERNAME' +- 'SPOTIPY_CLIENT_ID' +- 'SPOTIPY_CLIENT_SECRET' +- 'SPOTIPY_REDIRECT_URI' +- """ +- +- @classmethod +- def setUpClass(self): +- self.spotify = Spotify( +- client_credentials_manager=SpotifyClientCredentials()) +- self.spotify.trace = False +- +- muse_urn = 'spotify:artist:12Chz98pHFMPJEknJQMWvI' +- +- def test_request_with_token(self): +- artist = self.spotify.artist(self.muse_urn) +- self.assertTrue(artist['name'] == 'Muse') +- +- +-if __name__ == '__main__': +- unittest.main() diff --git a/dev-python/spotipy/metadata.xml b/dev-python/spotipy/metadata.xml new file mode 100644 index 0000000..dd0bd9c --- /dev/null +++ b/dev-python/spotipy/metadata.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> + +<pkgmetadata> + <maintainer type="person"> + <email>[email protected]</email> + <name>Andrew Ammerlaan</name> + </maintainer> + <maintainer type="project"> + <email>[email protected]</email> + <name>Proxy Maintainers</name> + </maintainer> +</pkgmetadata> diff --git a/dev-python/spotipy/spotipy-2.7.1.ebuild b/dev-python/spotipy/spotipy-2.7.1.ebuild new file mode 100644 index 0000000..de81368 --- /dev/null +++ b/dev-python/spotipy/spotipy-2.7.1.ebuild @@ -0,0 +1,41 @@ +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +PYTHON_COMPAT=( python3_{6,7,8} ) + +inherit distutils-r1 + +DESCRIPTION="A light weight Python library for the Spotify Web API" +HOMEPAGE="https://spotipy.readthedocs.io + https://github.com/plamere/spotipy" +SRC_URI="https://github.com/plamere/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" + +IUSE="examples" + +LICENSE="MIT" +KEYWORDS="~amd64 ~x86 " +SLOT="0" + +RDEPEND=" + dev-python/requests[${PYTHON_USEDEP}] + dev-python/six[${PYTHON_USEDEP}] + media-sound/spotify" + +DEPEND="test? ( dev-python/mock[${PYTHON_USEDEP}] )" + +distutils_enable_sphinx docs +distutils_enable_tests pytest + +PATCHES="${FILESDIR}/${P}-skip-online-test.patch" + +python_test() { + pytest -vv tests || die "Tests fail with ${EPYTHON}" +} + +python_install_all() { + use examples && dodoc -r examples + + distutils-r1_python_install_all +}
