Browse Source

Merge branch 'master' of github.com:weskerfoot/Spotify-MPD-Sync

pull/4/head
Wesley Kerfoot 6 years ago
parent
commit
a694e74f4c
  1. 5
      requirements.txt
  2. 6
      setup.py
  3. 104
      spotify_mpd_sync/msplaylist/authenticate.py
  4. 39
      spotify_mpd_sync/msplaylist/spotify.py

5
requirements.txt

@ -1,9 +1,14 @@
bottle==0.12.16
certifi==2019.3.9 certifi==2019.3.9
cffi==1.12.3 cffi==1.12.3
chardet==3.0.4 chardet==3.0.4
gevent==1.4.0
greenlet==0.4.15
httplib2==0.12.3
idna==2.8 idna==2.8
pycparser==2.19 pycparser==2.19
python-mpd2==1.0.0 python-mpd2==1.0.0
requests==2.21.0 requests==2.21.0
spotify-mpd-sync-weskerfoot==0.0.1
spotipy==2.4.4 spotipy==2.4.4
urllib3==1.24.2 urllib3==1.24.2

6
setup.py

@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup( setuptools.setup(
name="spotify-mpd-sync-weskerfoot", name="spotify-mpd-sync-weskerfoot",
version="0.0.1", version="0.0.2",
author="Wesley Kerfoot", author="Wesley Kerfoot",
author_email="wes@wesk.tech", author_email="wes@wesk.tech",
description="Synchronize Spotify Playlist to MPD", description="Synchronize Spotify Playlist to MPD",
@ -15,7 +15,9 @@ setuptools.setup(
packages=setuptools.find_packages(), packages=setuptools.find_packages(),
install_requires = [ install_requires = [
"spotipy>=2.4.4", "spotipy>=2.4.4",
"python-mpd2>=1.0.0" "python-mpd2>=1.0.0",
"bottle>=0.12.16",
"gevent>=1.4.0"
], ],
classifiers= [ classifiers= [
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",

104
spotify_mpd_sync/msplaylist/authenticate.py

@ -0,0 +1,104 @@
# shows a user's playlists (need to be authenticated via oauth)
import threading
import spotipy.oauth2 as oauth2
import spotipy
import queue
import os
from bottle import route, run, response, request
auth_token_queue = queue.Queue()
event_queue = queue.Queue()
@route('/')
def index():
auth_code = request.query.code
if auth_code:
auth_token_queue.put(auth_code)
return "It worked! You may close this tab now"
return "Oops! Something went wrong. Please file a bug report"
def wait_for_done(task):
server = threading.Thread(target=task)
server.daemon = True
server.start()
while True:
event = event_queue.get()
if event == "done":
break
def run_server():
threading.Thread(target= lambda: wait_for_done(lambda: run(quiet=True,
host='localhost',
port=8080))).start()
def prompt_for_user_token(username, scope=None, client_id = None,
client_secret = None, redirect_uri = None, cache_path = None):
"""
prompts the user to login if necessary and returns
the user token suitable for use with the spotipy.Spotify
constructor
Parameters:
- username - the Spotify username
- scope - the desired scope of the request
- client_id - the client id of your app
- client_secret - the client secret of your app
- redirect_uri - the redirect URI of your app
- cache_path - path to location to save tokens
"""
if not client_id:
client_id = os.getenv("SPOTIPY_CLIENT_ID")
if not client_secret:
client_secret = os.getenv("SPOTIPY_CLIENT_SECRET")
if not redirect_uri:
redirect_uri = os.getenv("SPOTIPY_REDIRECT_URI", "http://localhost:8080")
if not client_id:
print('''
You need to set your Spotify API credentials. You can do this by
setting environment variables like so:
export SPOTIPY_CLIENT_ID='your-spotify-client-id'
export SPOTIPY_CLIENT_SECRET='your-spotify-client-secret'
export SPOTIPY_REDIRECT_URI='your-app-redirect-url'
Get your credentials at
https://developer.spotify.com/my-applications
''')
raise spotipy.SpotifyException(550, -1, 'no credentials set')
cache_path = cache_path or ".cache-" + username
sp_oauth = oauth2.SpotifyOAuth(client_id, client_secret, redirect_uri,
scope=scope, cache_path=cache_path)
# try to get a valid token for this user, from the cache,
# if not in the cache, the create a new (this will send
# the user to a web page where they can authorize this app)
token_info = sp_oauth.get_cached_token()
if not token_info:
run_server()
auth_url = sp_oauth.get_authorize_url()
try:
import webbrowser
webbrowser.open(auth_url)
except:
print("Please navigate here: %s" % auth_url)
response = "%s?code=%s" % (redirect_uri, auth_token_queue.get())
event_queue.put("done")
code = sp_oauth.parse_response_code(response)
token_info = sp_oauth.get_access_token(code)
# Auth'ed API request
if token_info:
return token_info['access_token']
else:
return None

39
spotify_mpd_sync/msplaylist/spotify.py

@ -1,23 +1,32 @@
#! /usr/bin/env python #! /usr/bin/env python
import gevent.monkey
gevent.monkey.patch_all()
import spotipy import spotipy
from spotipy.oauth2 import SpotifyClientCredentials from spotipy.oauth2 import SpotifyClientCredentials
from spotipy.util import prompt_for_user_token
from mpd import MPDClient from mpd import MPDClient
from mpd.base import CommandError from mpd.base import CommandError
from collections import defaultdict from collections import defaultdict
from re import sub from re import sub
from os import environ from os import environ
import spotipy.util as util
import argparse
from spotify_mpd_sync.msplaylist.authenticate import prompt_for_user_token
class Spotify(): class Spotify():
def __init__(self): def __init__(self, host="localhost", port=6600):
self.username = environ.get("SPOTIFY_USERNAME") self.username = environ.get("SPOTIFY_USERNAME")
self.client_credentials_manager = SpotifyClientCredentials()
self.sp = spotipy.Spotify( scope = "playlist-read-private"
client_credentials_manager=self.client_credentials_manager
) token = prompt_for_user_token(self.username, scope)
if token:
self.sp = spotipy.Spotify(auth=token)
self.mpd_client = MPDClient() self.mpd_client = MPDClient()
self.mpd_client.connect("127.0.0.1", 6600) self.mpd_client.connect(host, port)
self._playlists = defaultdict(lambda: []) self._playlists = defaultdict(lambda: [])
@ -81,5 +90,21 @@ class Spotify():
def run_sync(): def run_sync():
spotify = Spotify() parser = argparse.ArgumentParser()
parser.add_argument("-H",
"--host",
default="localhost",
help="The MPD server you would like spotsync to use, defaults localhost")
parser.add_argument("-P",
"--port",
type=int,
default=6600,
help="The MPD port you would like spotsync to use, defaults to 6600")
args = parser.parse_args()
spotify = Spotify(host=args.host,
port=args.port)
spotify.persist_playlists() spotify.persist_playlists()

Loading…
Cancel
Save