Skip to content

Commit

Permalink
Add support for dynamic lengths
Browse files Browse the repository at this point in the history
  • Loading branch information
peppys committed May 24, 2021
1 parent 25eddf9 commit 1207891
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.idea
.env
*.env
*.pyc
*.zip
.DS_Store
Expand Down
1 change: 1 addition & 0 deletions backend/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from api.webhooks import webhooks_router

app = Sanic(name='dj-pep-api')
app.config.RESPONSE_TIMEOUT = 300


@app.get('/')
Expand Down
26 changes: 17 additions & 9 deletions backend/api/taskhandlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,40 @@
from sanic.request import Request
from sanic.response import json

from lib.firestore.client import find_songs_by_status, SongStatus, update_by_id
from lib.firestore.client import find_song_by_id, find_songs_by_status, SongStatus, update_by_id

task_handlers_router = Blueprint('task_handlers_bp', url_prefix='/task-handlers')


@task_handlers_router.post('/song-player')
async def song_player_handler(request: Request):
logging.info(f'Received request: {request.body}')

payload = loads(request.body.decode())

logging.info(f'Parsed payload: {payload}')

song = find_song_by_id(payload['song_id'])
if song is None:
logging.error(f'Could not find song with id {payload["song_id"]}')
return json({'ok': True}, status=200)

if song['status'] != SongStatus.QUEUED.value:
logging.error(f'Unexpected status {song["status"]} for song {payload["song_id"]}')
return json({'ok': True}, status=200)

# update any songs that are playing, in-case the last task errored out
playing_songs = find_songs_by_status(SongStatus.PLAYING)
for playing_song in playing_songs:
update_by_id(playing_song['id'], {'status': SongStatus.PLAYED.value})

update_by_id(payload['song_id'], {'status': SongStatus.PLAYING.value,
'started_playing_at': datetime.utcnow().isoformat()})
update_by_id(song['id'], {'status': SongStatus.PLAYING.value,
'started_playing_at': datetime.utcnow().isoformat()})

print(f'Waiting 30 seconds')
length = song['preview_length'] or 30
print(f'Waiting {length} seconds')

await sleep(30)
await sleep(length)

update_by_id(payload['song_id'], {'status': SongStatus.PLAYED.value,
'finished_playing_at': datetime.utcnow().isoformat()})
update_by_id(song['id'], {'status': SongStatus.PLAYED.value,
'finished_playing_at': datetime.utcnow().isoformat()})

return json({'ok': True}, status=200)
6 changes: 3 additions & 3 deletions backend/api/webhooks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ async def twilio_handler(request: Request):

song_doc = add_song(song)

create_task_to_play_song(song_id=song_doc.id, song_url=song['preview_url'])
create_task_to_play_song(song_id=song_doc.id)
except Exception as e:
logging.error(
f'Could not search spotify for track: {str(e)} {traceback.format_exc()}')
logging.exception(
f'Could not search for track: {str(e)} {traceback.format_exc()}')

return text('Sorry I had trouble with that. Please try a different song!', 200)

Expand Down
4 changes: 2 additions & 2 deletions backend/lib/cloudtasks/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
client = tasks_v2.CloudTasksClient()


def create_task_to_play_song(song_id: str, song_url: str):
payload = {'song_id': song_id, 'song_url': song_url}
def create_task_to_play_song(song_id: str):
payload = {'song_id': song_id}

parent = client.queue_path(project=os.getenv('GOOGLE_PROJECT_ID'),
location='us-central1',
Expand Down
10 changes: 9 additions & 1 deletion backend/lib/firestore/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
from google.cloud.firestore_v1 import DocumentReference
from google.cloud.firestore_v1 import DocumentReference, DocumentSnapshot

cred = credentials.ApplicationDefault()
firebase_admin.initialize_app(cred, {
Expand Down Expand Up @@ -64,6 +64,14 @@ def find_songs_by_status(status: SongStatus) -> List[Dict]:
return [{**{'id': doc.id}, **doc.to_dict()} for doc in docs]


def find_song_by_id(song_id: str) -> Optional[Dict]:
doc: DocumentSnapshot = db.collection('songs').document(song_id).get()
if not doc.exists:
return None

return {**{'id': doc.id}, **doc.to_dict()}


def update_by_id(song_id: str, updates: Dict):
doc_ref: DocumentReference = db.collection('songs').document(song_id)
doc_ref.update(updates)
12 changes: 10 additions & 2 deletions backend/lib/itunes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
from typing import Dict

from aiofiles import tempfile
from aiohttp import ClientSession
from mutagen.mp4 import MP4


async def find_song(query: str) -> Dict:
Expand All @@ -11,7 +13,7 @@ async def find_song(query: str) -> Dict:
headers={'Authorization': f'Bearer {os.getenv("ITUNES_API_TOKEN")}'},
params={
'term': query,
'types': 'artists%2Csongs',
'types': 'artists,songs',
'limit': 10,
})
response.raise_for_status()
Expand All @@ -24,12 +26,18 @@ async def find_song(query: str) -> Dict:
raise Exception('Sorry could not find track')

song = songs[0]
preview_url = song['attributes']['previews'][0]['url']
async with tempfile.NamedTemporaryFile() as fp:
response = await session.get(preview_url)
await fp.write(await response.read())
audio = MP4(fp.name)

return {
'name': song['attributes']['name'],
'artists': [{'name': song['attributes']['artistName']}],
'album_name': song['attributes']['albumName'],
'preview_url': song['attributes']['previews'][0]['url'],
'preview_url': preview_url,
'preview_length': int(audio.info.length),
'image_url': song['attributes']['artwork']['url'].replace('{w}', '750').replace('{h}',
'750'),
'source': 'itunes',
Expand Down
2 changes: 1 addition & 1 deletion backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ spotipy==2.9.0
sanic==19.12.0
google-cloud-tasks==1.5.0
googleapis-common-protos==1.6.0
mutagen
mutagen==1.45.1
phonenumbers==8.12.1
aiohttp[speedups]

0 comments on commit 1207891

Please sign in to comment.