Browse Source

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

pull/4/head
Wesley Kerfoot 5 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
cffi==1.12.3
chardet==3.0.4
gevent==1.4.0
greenlet==0.4.15
httplib2==0.12.3
idna==2.8
pycparser==2.19
python-mpd2==1.0.0
requests==2.21.0
spotify-mpd-sync-weskerfoot==0.0.1
spotipy==2.4.4
urllib3==1.24.2

6
setup.py

@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="spotify-mpd-sync-weskerfoot",
version="0.0.1",
version="0.0.2",
author="Wesley Kerfoot",
author_email="wes@wesk.tech",
description="Synchronize Spotify Playlist to MPD",
@ -15,7 +15,9 @@ setuptools.setup(
packages=setuptools.find_packages(),
install_requires = [
"spotipy>=2.4.4",
"python-mpd2>=1.0.0"
"python-mpd2>=1.0.0",
"bottle>=0.12.16",
"gevent>=1.4.0"
],
classifiers= [
"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
import gevent.monkey
gevent.monkey.patch_all()
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
from spotipy.util import prompt_for_user_token
from mpd import MPDClient
from mpd.base import CommandError
from collections import defaultdict
from re import sub
from os import environ
import spotipy.util as util
import argparse
from spotify_mpd_sync.msplaylist.authenticate import prompt_for_user_token
class Spotify():
def __init__(self):
def __init__(self, host="localhost", port=6600):
self.username = environ.get("SPOTIFY_USERNAME")
self.client_credentials_manager = SpotifyClientCredentials()
self.sp = spotipy.Spotify(
client_credentials_manager=self.client_credentials_manager
)
scope = "playlist-read-private"
token = prompt_for_user_token(self.username, scope)
if token:
self.sp = spotipy.Spotify(auth=token)
self.mpd_client = MPDClient()
self.mpd_client.connect("127.0.0.1", 6600)
self.mpd_client.connect(host, port)
self._playlists = defaultdict(lambda: [])
@ -81,5 +90,21 @@ class Spotify():
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()

Loading…
Cancel
Save