1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gmyth-stream/server/0.3/lib/request_handler.py Wed May 30 19:53:13 2007 +0100
1.3 @@ -0,0 +1,332 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
1.7 +__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
1.8 +__license__ = "GPL"
1.9 +__version__ = "0.4"
1.10 +
1.11 +import os
1.12 +import threading
1.13 +import SocketServer
1.14 +import BaseHTTPServer
1.15 +import socket
1.16 +import urlparse
1.17 +import cgi
1.18 +import lib.utils as utils
1.19 +import logging
1.20 +
1.21 +from log import Log
1.22 +import lib.transcoder as transcoder
1.23 +
1.24 +__all__ = ("RequestHandler")
1.25 +
1.26 +class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
1.27 + """Class that implements an HTTP request handler for our server."""
1.28 + log = logging.getLogger("gms.request")
1.29 + def_transcoder = None
1.30 + transcoders = utils.PluginSet(transcoder.Transcoder)
1.31 + transcoders_log = Log()
1.32 + tid_queue = []
1.33 +
1.34 + menu = {
1.35 + "Log": "/get_log.do",
1.36 + "Stop": "/stop-transcoder.do",
1.37 + "Status": "/status.do",
1.38 + "All Log": "/get_all_log.do",
1.39 + "Version": "/version.do",
1.40 + "Shutdown": "/shutdown.do"
1.41 + }
1.42 +
1.43 + @classmethod
1.44 + def load_plugins_transcoders(cls, directory):
1.45 + cls.transcoders.load_from_directory(directory)
1.46 +
1.47 + if cls.def_transcoder is None and cls.transcoders:
1.48 + cls.def_transcoder = cls.transcoders[0].name
1.49 + # load_plugins_transcoders()
1.50 +
1.51 +
1.52 + def do_dispatch(self, body):
1.53 + self.url = self.path
1.54 +
1.55 + pieces = urlparse.urlparse(self.path)
1.56 + self.path = pieces[2]
1.57 + self.query = cgi.parse_qs(pieces[4])
1.58 +
1.59 + if self.path == "/":
1.60 + self.serve_main(body)
1.61 + elif self.path == "/shutdown.do":
1.62 + self.serve_shutdown(body)
1.63 + elif self.path == "/stop-transcoder.do":
1.64 + self.serve_stop_transcoder(body)
1.65 + elif self.path == "/status.do":
1.66 + self.serve_status(body)
1.67 + elif self.path == "/version.do":
1.68 + self.serve_version(body)
1.69 + elif self.path == "/new_id.do":
1.70 + self.serve_new_id(body)
1.71 + elif self.path == "/get_log.do":
1.72 + self.serve_get_log(body)
1.73 + elif self.path == "/get_all_log.do":
1.74 + self.serve_get_all_log(body)
1.75 + elif self.path == "/stream.do":
1.76 + self.serve_stream(body)
1.77 + else:
1.78 + action = self.query.get("action", None)
1.79 + if action and "stream.do" in action:
1.80 + self.serve_stream(body)
1.81 + else:
1.82 + self.send_error(404, "File not found")
1.83 + # do_dispatch()
1.84 +
1.85 +
1.86 + def do_GET(self):
1.87 + self.do_dispatch(True)
1.88 + # do_GET()
1.89 +
1.90 +
1.91 + def do_HEAD(self):
1.92 + self.do_dispatch(False)
1.93 + # do_HEAD()
1.94 +
1.95 +
1.96 + def _nav_items(self):
1.97 + ret = ""
1.98 + for name, url in self.menu.items():
1.99 + ret += utils.getHTML("menu", {"name": name, "url": url})
1.100 +
1.101 + return ret
1.102 + # _nav_items()
1.103 +
1.104 + def serve_main(self, body):
1.105 + self.send_response(200)
1.106 + self.send_header("Content-Type", "text/html")
1.107 + self.send_header('Connection', 'close')
1.108 + self.end_headers()
1.109 + if body:
1.110 + self.wfile.write(utils.getHTML("index", {"menu": self._nav_items()}))
1.111 + # serve_main()
1.112 +
1.113 + def serve_version(self, body):
1.114 + self.send_response(200)
1.115 + self.send_header("Content-Type", "text/html")
1.116 + self.send_header('Connection', 'close')
1.117 + self.end_headers()
1.118 + if body:
1.119 + self.wfile.write("Version: %s" % __version__)
1.120 +
1.121 +
1.122 + def serve_shutdown(self, body):
1.123 + self.send_response(200)
1.124 + self.send_header("Content-Type", "text/html")
1.125 + self.send_header('Connection', 'close')
1.126 + self.end_headers()
1.127 + if body:
1.128 + self.wfile.write(utils.getHTML("shutdown"))
1.129 + self.server.server_close()
1.130 + # serve_shutdown()
1.131 +
1.132 +
1.133 + def serve_stop_all_transcoders(self, body):
1.134 + self.send_response(200)
1.135 + self.send_header("Content-Type", "text/html")
1.136 + self.send_header('Connection', 'close')
1.137 + self.end_headers()
1.138 + if body:
1.139 + self.server.stop_transcoders()
1.140 + self.wfile.write(utils.getHTML("stop_all", {"menu": self._nav_items()}))
1.141 + # serve_stop_all_transcoders()
1.142 +
1.143 +
1.144 + def serve_stop_selected_transcoders(self, body, tids=[]):
1.145 + self.send_response(200)
1.146 + self.send_header("Content-Type", "text/html")
1.147 + self.send_header('Connection', 'close')
1.148 + self.end_headers()
1.149 + opts = ""
1.150 + if body:
1.151 + transcoders = self.server.get_transcoders()
1.152 +
1.153 + for tid in tids:
1.154 + for t, r in transcoders:
1.155 + if t.tid == int(tid):
1.156 + try:
1.157 + t.stop()
1.158 + except Exception, e:
1.159 + self.log.info("Plugin already stopped")
1.160 +
1.161 + opts += utils._create_html_item("%s" % t)
1.162 +
1.163 + break
1.164 +
1.165 + self.wfile.write(utils.getHTML("stop_selected",
1.166 + {"menu": self._nav_items(),
1.167 + "opts": opts}))
1.168 + # serve_stop_selected_transcoders()
1.169 +
1.170 +
1.171 + def serve_stop_transcoder(self, body):
1.172 + req = self.query.get("request", None)
1.173 + tid = self.query.get("tid", None)
1.174 + if req and "all" in req:
1.175 + self.serve_stop_all_transcoders(body)
1.176 + elif tid:
1.177 + self.serve_stop_selected_transcoders(body, tid[0].split(";"))
1.178 + else:
1.179 + self.serve_status(body)
1.180 + # serve_stop_transcoder()
1.181 +
1.182 +
1.183 + def serve_status(self, body):
1.184 + self.send_response(200)
1.185 + self.send_header("Content-Type", "text/html")
1.186 + self.send_header('Connection', 'close')
1.187 + self.end_headers()
1.188 + stopone = ""
1.189 +
1.190 + if body:
1.191 + tl = self.server.get_transcoders()
1.192 + if not tl:
1.193 + running = "<p>No running transcoder.</p>\n"
1.194 + stopall = ""
1.195 + stopone = ""
1.196 +
1.197 + elif self.query.get("tid", None):
1.198 + req_tid = int(self.query.get("tid")[0])
1.199 + for transcoder, request in tl:
1.200 + if transcoder.tid == req_tid:
1.201 + self.wfile.write("Status: %s %%" % transcoder.status)
1.202 + return True
1.203 +
1.204 + return False
1.205 +
1.206 + else:
1.207 + running = "<p>Running transcoders:</p>\n"
1.208 + stopall = utils._create_html_item("<a href='%s?request=all'>"
1.209 + "[STOP ALL]</a>" %
1.210 + self.menu["Stop"])
1.211 +
1.212 + for transcoder, request in tl:
1.213 + stopone += utils._create_html_item("%s;"
1.214 + "<a href='%s?tid=%s'>"
1.215 + " [STOP] </a>") % (
1.216 + transcoder, self.menu["Stop"], transcoder.tid)
1.217 +
1.218 + self.wfile.write(utils.getHTML("status",
1.219 + {"menu": self._nav_items(),
1.220 + "running": running,
1.221 + "stopall": stopall,
1.222 + "stopone": stopone}))
1.223 + # serve_status()
1.224 +
1.225 +
1.226 + def _get_transcoder(self):
1.227 + # get transcoder option: mencoder is the default
1.228 + request_transcoders = self.query.get("transcoder", ["mencoder"])
1.229 +
1.230 + for t in request_transcoders:
1.231 + transcoder = self.transcoders.get(t)
1.232 + if transcoder:
1.233 + return transcoder
1.234 +
1.235 + if not transcoder:
1.236 + return self.transcoders[self.def_transcoder]
1.237 + # _get_transcoder()
1.238 +
1.239 +
1.240 + def _get_new_id(self, tid):
1.241 + self.server.last_tid = utils.create_tid(tid)
1.242 + self.tid_queue.append(self.server.last_tid)
1.243 + return self.server.last_tid
1.244 + # _get_new_id()
1.245 +
1.246 +
1.247 + def serve_new_id(self, body):
1.248 + self.send_response(200)
1.249 + self.send_header("Content-Type", "text/html")
1.250 + self.send_header('Connection', 'close')
1.251 + self.end_headers()
1.252 +
1.253 + if body:
1.254 + self.wfile.write("%s" % self._get_new_id(self.server.last_tid))
1.255 + # serve_new_id()
1.256 +
1.257 + def serve_get_log(self, body):
1.258 + self.send_response(200)
1.259 + self.send_header("Content-Type", "text/html")
1.260 + self.send_header('Connection', 'close')
1.261 + self.end_headers()
1.262 +
1.263 + if body:
1.264 + if self.query.get("tid", None):
1.265 + tid = int(self.query.get("tid")[0])
1.266 + stat = self.transcoders_log.get_status(tid)
1.267 + self.wfile.write("%s" % stat)
1.268 + else:
1.269 + stat = self.transcoders_log.get_status()
1.270 + for rtid, status in stat.iteritems():
1.271 + self.wfile.write("<b>%s</b>: %s<br><br>" % (rtid, status))
1.272 + # serve_get_log()
1.273 +
1.274 + def serve_get_all_log(self, body):
1.275 + self.send_response(200)
1.276 + self.send_header("Content-Type", "text/html")
1.277 + self.send_header('Connection', 'close')
1.278 + self.end_headers()
1.279 +
1.280 + if body:
1.281 + if self.query.get("tid", None):
1.282 + tid = int(self.query.get("tid")[0])
1.283 + stat = self.transcoders_log.get_status(tid, True)
1.284 + for status in stat:
1.285 + self.wfile.write("%s<br><br>" % status)
1.286 + else:
1.287 + stat = self.transcoders_log.get_status(None, True)
1.288 + for rtid, history in stat.iteritems():
1.289 + for status in history:
1.290 + self.wfile.write("<b>%s</b>: %s<br>" % (rtid, status))
1.291 + self.wfile.write("<br><br>")
1.292 + # serve_get_all_log()
1.293 +
1.294 + def serve_stream(self, body):
1.295 + transcoder = self._get_transcoder()
1.296 + try:
1.297 + obj = transcoder(self.query)
1.298 + except Exception, e:
1.299 + self.send_error(500, str(e))
1.300 + return
1.301 +
1.302 + self.send_response(200)
1.303 + self.send_header("Content-Type", obj.get_mimetype())
1.304 + self.send_header('Connection', 'close')
1.305 + self.end_headers()
1.306 +
1.307 + if body:
1.308 + test_tid = int(self.query.get("tid", "0")[0])
1.309 + if test_tid == 0 or test_tid not in self.tid_queue:
1.310 + test_tid = self._get_new_id(self.server.last_tid)
1.311 +
1.312 + self.transcoders_log.insert(test_tid, "gms.%s" % obj.name)
1.313 + obj.tid = test_tid
1.314 + obj.log = self.transcoders_log
1.315 +
1.316 + self.server.add_transcoders(self, obj)
1.317 + obj.start(self.wfile)
1.318 + self.server.del_transcoders(self, obj)
1.319 + # serve_stream()
1.320 +
1.321 +
1.322 + def log_request(self, code='-', size='-'):
1.323 + self.log.info('"%s" %s %s', self.requestline, str(code), str(size))
1.324 + # log_request()
1.325 +
1.326 +
1.327 + def log_error(self, format, *args):
1.328 + self.log.error("%s: %s" % (self.address_string(), format % args))
1.329 + # log_error()
1.330 +
1.331 +
1.332 + def log_message(self, format, *args):
1.333 + self.log.info("%s: %s" % (self.address_string(), format % args))
1.334 + # log_message()
1.335 +# RequestHandler