changed error page, MASSIVE new sound extension added with working YouTube duration, preparation and streaming API steps, wsgi random comment removal

This commit is contained in:
Xevion
2019-12-21 14:12:17 -06:00
parent 8cb5e077a4
commit 7f1a6a6e25
7 changed files with 110 additions and 21 deletions

1
.gitignore vendored
View File

@@ -16,3 +16,4 @@ app/static/token.dat
keys.json
.cache-xevioni
auth.json
app/sounds/*

View File

@@ -17,6 +17,6 @@ migrate = Migrate(app, db)
from app import models
from app import routes, simple_routes, hidden, dashboard
from app import ftbhot, custom, spotify, panzer
from app import ftbhot, custom, spotify, panzer, sound
app.jinja_env.globals.update(get_hidden=routes.get_hidden)

View File

@@ -24,4 +24,4 @@ def unauthorized(e):
@app.errorhandler(404)
def page_not_found(e):
# note that we set the 404 status explicitly
return render_template('404.html'), 404
return render_template('error.html', code=404, message='Content not found...'), 404

90
app/sound.py Normal file
View File

@@ -0,0 +1,90 @@
from app import app
from flask import send_file, redirect, url_for, render_template
from mutagen.mp3 import MP3
import os
import re
import json
import subprocess
# Services => Expected Data
# YouTube => Video ID
# Soundcloud =>
# Filenaming/API Convention Examples
# Original URL/URI => API Path => Connected File
# https://www.youtube.com/watch?v=awtYiVGXiaY => /stream/youtube/awtYiVGXiaY => youtube/awtYiVGXiaY.mp3
# https://soundcloud.com/yungraredeath/fall-in-line-w-kxng-prod-mars-mission => /stream/soundcloud/fall-in-line-w-kxng-prod-mars-mission---yungraredeath => soundcloud/fall-in-line-w-kxng-prod-mars-mission---yungraredeath.mp3
# spotify:track:16PmczUxlX7dpr6ror6pXd => /duration/spotify/16PmczUxlX7dpr6ror6pXd => spotify/16PmczUxlX7dpr6ror6pXd.mp3
class YouTubeHandler:
@staticmethod
def url(videoid):
return f'https://www.youtube.com/watch?v={videoid}'
@staticmethod
def getConfig(videoid):
with open(os.path.join('app', 'sounds', 'filenames.json'), 'r') as file:
return json.load(file)['youtube'][videoid]
@staticmethod
def filename(videoid):
try:
config = YouTubeHandler.getConfig(videoid)
return config['filename']
except KeyError:
filename = subprocess.run(
['youtube-dl', '-x', '--audio-format', 'mp3', '--restrict-filenames', '--get-filename',
YouTubeHandler.url(videoid)], encoding='utf-8', capture_output=True).stdout
filename = filename.split('.')
filename[-1] = 'mp3'
return '.'.join(filename)
@staticmethod
def path(videoid):
try:
config = YouTubeHandler.getConfig(videoid)
return config['path']
except KeyError:
filename = YouTubeHandler.filename(videoid)
path = os.path.join('app', 'sounds', 'youtube', filename)
with open(os.path.join('app', 'sounds', 'filenames.json'), 'r+') as file:
config = json.load(file)
config['youtube'][videoid] = {
"filename" : filename,
"path" : path
}
file.seek(0)
file.write(json.dumps(config))
file.truncate()
return path
@staticmethod
def download(videoid):
config = YouTubeHandler.getConfig(videoid)
if not os.path.exists(config['path']):
subprocess.run(['youtube-dl', '-x', '--restrict-filenames', '--audio-format', 'mp3', YouTubeHandler.url(videoid)])
print(os.listdir('.'))
os.rename(config['filename'], config['path'])
service_functions = {
'youtube' : YouTubeHandler,
'spotify' : {'url' : None, 'path' : None},
'soundcloud' : {'url' : None, 'path' : None}
}
# Streams a prepared MP3 back to the client
@app.route('/stream/<service>/<mediaid>')
def stream(service, mediaid):
prepare(service, mediaid)
if service == 'youtube':
config = YouTubeHandler.getConfig(mediaid)
return send_file(os.path.join(os.path.dirname(__file__), '..', config['path']), attachment_filename=config['filename'])
return '???'
# Prepares a URL for download, returning the duration it should play for if streamed
@app.route('/prepare/<service>/<mediaid>')
def prepare(service, mediaid):
filepath = service_functions[service].path(mediaid)
service_functions[service].download(mediaid)
print(filepath)
return str(MP3(filepath).info.length)

View File

@@ -5,10 +5,10 @@
<div class="hero-body">
<div class="container has-text-centered">
<p class="title">
{{ code }}
{{ code if code is not none else 'Error' }}
</p>
<p class="subtitle">
{{ message }} <em href="{{ url_for('index') }}">Go home?</em>
{{ message if message is not none else 'Error encountered' }} <em href="{{ url if url is not none else url_for('index') }}">{{ url_message if url_message is not none else 'Go home?' }}</em>
</p>
</div>
</div>

View File

@@ -1,21 +1,21 @@
Flask_Migrate==2.5.2
pyperclip==1.7.0
spotipy==2.4.4
alembic==1.2.1
matplotlib==3.1.1
SQLAlchemy==1.3.10
hurry.filesize==0.9
Faker==2.0.3
xmltodict==0.12.0
numpy==1.17.3
Flask_SQLAlchemy==2.4.1
Flask_Migrate==2.5.2
Flask==1.1.1
alembic==1.2.1
SQLAlchemy==1.3.10
pyperclip==1.7.0
Werkzeug==0.16.0
requests==2.20.0
WTForms==2.2.1
Flask_WTF==0.14.2
Werkzeug==0.16.0
Flask==1.1.1
Flask_Login==0.4.1
xmltodict==0.12.0
spotipy==2.4.4
mistune==0.8.4
Flask_Login==0.4.1
Flask_WTF==0.14.2
matplotlib==3.1.1
Faker==2.0.3
numpy==1.17.3
Flask_SQLAlchemy==2.4.1
Pillow==6.2.1
python_dateutil==2.8.1
hurry==1.1

View File

@@ -1,8 +1,6 @@
from app import app, db
from app.models import User, Post, Search
# test message
@app.shell_context_processor
def make_shell_context():
return {'db' : db, 'User' : User, 'Post' : Post, 'Search' : Search}