From 88b7884e55093e8dbe20cdd4b12b45885cc0e458 Mon Sep 17 00:00:00 2001 From: Xevion Date: Tue, 24 Dec 2019 22:10:57 -0600 Subject: [PATCH] status modifications with new validation and JSONifiation methods --- app/sound.py | 15 +++++++++++---- app/sound_models.py | 14 +++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/sound.py b/app/sound.py index 8e11bec..0af5906 100644 --- a/app/sound.py +++ b/app/sound.py @@ -11,7 +11,7 @@ import subprocess # Retrieves the YouTubeAudio object relevant to the mediaid if available. If not, it facilitiates the creation and writing of one. # Also helps with access times. def get_youtube(mediaid): - audio = YouTubeAudio.query.filter_by(id=mediaid).first() + audio = YouTubeAudio.query.get(mediaid) if audio is not None: return audio # sets the access time to now audio = YouTubeAudio(id=mediaid) @@ -48,12 +48,19 @@ def duration(service, mediaid): else: return Response('Bad request', status=400, mimetype='text/plain') -# Returns the duration of a specific media +# Returns a detailed JSON export of a specific database entry. +# Will not create a new database entry where one didn't exist before. @app.route('/status//') def status(service, mediaid): if service == 'youtube': - audio = get_youtube(mediaid).duration - return Response(str(duration), status=200, mimetype='text/plain') + audio = YouTubeAudio.query.get(mediaid) + if audio is None: + if YouTubeAudio.isValid(mediaid): + return Response('Media not yet downloaded', status=400, mimetype='text/plain') + else: + return Response('Invalid ID', status=400, mimetype='text/plain') + else: + return Response(audio.toJSON(), status=200, mimetype='text/plain') elif service == 'soundcloud': return Response('Not implemented', status=501, mimetype='text/plain') elif service == 'spotify': diff --git a/app/sound_models.py b/app/sound_models.py index ad726d8..5e86475 100644 --- a/app/sound_models.py +++ b/app/sound_models.py @@ -3,6 +3,7 @@ from app import db import subprocess import json import os +import re class YouTubeAudio(db.Model): id = db.Column(db.String(11), primary_key=True) # 11 char id, presumed to stay the same for the long haul. Should be able to change to 12 chars. @@ -38,7 +39,7 @@ class YouTubeAudio(db.Model): print(f'Filename acquired for {self.id}') processJSON = subprocess.Popen(f'youtube-dl -4 -x --audio-format mp3 --restrict-filenames --dump-json {self.id}'.split(' '), encoding='utf-8', stdout=subprocess.PIPE) - data = json.loads(processJSON.communicate()[0]) + data = json.loads(processJSON.communicate()[0].decode()) print(f'JSON acquired for {self.id}, beginning to fill.') self.duration = data['duration'] self.creator = data['creator'] or data['uploader'] @@ -52,6 +53,17 @@ class YouTubeAudio(db.Model): subprocess.run(f'youtube-dl -x -4 --restrict-filenames --embed-thumbnail --audio-format mp3 -o ./app/sounds/youtube/%(id)s.%(ext)s {self.id}'.split(' ')) print(f'Download attempt for {self.id} finished.') + @staticmethod + def isValid(id): + return re.match(r'^[A-Za-z0-9_-]{11}$', id) is not None + + def toJSON(self, noConvert=False): + data = {'id' : self.id, 'url' : self.url, 'title' : self.title, 'creator' : self.creator, + 'uploader' : self.uploader, 'filename' : self.filename, 'duration' : self.duration, + 'access_count' : self.access_count, 'download_timestamp' : self.download_timestamp.isoformat(), + 'last_access_timestamp' : self.last_access_timestamp.isoformat()} + return data if noConvert else json.dumps(data) + def delete(self): os.remove(os.path.join('app', 'sounds', 'youtube', self.filename)) db.session.delete(self)