Skip to content

Instantly share code, notes, and snippets.

@KatieFrogs
Last active October 18, 2021 11:21
Show Gist options
  • Save KatieFrogs/4082c4df71e364419d14947c6006519b to your computer and use it in GitHub Desktop.
Save KatieFrogs/4082c4df71e364419d14947c6006519b to your computer and use it in GitHub Desktop.
Python script that opens files in vgmstream-web
#!/usr/bin/env python3
import os
import sys
import http.server
import urllib
import shutil
import posixpath
from functools import partial
from http import HTTPStatus
import webbrowser
vgmWeb = "https://katiefrogs.github.io/vgmstream-web/"
class HttpHandler(http.server.BaseHTTPRequestHandler):
def __init__(self, *args, directory=None, **kwargs):
if directory is None:
raise ValueError
self.directory = directory
super().__init__(*args, **kwargs)
def do_GET(self):
f = self.send_head()
if f:
try:
self.copyfile(f, self.wfile)
finally:
f.close()
if not self.directory:
httpd.shutdown()
def do_HEAD(self):
f = self.send_head()
if f:
f.close()
def send_head(self):
path = self.translate_path(self.path)
f = None
if path.endswith("/") or path not in self.directory:
self.send_error(HTTPStatus.NOT_FOUND, "File not found")
return None
try:
f = open(self.directory[path], "rb")
except OSError:
self.send_error(HTTPStatus.NOT_FOUND, "File not found")
return None
finally:
del self.directory[path]
try:
fs = os.fstat(f.fileno())
self.send_response(HTTPStatus.OK)
self.send_header("Content-type", "application/octet-stream")
self.send_header("Content-Length", str(fs[6]))
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.send_header("Access-Control-Allow-Origin", "*")
self.end_headers()
return f
except:
f.close()
raise
def translate_path(self, path):
path = path.split("?", 1)[0]
path = path.split("#", 1)[0]
trailing_slash = path.rstrip().endswith("/")
try:
path = urllib.parse.unquote(path, errors="surrogatepass")
except UnicodeDecodeError:
path = urllib.parse.unquote(path)
path = posixpath.normpath(path)
words = path.split("/")
words = filter(None, words)
path = ""
for word in words:
if os.path.dirname(word) or word in (os.curdir, os.pardir):
continue
path = os.path.join(path, word)
if trailing_slash:
path += "/"
return path
def copyfile(self, source, outputfile):
shutil.copyfileobj(source, outputfile)
def existingFile(arg):
if os.path.isfile(arg):
return arg
else:
print("File not found: '{}'".format(arg), file=sys.stderr)
sys.exit(1)
def existingDir(arg):
if os.path.isdir(arg):
return arg
else:
raise argparse.ArgumentTypeError("Directory not found: '{}'".format(arg))
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"file",
help="Path to a streamed audio file."
)
parser.add_argument(
"sub",
nargs="*",
help="Additional file or files that are required for the playback."
)
parser.add_argument(
"--base",
type=existingDir,
help="Base directory."
)
if len(sys.argv) == 1:
parser.print_help()
else:
args = parser.parse_args()
file = existingFile(os.path.join(args.base, args.file) if args.base else args.file)
sub = [existingFile(os.path.join(args.base, name) if args.base else name) for name in args.sub]
directory = {}
subname = []
filename = args.file if args.base else os.path.split(args.file)[1]
directory[filename] = file
for i in range(len(args.sub)):
subname.append(args.sub[i] if args.base else os.path.split(args.sub[i])[1])
directory[subname[-1]] = sub[i]
handler_class = partial(HttpHandler, directory=directory)
httpd = http.server.ThreadingHTTPServer(("", 0), handler_class)
prefix = "http://localhost:{}/".format(httpd.server_port)
url = vgmWeb
if len(sub):
url = "{}#base={}&play={}".format(url, prefix, filename)
else:
url = "{}#play={}{}".format(url, prefix, filename)
for i in range(len(subname)):
url = "{}&sub={}".format(url, subname[i])
webbrowser.open(url)
httpd.serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment