morphbr@718: #!/usr/bin/env python morphbr@718: morphbr@718: __author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza" morphbr@718: __author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br" morphbr@718: __license__ = "GPL" morphbr@718: __version__ = "0.4" morphbr@718: morphbr@718: import os morphbr@718: import threading morphbr@718: import SocketServer morphbr@718: import BaseHTTPServer morphbr@718: import socket morphbr@718: import urlparse morphbr@718: import cgi morphbr@718: import lib.utils as utils morphbr@718: import logging morphbr@718: morphbr@718: from log import Log morphbr@718: import lib.transcoder as transcoder morphbr@718: morphbr@718: __all__ = ("RequestHandler") morphbr@718: morphbr@718: class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): morphbr@718: """Class that implements an HTTP request handler for our server.""" morphbr@718: log = logging.getLogger("gms.request") morphbr@718: def_transcoder = None morphbr@718: transcoders = utils.PluginSet(transcoder.Transcoder) morphbr@718: transcoders_log = Log() morphbr@718: tid_queue = [] morphbr@718: morphbr@718: menu = { morphbr@718: "Log": "/get_log.do", morphbr@718: "Stop": "/stop-transcoder.do", morphbr@718: "Status": "/status.do", morphbr@718: "All Log": "/get_all_log.do", morphbr@718: "Version": "/version.do", morphbr@718: "Shutdown": "/shutdown.do" morphbr@718: } morphbr@718: morphbr@718: @classmethod morphbr@718: def load_plugins_transcoders(cls, directory): morphbr@718: cls.transcoders.load_from_directory(directory) morphbr@718: morphbr@718: if cls.def_transcoder is None and cls.transcoders: morphbr@718: cls.def_transcoder = cls.transcoders[0].name morphbr@718: # load_plugins_transcoders() morphbr@718: morphbr@718: morphbr@718: def do_dispatch(self, body): morphbr@718: self.url = self.path morphbr@718: morphbr@718: pieces = urlparse.urlparse(self.path) morphbr@718: self.path = pieces[2] morphbr@718: self.query = cgi.parse_qs(pieces[4]) morphbr@718: morphbr@718: if self.path == "/": morphbr@718: self.serve_main(body) morphbr@718: elif self.path == "/shutdown.do": morphbr@718: self.serve_shutdown(body) morphbr@718: elif self.path == "/stop-transcoder.do": morphbr@718: self.serve_stop_transcoder(body) morphbr@718: elif self.path == "/status.do": morphbr@718: self.serve_status(body) morphbr@718: elif self.path == "/version.do": morphbr@718: self.serve_version(body) morphbr@718: elif self.path == "/new_id.do": morphbr@718: self.serve_new_id(body) morphbr@718: elif self.path == "/get_log.do": morphbr@718: self.serve_get_log(body) morphbr@718: elif self.path == "/get_all_log.do": morphbr@718: self.serve_get_all_log(body) morphbr@718: elif self.path == "/stream.do": morphbr@718: self.serve_stream(body) morphbr@718: else: morphbr@718: action = self.query.get("action", None) morphbr@718: if action and "stream.do" in action: morphbr@718: self.serve_stream(body) morphbr@718: else: morphbr@718: self.send_error(404, "File not found") morphbr@718: # do_dispatch() morphbr@718: morphbr@718: morphbr@718: def do_GET(self): morphbr@718: self.do_dispatch(True) morphbr@718: # do_GET() morphbr@718: morphbr@718: morphbr@718: def do_HEAD(self): morphbr@718: self.do_dispatch(False) morphbr@718: # do_HEAD() morphbr@718: morphbr@718: morphbr@718: def _nav_items(self): morphbr@718: ret = "" morphbr@718: for name, url in self.menu.items(): morphbr@718: ret += utils.getHTML("menu", {"name": name, "url": url}) morphbr@718: morphbr@718: return ret morphbr@718: # _nav_items() morphbr@718: morphbr@718: def serve_main(self, body): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: if body: morphbr@718: self.wfile.write(utils.getHTML("index", {"menu": self._nav_items()})) morphbr@718: # serve_main() morphbr@718: morphbr@718: def serve_version(self, body): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: if body: morphbr@718: self.wfile.write("Version: %s" % __version__) morphbr@718: morphbr@718: morphbr@718: def serve_shutdown(self, body): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: if body: morphbr@718: self.wfile.write(utils.getHTML("shutdown")) morphbr@718: self.server.server_close() morphbr@718: # serve_shutdown() morphbr@718: morphbr@718: morphbr@718: def serve_stop_all_transcoders(self, body): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: if body: morphbr@718: self.server.stop_transcoders() morphbr@718: self.wfile.write(utils.getHTML("stop_all", {"menu": self._nav_items()})) morphbr@718: # serve_stop_all_transcoders() morphbr@718: morphbr@718: morphbr@718: def serve_stop_selected_transcoders(self, body, tids=[]): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: opts = "" morphbr@718: if body: morphbr@718: transcoders = self.server.get_transcoders() morphbr@718: morphbr@718: for tid in tids: morphbr@718: for t, r in transcoders: morphbr@718: if t.tid == int(tid): morphbr@718: try: morphbr@718: t.stop() morphbr@718: except Exception, e: morphbr@718: self.log.info("Plugin already stopped") morphbr@718: morphbr@718: opts += utils._create_html_item("%s" % t) morphbr@718: morphbr@718: break morphbr@718: morphbr@718: self.wfile.write(utils.getHTML("stop_selected", morphbr@718: {"menu": self._nav_items(), morphbr@718: "opts": opts})) morphbr@718: # serve_stop_selected_transcoders() morphbr@718: morphbr@718: morphbr@718: def serve_stop_transcoder(self, body): morphbr@718: req = self.query.get("request", None) morphbr@718: tid = self.query.get("tid", None) morphbr@718: if req and "all" in req: morphbr@718: self.serve_stop_all_transcoders(body) morphbr@718: elif tid: morphbr@718: self.serve_stop_selected_transcoders(body, tid[0].split(";")) morphbr@718: else: morphbr@718: self.serve_status(body) morphbr@718: # serve_stop_transcoder() morphbr@718: morphbr@718: morphbr@718: def serve_status(self, body): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: stopone = "" morphbr@718: morphbr@718: if body: morphbr@718: tl = self.server.get_transcoders() morphbr@718: if not tl: morphbr@718: running = "
No running transcoder.
\n" morphbr@718: stopall = "" morphbr@718: stopone = "" morphbr@718: morphbr@718: elif self.query.get("tid", None): morphbr@718: req_tid = int(self.query.get("tid")[0]) morphbr@718: for transcoder, request in tl: morphbr@718: if transcoder.tid == req_tid: morphbr@718: self.wfile.write("Status: %s %%" % transcoder.status) morphbr@718: return True morphbr@718: morphbr@718: return False morphbr@718: morphbr@718: else: morphbr@718: running = "Running transcoders:
\n" morphbr@718: stopall = utils._create_html_item("" morphbr@718: "[STOP ALL]" % morphbr@718: self.menu["Stop"]) morphbr@718: morphbr@718: for transcoder, request in tl: morphbr@718: stopone += utils._create_html_item("%s;" morphbr@718: "" morphbr@718: " [STOP] ") % ( morphbr@718: transcoder, self.menu["Stop"], transcoder.tid) morphbr@718: morphbr@718: self.wfile.write(utils.getHTML("status", morphbr@718: {"menu": self._nav_items(), morphbr@718: "running": running, morphbr@718: "stopall": stopall, morphbr@718: "stopone": stopone})) morphbr@718: # serve_status() morphbr@718: morphbr@718: morphbr@718: def _get_transcoder(self): morphbr@718: # get transcoder option: mencoder is the default morphbr@718: request_transcoders = self.query.get("transcoder", ["mencoder"]) morphbr@718: morphbr@718: for t in request_transcoders: morphbr@718: transcoder = self.transcoders.get(t) morphbr@718: if transcoder: morphbr@718: return transcoder morphbr@718: morphbr@718: if not transcoder: morphbr@718: return self.transcoders[self.def_transcoder] morphbr@718: # _get_transcoder() morphbr@718: morphbr@718: morphbr@718: def _get_new_id(self, tid): morphbr@718: self.server.last_tid = utils.create_tid(tid) morphbr@718: self.tid_queue.append(self.server.last_tid) morphbr@718: return self.server.last_tid morphbr@718: # _get_new_id() morphbr@718: morphbr@718: morphbr@718: def serve_new_id(self, body): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: morphbr@718: if body: morphbr@718: self.wfile.write("%s" % self._get_new_id(self.server.last_tid)) morphbr@718: # serve_new_id() morphbr@718: morphbr@718: def serve_get_log(self, body): morphbr@718: self.send_response(200) morphbr@718: self.send_header("Content-Type", "text/html") morphbr@718: self.send_header('Connection', 'close') morphbr@718: self.end_headers() morphbr@718: morphbr@718: if body: morphbr@718: if self.query.get("tid", None): morphbr@718: tid = int(self.query.get("tid")[0]) morphbr@718: stat = self.transcoders_log.get_status(tid) morphbr@718: self.wfile.write("%s" % stat) morphbr@718: else: morphbr@718: stat = self.transcoders_log.get_status() morphbr@718: for rtid, status in stat.iteritems(): morphbr@718: self.wfile.write("%s: %s