imported spotframework, utilising for running playlists locally
This commit is contained in:
parent
7272379a9c
commit
57408efcda
@ -7,6 +7,7 @@ google-api-core==1.14.2
|
|||||||
google-auth==1.6.3
|
google-auth==1.6.3
|
||||||
google-cloud-core==1.0.3
|
google-cloud-core==1.0.3
|
||||||
google-cloud-firestore==1.4.0
|
google-cloud-firestore==1.4.0
|
||||||
|
google-cloud-logging==1.12.1
|
||||||
google-cloud-pubsub==0.45.0
|
google-cloud-pubsub==0.45.0
|
||||||
google-cloud-tasks==1.2.0
|
google-cloud-tasks==1.2.0
|
||||||
googleapis-common-protos==1.6.0
|
googleapis-common-protos==1.6.0
|
||||||
|
@ -9,6 +9,8 @@ from google.cloud import tasks_v2
|
|||||||
from google.protobuf import timestamp_pb2
|
from google.protobuf import timestamp_pb2
|
||||||
from werkzeug.security import check_password_hash, generate_password_hash
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
|
||||||
|
from spotify.tasks.run_user_playlist import run_user_playlist as run_user_playlist
|
||||||
|
|
||||||
import spotify.api.database as database
|
import spotify.api.database as database
|
||||||
|
|
||||||
blueprint = Blueprint('api', __name__)
|
blueprint = Blueprint('api', __name__)
|
||||||
@ -307,7 +309,7 @@ def run_playlist():
|
|||||||
|
|
||||||
if playlist_name:
|
if playlist_name:
|
||||||
|
|
||||||
execute_playlist(session['username'], playlist_name)
|
run_user_playlist(session['username'], playlist_name)
|
||||||
|
|
||||||
return jsonify({'message': 'execution requested', 'status': 'success'}), 200
|
return jsonify({'message': 'execution requested', 'status': 'success'}), 200
|
||||||
|
|
||||||
@ -325,7 +327,9 @@ def run_playlist_task():
|
|||||||
payload = request.get_data(as_text=True)
|
payload = request.get_data(as_text=True)
|
||||||
if payload:
|
if payload:
|
||||||
payload = json.loads(payload)
|
payload = json.loads(payload)
|
||||||
execute_playlist(payload['username'], payload['name'])
|
|
||||||
|
run_user_playlist(payload['username'], payload['name'])
|
||||||
|
|
||||||
return jsonify({'message': 'executed playlist', 'status': 'success'}), 200
|
return jsonify({'message': 'executed playlist', 'status': 'success'}), 200
|
||||||
else:
|
else:
|
||||||
return jsonify({'error': 'unauthorized'}), 401
|
return jsonify({'error': 'unauthorized'}), 401
|
||||||
@ -455,7 +459,7 @@ def execute_user(username):
|
|||||||
# execute_playlist(username, iterate_playlist['name'])
|
# execute_playlist(username, iterate_playlist['name'])
|
||||||
|
|
||||||
|
|
||||||
def execute_playlist(username, name):
|
def push_run_user_playlist_message(username, name):
|
||||||
|
|
||||||
data = u'{}'.format(name)
|
data = u'{}'.format(name)
|
||||||
data = data.encode('utf-8')
|
data = data.encode('utf-8')
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import requests
|
|
||||||
from base64 import b64encode
|
|
||||||
from google.cloud import firestore
|
from google.cloud import firestore
|
||||||
|
|
||||||
|
from spotframework.net.user import User
|
||||||
|
from spotframework.net.network import Network
|
||||||
|
|
||||||
db = firestore.Client()
|
db = firestore.Client()
|
||||||
|
|
||||||
|
|
||||||
@ -14,30 +15,12 @@ def create_playlist(username, name):
|
|||||||
user_dict = users[0].to_dict()
|
user_dict = users[0].to_dict()
|
||||||
spotify_keys = db.document('key/spotify').get().to_dict()
|
spotify_keys = db.document('key/spotify').get().to_dict()
|
||||||
|
|
||||||
idsecret = b64encode(bytes(spotify_keys['clientid'] + ':' + spotify_keys['clientsecret'], "utf-8")).decode("ascii")
|
net = Network(User(spotify_keys['clientid'],
|
||||||
|
spotify_keys['clientsecret'],
|
||||||
|
user_dict['access_token'],
|
||||||
|
user_dict['refresh_token']))
|
||||||
|
|
||||||
token_headers = {'Authorization': 'Basic %s' % idsecret}
|
net.create_playlist(net.user.username, name)
|
||||||
headers = {"Content-Type": "application/json"}
|
|
||||||
|
|
||||||
data = {"grant_type": "refresh_token", "refresh_token": user_dict['refresh_token']}
|
else:
|
||||||
|
raise ValueError('no/multiple username(s)')
|
||||||
token_req = requests.post('https://accounts.spotify.com/api/token', data=data, headers=token_headers)
|
|
||||||
|
|
||||||
if 200 <= token_req.status_code < 300:
|
|
||||||
accesstoken = token_req.json()['access_token']
|
|
||||||
|
|
||||||
json = {"name": name, "public": True, "collaborative": False}
|
|
||||||
|
|
||||||
headers['Authorization'] = 'Bearer ' + accesstoken
|
|
||||||
|
|
||||||
info_id = requests.get('https://api.spotify.com/v1/me', headers=headers).json()['id']
|
|
||||||
|
|
||||||
play_req = requests.post(f'https://api.spotify.com/v1/users/{info_id}/playlists', json=json, headers=headers)
|
|
||||||
|
|
||||||
resp = play_req.json()
|
|
||||||
|
|
||||||
return resp["id"]
|
|
||||||
|
|
||||||
else:
|
|
||||||
print(token_req.status_code)
|
|
||||||
raise Exception('failed to get access token')
|
|
||||||
|
@ -2,13 +2,30 @@ from flask import Flask, render_template, redirect, request, session, flash, url
|
|||||||
from google.cloud import firestore
|
from google.cloud import firestore
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
from spotify.auth import auth_blueprint
|
from spotify.auth import auth_blueprint
|
||||||
from spotify.api import api_blueprint
|
from spotify.api import api_blueprint
|
||||||
|
|
||||||
|
from google.cloud.logging.handlers import CloudLoggingHandler
|
||||||
|
from google.cloud import logging as glogging
|
||||||
|
|
||||||
# Project ID is determined by the GCLOUD_PROJECT environment variable
|
# Project ID is determined by the GCLOUD_PROJECT environment variable
|
||||||
db = firestore.Client()
|
db = firestore.Client()
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.setLevel('INFO')
|
||||||
|
|
||||||
|
log_format = '%(levelname)s %(name)s:%(funcName)s - %(message)s'
|
||||||
|
formatter = logging.Formatter(log_format)
|
||||||
|
|
||||||
|
client = glogging.Client()
|
||||||
|
handler = CloudLoggingHandler(client)
|
||||||
|
|
||||||
|
handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
logger.addHandler(handler)
|
||||||
|
|
||||||
app = Flask(__name__, static_folder=os.path.join(os.path.dirname(__file__), '..', 'build'), template_folder="templates")
|
app = Flask(__name__, static_folder=os.path.join(os.path.dirname(__file__), '..', 'build'), template_folder="templates")
|
||||||
app.secret_key = db.collection(u'spotify').document(u'config').get().to_dict()['secret_key']
|
app.secret_key = db.collection(u'spotify').document(u'config').get().to_dict()['secret_key']
|
||||||
app.register_blueprint(auth_blueprint, url_prefix='/auth')
|
app.register_blueprint(auth_blueprint, url_prefix='/auth')
|
||||||
|
0
spotify/tasks/__init__.py
Normal file
0
spotify/tasks/__init__.py
Normal file
111
spotify/tasks/run_user_playlist.py
Normal file
111
spotify/tasks/run_user_playlist.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
from google.cloud import firestore
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from spotframework.engine.playlistengine import PlaylistEngine
|
||||||
|
from spotframework.engine.filter.shuffle import Shuffle
|
||||||
|
from spotframework.engine.filter.sortreversereleasedate import SortReverseReleaseDate
|
||||||
|
from spotframework.engine.filter.deduplicatebyid import DeduplicateByID
|
||||||
|
|
||||||
|
from spotframework.net.network import Network
|
||||||
|
from spotframework.net.user import User
|
||||||
|
|
||||||
|
db = firestore.Client()
|
||||||
|
|
||||||
|
captured_playlists = []
|
||||||
|
|
||||||
|
|
||||||
|
def run_user_playlist(username, playlist_name):
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
users = [i for i in db.collection(u'spotify_users').where(u'username', u'==', username).stream()]
|
||||||
|
|
||||||
|
logger.info(f'{username} / {playlist_name}')
|
||||||
|
|
||||||
|
if len(users) == 1:
|
||||||
|
|
||||||
|
user_dict = users[0].to_dict()
|
||||||
|
|
||||||
|
playlist_collection = db.collection(u'spotify_users', u'{}'.format(users[0].id), 'playlists')
|
||||||
|
|
||||||
|
playlists = [i for i in playlist_collection.where(u'name', u'==', playlist_name).stream()]
|
||||||
|
|
||||||
|
if len(playlists) == 1:
|
||||||
|
|
||||||
|
playlist_dict = playlists[0].to_dict()
|
||||||
|
|
||||||
|
if playlist_dict['playlist_id'] is None:
|
||||||
|
logger.critical(f'no playlist id to populate ({username}/{playlist_name})')
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(playlist_dict['parts']) == 0 and len(playlist_dict['playlist_references']) == 0:
|
||||||
|
logger.critical(f'no playlists to use for creation ({username}/{playlist_name})')
|
||||||
|
return
|
||||||
|
|
||||||
|
spotify_keys = db.document('key/spotify').get().to_dict()
|
||||||
|
|
||||||
|
net = Network(User(spotify_keys['clientid'],
|
||||||
|
spotify_keys['clientsecret'],
|
||||||
|
user_dict['access_token'],
|
||||||
|
user_dict['refresh_token']))
|
||||||
|
|
||||||
|
engine = PlaylistEngine(net)
|
||||||
|
engine.load_user_playlists()
|
||||||
|
|
||||||
|
processors = [DeduplicateByID()]
|
||||||
|
|
||||||
|
if playlist_dict['shuffle'] is True:
|
||||||
|
processors.append(Shuffle())
|
||||||
|
else:
|
||||||
|
processors.append(SortReverseReleaseDate())
|
||||||
|
|
||||||
|
global captured_playlists
|
||||||
|
captured_playlists = []
|
||||||
|
|
||||||
|
submit_parts = playlist_dict['parts'] + generate_parts(users[0].id, playlist_dict['name'])
|
||||||
|
|
||||||
|
submit_parts = [i for i in {j for j in submit_parts}]
|
||||||
|
|
||||||
|
if playlist_dict['type'] == 'recents':
|
||||||
|
boundary_date = datetime.datetime.now() - datetime.timedelta(days=int(playlist_dict['day_boundary']))
|
||||||
|
tracks = engine.get_recent_playlist(boundary_date,
|
||||||
|
submit_parts,
|
||||||
|
processors,
|
||||||
|
include_recommendations=playlist_dict['include_recommendations'],
|
||||||
|
recommendation_limit=int(playlist_dict['recommendation_sample']))
|
||||||
|
else:
|
||||||
|
tracks = engine.make_playlist(submit_parts,
|
||||||
|
processors,
|
||||||
|
include_recommendations=playlist_dict['include_recommendations'],
|
||||||
|
recommendation_limit=int(playlist_dict['recommendation_sample']))
|
||||||
|
|
||||||
|
engine.execute_playlist(tracks, playlist_dict['playlist_id'])
|
||||||
|
engine.change_description(sorted(submit_parts), playlist_dict['playlist_id'])
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.critical(f'multiple/no playlists found ({username}/{playlist_name})')
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.critical(f'multiple/no user(s) found ({username}/{playlist_name})')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def generate_parts(user_id, name):
|
||||||
|
|
||||||
|
playlist_doc = [i.to_dict() for i in
|
||||||
|
db.document(u'spotify_users/{}'.format(user_id))
|
||||||
|
.collection(u'playlists')
|
||||||
|
.where(u'name', '==', name).stream()][0]
|
||||||
|
|
||||||
|
return_parts = playlist_doc['parts']
|
||||||
|
|
||||||
|
captured_playlists.append(name)
|
||||||
|
|
||||||
|
for i in playlist_doc['playlist_references']:
|
||||||
|
if i not in captured_playlists:
|
||||||
|
return_parts += generate_parts(user_id, i)
|
||||||
|
|
||||||
|
return return_parts
|
Loading…
Reference in New Issue
Block a user