finish up download error checking and returns, nearly finished with exception handling

nearly ready to deploy! at 4AM! end my life!
This commit is contained in:
Xevion
2020-01-05 04:42:30 -06:00
parent 5076b782ee
commit 69c76599ad
2 changed files with 21 additions and 16 deletions

View File

@@ -1,6 +1,7 @@
from app import app, db, limiter from app import app, db, limiter
from app.sound_models import YouTubeAudio, SoundcloudAudio, CouldNotDecode, CouldNotDownload, CouldNotProcess from app.sound_models import YouTubeAudio, SoundcloudAudio, CouldNotDecode, CouldNotDownload, CouldNotProcess
from flask import Response, send_file, redirect, url_for, render_template, request, jsonify from flask import Response, send_file, redirect, url_for, render_template, request, jsonify
from flask_login import current_user
from multiprocessing import Value from multiprocessing import Value
from mutagen.mp3 import MP3 from mutagen.mp3 import MP3
import os import os
@@ -38,14 +39,14 @@ basic_responses = {
} }
# A simple function among the routes to determine what should be returned. # A simple function among the routes to determine what should be returned.
def errorCheck(e, auth=False): # Not particularly sure how request context is passed, but it seems that either it passed or can access current_user's authenitcation/role's properly, so no problem.
response = str(e) # Shows error in full context IF authenticated + admin, otherwise basic error description, OTHERWISE a basic error message.
print(response) def errorCheck(e):
if auth:
if type(e) in basic_responses.keys(): if type(e) in basic_responses.keys():
response += f'\n{basic_responses[type(e)]}' response = f'{basic_responses[type(e)]}'
else: else:
raise e raise e
if current_user.is_authenticated and current_user.has_role('Admin'): response = str(e) + '\n' + response
return Response(response, status=200, mimetype='text/plain') return Response(response, status=200, mimetype='text/plain')
# Under the request context, it grabs the same args needed to decide whether the stream has been downloaded previously # Under the request context, it grabs the same args needed to decide whether the stream has been downloaded previously

View File

@@ -60,11 +60,11 @@ class YouTubeAudio(db.Model):
# Use stdout=PIPE, [Python 3.6] production server support instead of 'capture_output=True' => 'process.stdout' # Use stdout=PIPE, [Python 3.6] production server support instead of 'capture_output=True' => 'process.stdout'
self.filename = self.id + '.mp3' self.filename = self.id + '.mp3'
command = f'youtube-dl -4 -x --audio-format mp3 --restrict-filenames --dump-json {self.id}' command = f'youtube-dl -4 -x --audio-format mp3 --restrict-filenames --dump-json {self.id}'
processJSON = subprocess.Popen(command.split(' '), process = subprocess.Popen(command.split(' '),
encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE) encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
data = processJSON.communicate() data = process.communicate()
if processJSON.returncode != 0: if process.returncode != 0:
raise CouldNotProcess(f'> {command}\n{data[1]}Exit Code: {processJSON.returncode}') raise CouldNotProcess(f'Command: {command}\n{data[1]}Exit Code: {process.returncode}') # process ends with a newline, not needed between
try: try:
data = json.loads(data[0]) data = json.loads(data[0])
except json.JSONDecodeError: except json.JSONDecodeError:
@@ -81,12 +81,16 @@ class YouTubeAudio(db.Model):
# Begins the download process for a video # Begins the download process for a video
def download(self): def download(self):
print(f'Attempting download of {self.id}') print(f'Attempting download of {self.id}')
process = subprocess.Popen(f'youtube-dl -x -4 --restrict-filenames --audio-quality 64K --audio-format mp3 -o ./app/sounds/youtube/%(id)s.%(ext)s {self.id}'.split(' ')) command = f'youtube-dl -x -4 --restrict-filenames --audio-quality 64K --audio-format mp3 -o ./app/sounds/youtube/%(id)s.%(ext)s {self.id}'
process = subprocess.Popen(command.split(' '), encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
data = process.communicate() # Not the data for the mp3, just the output. We have to separate this in order to 'wait' for the process to complete fully.
print('Checking process return code...')
if process.returncode != 0: if process.returncode != 0:
raise CouldNotProcess(data + f'\Exit Code: {processJSON.returncode}') raise CouldNotProcess(f'Command: {command}\n{data[1]}Exit Code: {process.returncode}')
print('Checking for expected file...')
if not os.path.exists(self.getPath()): if not os.path.exists(self.getPath()):
raise CouldNotDownload(process.communicate()[0]) raise CouldNotDownload(data[1])
print(f'Download attempt for {self.id} finished.') print(f'Download attempt for {self.id} finished successfully.')
# Validates whether the specified ID could be a valid YouTube video ID # Validates whether the specified ID could be a valid YouTube video ID
@staticmethod @staticmethod