environment-dependent tag update

error checking
sidebar links
docstrings

closes #13
This commit is contained in:
aj 2020-05-08 15:19:27 +01:00
parent a01b449325
commit e3fd4bb6d5
9 changed files with 97 additions and 54 deletions

View File

@ -1,9 +1,11 @@
from flask import Blueprint, jsonify, request from flask import Blueprint, jsonify, request
import logging import logging
import os
from music.api.decorators import login_or_basic_auth from music.api.decorators import login_or_basic_auth
from music.cloud.function import update_tag from music.cloud.function import update_tag as serverless_update_tag
from music.tasks.update_tag import update_tag
from music.model.tag import Tag from music.model.tag import Tag
@ -56,53 +58,62 @@ def put_tag(tag_id, user):
request_json = request.get_json() request_json = request.get_json()
if request_json.get('name'): if request_json.get('name'):
db_tag.name = request_json['name'] db_tag.name = request_json['name'].strip()
update_required = False update_required = False
tracks = []
if request_json.get('tracks') is not None: if request_json.get('tracks') is not None:
update_required = True update_required = True
for track in request_json['tracks']: db_tag.tracks = [
if track.get('name') and track.get('artist'): {
tracks.append({ 'name': track['name'].strip(),
'name': track['name'], 'artist': track['artist'].strip()
'artist': track['artist'] }
}) for track in request_json['tracks']
db_tag.tracks = tracks if track.get('name') and track.get('artist')
]
albums = []
if request_json.get('albums') is not None: if request_json.get('albums') is not None:
update_required = True update_required = True
for album in request_json['albums']: db_tag.albums = [
if album.get('name') and album.get('artist'): {
albums.append({ 'name': album['name'].strip(),
'name': album['name'], 'artist': album['artist'].strip()
'artist': album['artist'] }
}) for album in request_json['albums']
db_tag.albums = albums if album.get('name') and album.get('artist')
]
artists = []
if request_json.get('artists') is not None: if request_json.get('artists') is not None:
update_required = True update_required = True
for artist in request_json['artists']: db_tag.artists = [
if artist.get('name'): {
artists.append({ 'name': artist['name'].strip()
'name': artist['name'] }
}) for artist in request_json['artists']
db_tag.artists = artists if artist.get('name')
]
if update_required:
update_tag(username=user.username, tag_id=tag_id)
db_tag.update() db_tag.update()
if update_required:
# queue serverless refresh
if os.environ.get('DEPLOY_DESTINATION', None) == 'PROD':
serverless_update_tag(username=user.username, tag_id=tag_id)
else:
update_tag(username=user.username, tag_id=tag_id)
return jsonify({"message": 'tag updated', "status": "success"}), 200 return jsonify({"message": 'tag updated', "status": "success"}), 200
def post_tag(tag_id, user): def post_tag(tag_id, user):
logger.info(f'creating {tag_id} for {user.username}') logger.info(f'creating {tag_id} for {user.username}')
tag_id = tag_id.replace(' ', '_') tag_id = tag_id.replace(' ', '_').strip()
existing_ids = [i.tag_id for i in Tag.collection.parent(user.key).fetch()]
while tag_id in existing_ids:
tag_id += '1'
tag = Tag(parent=user.key) tag = Tag(parent=user.key)
tag.tag_id = tag_id tag.tag_id = tag_id
@ -126,5 +137,10 @@ def delete_tag(tag_id, user):
@login_or_basic_auth @login_or_basic_auth
def tag_refresh(tag_id, user=None): def tag_refresh(tag_id, user=None):
logger.info(f'updating {tag_id} tag for {user.username}') logger.info(f'updating {tag_id} tag for {user.username}')
if os.environ.get('DEPLOY_DESTINATION', None) == 'PROD':
serverless_update_tag(username=user.username, tag_id=tag_id)
else:
update_tag(username=user.username, tag_id=tag_id) update_tag(username=user.username, tag_id=tag_id)
return jsonify({"message": 'tag updated', "status": "success"}), 200 return jsonify({"message": 'tag updated', "status": "success"}), 200

View File

@ -6,5 +6,15 @@ logger = logging.getLogger(__name__)
def update_tag(username, tag_id): def update_tag(username, tag_id):
"""Queue serverless tag update for user"""
logger.info(f'queuing {tag_id} update for {username}') logger.info(f'queuing {tag_id} update for {username}')
if username is None:
logger.error(f'no username provided')
return
if tag_id is None:
logger.error(f'no tag_id provided for {username}')
return
publisher.publish('projects/sarsooxyz/topics/update_tag', b'', tag_id=tag_id, username=username) publisher.publish('projects/sarsooxyz/topics/update_tag', b'', tag_id=tag_id, username=username)

View File

@ -20,6 +20,7 @@ logger = logging.getLogger(__name__)
def execute_all_user_playlists(): def execute_all_user_playlists():
"""Create user playlist refresh task for all users"""
seconds_delay = 0 seconds_delay = 0
logger.info('running') logger.info('running')
@ -48,10 +49,13 @@ def execute_all_user_playlists():
def execute_user_playlists(username): def execute_user_playlists(username):
"""Refresh all playlists for given user, environment dependent"""
user = User.collection.filter('username', '==', username.strip().lower()).get() user = User.collection.filter('username', '==', username.strip().lower()).get()
if user is None: if user is None:
logger.error(f'user {username} not found') logger.error(f'user {username} not found')
return
playlists = Playlist.collection.parent(user.key).fetch() playlists = Playlist.collection.parent(user.key).fetch()
@ -70,6 +74,7 @@ def execute_user_playlists(username):
def create_run_user_playlist_task(username, playlist_name, delay=0): def create_run_user_playlist_task(username, playlist_name, delay=0):
"""Create tasks for a users given playlist"""
task = { task = {
'app_engine_http_request': { # Specify the type of request. 'app_engine_http_request': { # Specify the type of request.
@ -108,6 +113,8 @@ def create_play_user_playlist_task(username,
add_last_month=False, add_last_month=False,
delay=0, delay=0,
device_name=None): device_name=None):
"""Create tasks for a users given scratch playlist"""
task = { task = {
'app_engine_http_request': { # Specify the type of request. 'app_engine_http_request': { # Specify the type of request.
'http_method': 'POST', 'http_method': 'POST',
@ -142,6 +149,7 @@ def create_play_user_playlist_task(username,
def execute_all_user_playlist_stats(): def execute_all_user_playlist_stats():
""""Create user playlist stats refresh task for all users"""
seconds_delay = 0 seconds_delay = 0
logger.info('running') logger.info('running')
@ -163,15 +171,17 @@ def execute_all_user_playlist_stats():
def execute_user_playlist_stats(username): def execute_user_playlist_stats(username):
"""Refresh all playlist stats for given user, environment dependent"""
user = User.collection.filter('username', '==', username.strip().lower()).get() user = User.collection.filter('username', '==', username.strip().lower()).get()
if user is None: if user is None:
logger.error(f'user {username} not found') logger.error(f'user {username} not found')
return
playlists = Playlist.collection.parent(user.key).fetch() playlists = Playlist.collection.parent(user.key).fetch()
seconds_delay = 0 seconds_delay = 0
logger.info(f'running {username}') logger.info(f'running stats for {username}')
if user.lastfm_username and len(user.lastfm_username) > 0: if user.lastfm_username and len(user.lastfm_username) > 0:
for playlist in playlists: for playlist in playlists:
@ -188,6 +198,7 @@ def execute_user_playlist_stats(username):
def create_refresh_user_task(username, delay=0): def create_refresh_user_task(username, delay=0):
"""Create user playlist stats refresh task"""
task = { task = {
'app_engine_http_request': { # Specify the type of request. 'app_engine_http_request': { # Specify the type of request.
@ -209,6 +220,7 @@ def create_refresh_user_task(username, delay=0):
def create_refresh_playlist_task(username, playlist_name, delay=0): def create_refresh_playlist_task(username, playlist_name, delay=0):
"""Create user playlist stats refresh tasks"""
track_task = { track_task = {
'app_engine_http_request': { # Specify the type of request. 'app_engine_http_request': { # Specify the type of request.

View File

@ -46,7 +46,7 @@ class Playlist(Model):
add_this_month = BooleanField(default=False) add_this_month = BooleanField(default=False)
day_boundary = NumberField(default=21) day_boundary = NumberField(default=21)
chart_range = TextField(default='1month') chart_range = TextField(default='MONTH')
chart_limit = NumberField(default=50) chart_limit = NumberField(default=50)
def to_dict(self): def to_dict(self):

View File

@ -12,7 +12,10 @@ logger = logging.getLogger(__name__)
def create_playlist(user, name): def create_playlist(user, name):
logger.info(f'creating spotify playlist for {user.username} / {name}') logger.info(f'creating spotify playlist for {user.username} / {name}')
if user is not None: if user is None:
logger.error(f'{user.username} not provided')
return
net = database.get_authed_spotify_network(user) net = database.get_authed_spotify_network(user)
playlist = net.create_playlist(net.user.username, name) playlist = net.create_playlist(net.user.username, name)
@ -22,6 +25,3 @@ def create_playlist(user, name):
else: else:
logger.error(f'no response received {user.username} / {name}') logger.error(f'no response received {user.username} / {name}')
return return
else:
logger.error(f'{user.username} not provided')

View File

@ -34,10 +34,6 @@ def play_user_playlist(username,
logger.info(f'playing for {username}') logger.info(f'playing for {username}')
if user is None:
logger.critical(f'{username} not found')
return
if parts is None and playlists is None: if parts is None and playlists is None:
logger.critical(f'no playlists to use for creation ({username})') logger.critical(f'no playlists to use for creation ({username})')
return None return None

View File

@ -26,16 +26,14 @@ logger = logging.getLogger(__name__)
def run_user_playlist(username, playlist_name): def run_user_playlist(username, playlist_name):
"""Generate and upadate a user's playlist""" """Generate and upadate a user's playlist"""
user = User.collection.filter('username', '==', username.strip().lower()).get() user = User.collection.filter('username', '==', username.strip().lower()).get()
if user is None:
logger.error(f'user {username} not found')
logger.info(f'running {username} / {playlist_name}')
# PRE-RUN CHECKS # PRE-RUN CHECKS
if user is None: if user is None:
logger.critical(f'{username} not found') logger.error(f'user {username} not found')
return return
logger.info(f'running {username} / {playlist_name}')
playlist = Playlist.collection.parent(user.key).filter('name', '==', playlist_name).get() playlist = Playlist.collection.parent(user.key).filter('name', '==', playlist_name).get()
if playlist is None: if playlist is None:
@ -49,6 +47,11 @@ def run_user_playlist(username, playlist_name):
# END CHECKS # END CHECKS
net = database.get_authed_spotify_network(user) net = database.get_authed_spotify_network(user)
if net is None:
logger.error(f'no spotify network returned for {username}')
return
engine = PlaylistEngine(net) engine = PlaylistEngine(net)
part_generator = PartGenerator(user=user) part_generator = PartGenerator(user=user)

View File

@ -14,6 +14,8 @@ def update_tag(username, tag_id):
user = User.collection.filter('username', '==', username.strip().lower()).get() user = User.collection.filter('username', '==', username.strip().lower()).get()
if user is None: if user is None:
logger.error(f'user {username} not found') logger.error(f'user {username} not found')
return
tag = Tag.collection.parent(user.key).filter('tag_id', '==', tag_id).get() tag = Tag.collection.parent(user.key).filter('tag_id', '==', tag_id).get()
if tag is None: if tag is None:
@ -26,6 +28,10 @@ def update_tag(username, tag_id):
net = database.get_authed_lastfm_network(user) net = database.get_authed_lastfm_network(user)
if net is None:
logger.error(f'no last.fm network returned for {username}')
return
tag_count = 0 tag_count = 0
user_scrobbles = net.get_user_scrobble_count() user_scrobbles = net.get_user_scrobble_count()

View File

@ -141,7 +141,7 @@ class MusicTools extends Component {
<ListItemIcon><KeyboardBackspace /></ListItemIcon> <ListItemIcon><KeyboardBackspace /></ListItemIcon>
<ListItemText primary="Logout" /> <ListItemText primary="Logout" />
</ListItem> </ListItem>
<ListItem button key="sarsoo.xyz" component={Link} to='https://sarsoo.xyz'> <ListItem button key="sarsoo.xyz" onClick={(e) => { window.location.href = 'https://sarsoo.xyz' }}>
<ListItemIcon><ExitToApp /></ListItemIcon> <ListItemIcon><ExitToApp /></ListItemIcon>
<ListItemText primary="sarsoo.xyz" /> <ListItemText primary="sarsoo.xyz" />
</ListItem> </ListItem>