Mixonomer/spotify/tasks/play_user_playlist.py

105 lines
3.4 KiB
Python
Raw Normal View History

2019-08-12 00:34:04 +01:00
from google.cloud import firestore
import datetime
import logging
from spotframework.engine.playlistengine import PlaylistEngine, PlaylistSource, RecommendationSource
from spotframework.engine.processor.shuffle import Shuffle
from spotframework.engine.processor.sort import SortReleaseDate
from spotframework.engine.processor.deduplicate import DeduplicateByID
2019-08-12 00:34:04 +01:00
from spotframework.player.player import Player
import spotify.db.database as database
from spotify.db.part_generator import PartGenerator
2019-08-12 00:34:04 +01:00
db = firestore.Client()
logger = logging.getLogger(__name__)
2019-08-12 00:34:04 +01:00
def play_user_playlist(username,
playlist_type='default',
parts=None,
playlists=None,
shuffle=False,
include_recommendations=True,
recommendation_sample=10,
day_boundary=10,
add_this_month=False,
add_last_month=False,
device_name=None):
2019-08-12 00:34:04 +01:00
users = database.get_user_query_stream(username)
2019-08-12 00:34:04 +01:00
logger.info(f'playing for {username}')
2019-08-12 00:34:04 +01:00
if len(users) == 1:
if parts is None and playlists is None:
2019-08-12 00:34:04 +01:00
logger.critical(f'no playlists to use for creation ({username})')
return None
if parts is None:
parts = []
if playlists is None:
playlists = []
2019-08-12 00:34:04 +01:00
if len(parts) == 0 and len(playlists) == 0:
logger.critical(f'no playlists to use for creation ({username})')
return None
2019-08-12 00:34:04 +01:00
net = database.get_authed_network(username)
2019-08-12 00:34:04 +01:00
device = None
if device_name:
devices = net.get_available_devices()
if devices and len(devices) > 0:
device = next((i for i in devices if i.name == device_name), None)
if device is None:
logger.error(f'error selecting device {device_name} to play on')
else:
logger.warning(f'no available devices to play')
2019-08-12 00:34:04 +01:00
engine = PlaylistEngine(net)
player = Player(net)
2019-08-12 00:34:04 +01:00
processors = [DeduplicateByID()]
if shuffle:
processors.append(Shuffle())
else:
processors.append(SortReleaseDate(reverse=True))
2019-08-12 00:34:04 +01:00
submit_parts = parts
part_generator = PartGenerator(user_id=users[0].id)
2019-08-12 00:34:04 +01:00
for part in playlists:
submit_parts += part_generator.get_recursive_parts(part)
2019-08-12 00:34:04 +01:00
submit_parts = [i for i in {j for j in submit_parts}]
params = [
PlaylistSource.Params(names=submit_parts, processors=processors)
]
if include_recommendations:
params.append(RecommendationSource.Params(recommendation_limit=int(recommendation_sample)))
2019-08-12 00:34:04 +01:00
if playlist_type == 'recents':
2019-09-15 15:33:29 +01:00
boundary_date = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=int(day_boundary))
tracks = engine.get_recent_playlist(params=params,
boundary_date=boundary_date,
add_this_month=add_this_month,
add_last_month=add_last_month)
2019-08-12 00:34:04 +01:00
else:
tracks = engine.make_playlist(params=params)
2019-08-12 00:34:04 +01:00
player.play(tracks=tracks, device=device)
2019-08-12 00:34:04 +01:00
else:
logger.critical(f'multiple/no user(s) found ({username})')
return None