mirror of
https://github.com/Xevion/v1.xevion.dev.git
synced 2025-12-06 13:16:55 -06:00
begin clearing out old sound functions, add downloader function
most of these are untested and definitely very buggy, just moving stuff around for now
This commit is contained in:
76
app/sound.py
76
app/sound.py
@@ -6,41 +6,6 @@ import os
|
||||
import re
|
||||
import json
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
# 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:
|
||||
# Use stdout=PIPE, [Python 3.6] production server support instead of 'capture_output=True' => 'process.stdout'
|
||||
process = subprocess.Popen(
|
||||
['youtube-dl', '-x', '--audio-format', 'mp3', '--restrict-filenames', '--get-filename', YouTubeHandler.url(videoid)],
|
||||
encoding='utf-8', stdout=subprocess.PIPE)
|
||||
filename = process.communicate()[0].split('.')
|
||||
filename[-1] = 'mp3'
|
||||
return '.'.join(filename)
|
||||
|
||||
@staticmethod
|
||||
def path(videoid):
|
||||
@@ -68,47 +33,6 @@ class YouTubeHandler:
|
||||
subprocess.run(['youtube-dl', '-x', '--restrict-filenames', '--audio-format', 'mp3', YouTubeHandler.url(videoid)])
|
||||
os.rename(config['filename'], config['path'])
|
||||
|
||||
service_functions = {
|
||||
'youtube' : YouTubeHandler,
|
||||
'spotify' : SpotifyHandler,
|
||||
'soundcloud' : SoundcloudHandler
|
||||
}
|
||||
|
||||
# Default JSON format, will be used in case of corruption
|
||||
JSONDefault = {'youtube' : {}, 'soundcloud' : {}, 'spotify' : {}}
|
||||
|
||||
if not os.path.exists(os.path.join('app', 'sounds')):
|
||||
print('Sounds folder not found. Creating.')
|
||||
os.mkdir(os.path.join('app', 'sounds'))
|
||||
|
||||
# Test JSON file existence
|
||||
if not os.path.exists(os.path.join('app', 'sounds', 'filenames.json')):
|
||||
print('JSON database file not found. Creating with default data structure.')
|
||||
with open(os.path.join('app', 'sounds', 'filenames.json'), 'w+') as file:
|
||||
json.dump({'youtube' : {} }, file)
|
||||
else:
|
||||
# File exists, but is it valid JSON?
|
||||
try:
|
||||
print('Testing JSON database file.')
|
||||
with open(os.path.join('app', 'sounds', 'filenames.json'), 'r') as file:
|
||||
json.load(file)
|
||||
except json.JSONDecodeError:
|
||||
# Corruption or other has occurred. Clearing all service folders. Resetting and clearing all services
|
||||
print('Corruption/Invalid formatting in JSON file detected, clearing all config/media.')
|
||||
print('Clearing JSON database file.')
|
||||
with open(os.path.join('app', 'sounds', 'filenames.json'), 'w+') as file:
|
||||
json.dump(JSONDefault, file)
|
||||
|
||||
for service in service_functions.keys():
|
||||
print(f"Clearing '{service}' folder.")
|
||||
servicePath = os.path.join('app', 'sounds', service)
|
||||
if os.path.exists(servicePath):
|
||||
shutil.rmtree(servicePath)
|
||||
os.mkdir(servicePath)
|
||||
else:
|
||||
os.mkdir(servicePath)
|
||||
|
||||
# Streams a prepared MP3 back to the client
|
||||
@app.route('/stream/<service>/<mediaid>')
|
||||
def stream(service, mediaid):
|
||||
prepare(service, mediaid)
|
||||
|
||||
@@ -15,10 +15,14 @@ class YouTubeAudio(db.Model):
|
||||
download_timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
||||
last_access_timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
|
||||
|
||||
def getPath(self):
|
||||
return os.path.join('app', 'sounds', 'youtube', self.filename)
|
||||
|
||||
def file_exists(self):
|
||||
return os.path.exists(os.path.join('app', 'sounds', 'youtube', self.filename))
|
||||
return os.path.exists(self.getPath())
|
||||
|
||||
def fill_metadata(self):
|
||||
# Use stdout=PIPE, [Python 3.6] production server support instead of 'capture_output=True' => 'process.stdout'
|
||||
self.url = f'https://www.youtube.com/watch?v={self.id}'
|
||||
processFilename = subprocess.Popen(['youtube-dl', '-x', '--audio-format', 'mp3', '--restrict-filenames', '--get-filename', self.url],
|
||||
encoding='utf-8', stdout=subprocess.PIPE)
|
||||
@@ -31,6 +35,10 @@ class YouTubeAudio(db.Model):
|
||||
self.uploader = data['uploader'] or data['creator']
|
||||
self.title = data['title'] or data['alt_title'] # Do not trust alt-title ; it is volatile and uploader set, e.x. https://i.imgur.com/Tgff4rI.png
|
||||
|
||||
def download(self):
|
||||
subprocess.run(['youtube-dl', '-x', '--restrict-filenames', '--audio-format', 'mp3', self.id])
|
||||
os.rename(self.filename, self.getPath())
|
||||
|
||||
class SoundcloudAudio(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True) # hidden API-accessible only ID
|
||||
url = db.Column(db.String(256))
|
||||
|
||||
Reference in New Issue
Block a user