#!/usr/bin/env python2 import os, mimetypes, json, cgi, recode, time, urllib, events, threading from config import config from directory import Directory, File from session import Session class Application(object): # Application handlers def files(self, environ, start_response, path): full_path = os.path.join(config.get('music_root'), *path[1:]) rel_path = os.path.join(*path[1:] or '.') if os.path.isdir(full_path): start_response('200 OK', [('Content-Type', 'text/html; charset=UTF-8')]) return (str(x) for x in Directory(rel_path).listdir()) else: args = cgi.FieldStorage(environ = environ) decoder = args.getvalue('decoder') if 'decoder' in args else None encoder = args.getvalue('encoder') if 'encoder' in args else None if decoder and encoder: cache_file = File(rel_path).get_cache_file() return File(cache_file, True).send(environ, start_response) else: return File(rel_path).send(environ, start_response) def static(self, environ, start_response, path): filename = os.path.join('static', *path[1:]) if not os.access(filename, os.F_OK) or '..' in path: start_response('404 Not Found', []) return [] mime = mimetypes.guess_type(filename, strict = False)[0] or 'application/octet-stream' start_response('200 OK', [('Content-Type', mime)]) return open(filename, 'rb') # JSON handlers def json_list(self, environ, start_response, path): args = cgi.FieldStorage(environ = environ) directory = args.getvalue('directory') if 'directory' in args else '/' d = Directory(directory) contents = d.listdir() start_response('200 OK', [('Content-Type', 'text/plain')]) s = json.dumps([x.json() for x in contents]) return s def json_cache(self, environ, start_response, path): args = cgi.FieldStorage(environ = environ) path = args.getvalue('path') if 'path' in args else None decoder = args.getvalue('decoder') if 'decoder' in args else None encoder = args.getvalue('encoder') if 'encoder' in args else None f = File(path) t = threading.Thread(target = f.recode, args = (decoder, encoder, environ['sessionid'])) t.start() start_response('200 OK', [('Content-Type', 'text/plain')]) return [] handlers = { 'files': files, 'static': static, 'list': json_list, 'cache': json_cache, 'events': events.EventSubscriber, } # WSGI handler def __call__(self, environ, start_response): path = urllib.unquote(environ['PATH_INFO']) path = path.split('/')[1:] module = path[0] or None if not module: module = 'static' path = ['static', 'index.html'] if module in self.handlers: return Session(self.handlers[module])(self, environ, start_response, path) start_response('404 Not Found', [('Content-Type', 'text/plain')]) return [str(path)] if __name__ == '__main__': import sys if len(sys.argv) == 3: from flup.server.fcgi import WSGIServer WSGIServer(Application(), bindAddress = (sys.argv[1], int(sys.argv[2]))).run() else: from wsgiref.simple_server import make_server, WSGIServer # enable IPv6 WSGIServer.address_family |= 10 httpd = make_server('', 8000, Application()) httpd.serve_forever()