gmyth-stream/server/0.3/lib/request_handler.py
author rosfran
Wed May 30 14:46:18 2007 +0100 (2007-05-30)
branchtrunk
changeset 720 365a09aee64b
child 723 f5f7abc760aa
permissions -rw-r--r--
[svn r726] Fixed bug on NUV extendend header parsing.
     1 #!/usr/bin/env python
     2 
     3 __author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
     4 __author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
     5 __license__ = "GPL"
     6 __version__ = "0.4"
     7 
     8 import os
     9 import threading
    10 import SocketServer
    11 import BaseHTTPServer
    12 import socket
    13 import urlparse
    14 import cgi
    15 import lib.utils as utils
    16 import logging
    17 
    18 from log import Log
    19 import lib.transcoder as transcoder
    20 
    21 __all__ = ("RequestHandler")
    22 
    23 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    24     """Class that implements an HTTP request handler for our server."""
    25     log = logging.getLogger("gms.request")
    26     def_transcoder = None
    27     transcoders = utils.PluginSet(transcoder.Transcoder)
    28     transcoders_log = Log()
    29     tid_queue = []
    30 
    31     menu = {
    32         "Log": "/get_log.do",
    33         "Stop": "/stop-transcoder.do",
    34         "Status": "/status.do",
    35         "All Log": "/get_all_log.do",
    36         "Version": "/version.do",
    37         "Shutdown": "/shutdown.do"
    38         }
    39 
    40     @classmethod
    41     def load_plugins_transcoders(cls, directory):
    42         cls.transcoders.load_from_directory(directory)
    43 
    44         if cls.def_transcoder is None and cls.transcoders:
    45             cls.def_transcoder = cls.transcoders[0].name
    46     # load_plugins_transcoders()
    47 
    48 
    49     def do_dispatch(self, body):
    50         self.url = self.path
    51 
    52         pieces = urlparse.urlparse(self.path)
    53         self.path = pieces[2]
    54         self.query = cgi.parse_qs(pieces[4])
    55 
    56         if self.path == "/":
    57             self.serve_main(body)
    58         elif self.path == "/shutdown.do":
    59             self.serve_shutdown(body)
    60         elif self.path == "/stop-transcoder.do":
    61             self.serve_stop_transcoder(body)
    62         elif self.path == "/status.do":
    63             self.serve_status(body)
    64         elif self.path == "/version.do":
    65             self.serve_version(body)
    66         elif self.path == "/new_id.do":
    67             self.serve_new_id(body)
    68         elif self.path == "/get_log.do":
    69             self.serve_get_log(body)
    70         elif self.path == "/get_all_log.do":
    71             self.serve_get_all_log(body)
    72         elif self.path == "/stream.do":
    73             self.serve_stream(body)
    74         else:
    75             action = self.query.get("action", None)
    76             if action and "stream.do" in action:
    77                 self.serve_stream(body)
    78             else:
    79                 self.send_error(404, "File not found")
    80     # do_dispatch()
    81 
    82 
    83     def do_GET(self):
    84         self.do_dispatch(True)
    85     # do_GET()
    86 
    87 
    88     def do_HEAD(self):
    89         self.do_dispatch(False)
    90     # do_HEAD()
    91 
    92 
    93     def _nav_items(self):
    94         ret = ""
    95         for name, url in self.menu.items():
    96             ret += utils.getHTML("menu", {"name": name, "url": url})
    97 
    98         return ret
    99     # _nav_items()
   100 
   101     def serve_main(self, body):
   102         self.send_response(200)
   103         self.send_header("Content-Type", "text/html")
   104         self.send_header('Connection', 'close')
   105         self.end_headers()
   106         if body:
   107             self.wfile.write(utils.getHTML("index", {"menu": self._nav_items()}))
   108     # serve_main()
   109 
   110     def serve_version(self, body):
   111         self.send_response(200)
   112         self.send_header("Content-Type", "text/html")
   113         self.send_header('Connection', 'close')
   114         self.end_headers()
   115         if body:
   116             self.wfile.write("Version: %s" %  __version__)
   117 
   118 
   119     def serve_shutdown(self, body):
   120         self.send_response(200)
   121         self.send_header("Content-Type", "text/html")
   122         self.send_header('Connection', 'close')
   123         self.end_headers()
   124         if body:
   125             self.wfile.write(utils.getHTML("shutdown"))
   126         self.server.server_close()
   127     # serve_shutdown()
   128 
   129 
   130     def serve_stop_all_transcoders(self, body):
   131         self.send_response(200)
   132         self.send_header("Content-Type", "text/html")
   133         self.send_header('Connection', 'close')
   134         self.end_headers()
   135         if body:
   136             self.server.stop_transcoders()
   137             self.wfile.write(utils.getHTML("stop_all", {"menu": self._nav_items()}))
   138     # serve_stop_all_transcoders()
   139 
   140 
   141     def serve_stop_selected_transcoders(self, body, tids=[]):
   142         self.send_response(200)
   143         self.send_header("Content-Type", "text/html")
   144         self.send_header('Connection', 'close')
   145         self.end_headers()
   146         opts = ""
   147         if body:
   148             transcoders = self.server.get_transcoders()
   149 
   150             for tid in tids:
   151                 for t, r in transcoders:
   152                     if t.tid == int(tid):
   153                         try:
   154                             t.stop()
   155                         except Exception, e:
   156                             self.log.info("Plugin already stopped")
   157 
   158                         opts += utils._create_html_item("%s" % t)
   159 
   160                         break
   161 
   162                 self.wfile.write(utils.getHTML("stop_selected",
   163                                                {"menu": self._nav_items(),
   164                                                 "opts": opts}))
   165     # serve_stop_selected_transcoders()
   166 
   167 
   168     def serve_stop_transcoder(self, body):
   169         req = self.query.get("request", None)
   170         tid = self.query.get("tid", None)
   171         if req and "all" in req:
   172             self.serve_stop_all_transcoders(body)
   173         elif tid:
   174             self.serve_stop_selected_transcoders(body, tid[0].split(";"))
   175         else:
   176             self.serve_status(body)
   177     # serve_stop_transcoder()
   178 
   179 
   180     def serve_status(self, body):
   181         self.send_response(200)
   182         self.send_header("Content-Type", "text/html")
   183         self.send_header('Connection', 'close')
   184         self.end_headers()
   185         stopone = ""
   186 
   187         if body:
   188             tl = self.server.get_transcoders()
   189             if not tl:
   190                 running = "<p>No running transcoder.</p>\n"
   191                 stopall = ""
   192                 stopone = ""
   193 
   194             elif self.query.get("tid", None):
   195                 req_tid = int(self.query.get("tid")[0])
   196                 for transcoder, request in tl:
   197                     if transcoder.tid == req_tid:
   198                         self.wfile.write("Status: %s %%" % transcoder.status)
   199                         return True
   200 
   201                 return False
   202 
   203             else:
   204                 running = "<p>Running transcoders:</p>\n"
   205                 stopall = utils._create_html_item("<a href='%s?request=all'>"
   206                                                  "[STOP ALL]</a>" %
   207                                                  self.menu["Stop"])
   208 
   209                 for transcoder, request in tl:
   210                     stopone += utils._create_html_item("%s;"
   211                                                        "<a href='%s?tid=%s'>"
   212                                                        " [STOP] </a>") % (
   213                         transcoder, self.menu["Stop"], transcoder.tid)
   214 
   215             self.wfile.write(utils.getHTML("status",
   216                                            {"menu": self._nav_items(),
   217                                             "running": running,
   218                                             "stopall": stopall,
   219                                             "stopone": stopone}))
   220     # serve_status()
   221 
   222 
   223     def _get_transcoder(self):
   224         # get transcoder option: mencoder is the default
   225         request_transcoders = self.query.get("transcoder", ["mencoder"])
   226 
   227         for t in request_transcoders:
   228             transcoder = self.transcoders.get(t)
   229             if transcoder:
   230                 return transcoder
   231 
   232         if not transcoder:
   233             return self.transcoders[self.def_transcoder]
   234     # _get_transcoder()
   235 
   236 
   237     def _get_new_id(self, tid):
   238         self.server.last_tid = utils.create_tid(tid)
   239         self.tid_queue.append(self.server.last_tid)
   240         return self.server.last_tid
   241     # _get_new_id()
   242 
   243 
   244     def serve_new_id(self, body):
   245         self.send_response(200)
   246         self.send_header("Content-Type", "text/html")
   247         self.send_header('Connection', 'close')
   248         self.end_headers()
   249 
   250         if body:
   251             self.wfile.write("%s" % self._get_new_id(self.server.last_tid))
   252     # serve_new_id()
   253 
   254     def serve_get_log(self, body):
   255         self.send_response(200)
   256         self.send_header("Content-Type", "text/html")
   257         self.send_header('Connection', 'close')
   258         self.end_headers()
   259 
   260         if body:
   261             if self.query.get("tid", None):
   262                 tid = int(self.query.get("tid")[0])
   263                 stat = self.transcoders_log.get_status(tid)
   264                 self.wfile.write("%s" % stat)
   265             else:
   266                 stat = self.transcoders_log.get_status()
   267                 for rtid, status in stat.iteritems():
   268                     self.wfile.write("<b>%s</b>: %s<br><br>" % (rtid, status))
   269     # serve_get_log()
   270 
   271     def serve_get_all_log(self, body):
   272         self.send_response(200)
   273         self.send_header("Content-Type", "text/html")
   274         self.send_header('Connection', 'close')
   275         self.end_headers()
   276 
   277         if body:
   278             if self.query.get("tid", None):
   279                 tid = int(self.query.get("tid")[0])
   280                 stat = self.transcoders_log.get_status(tid, True)
   281                 for status in stat:
   282                     self.wfile.write("%s<br><br>" % status)
   283             else:
   284                 stat = self.transcoders_log.get_status(None, True)
   285                 for rtid, history in stat.iteritems():
   286                     for status in history:
   287                         self.wfile.write("<b>%s</b>: %s<br>" % (rtid, status))
   288                     self.wfile.write("<br><br>")
   289     # serve_get_all_log()
   290 
   291     def serve_stream(self, body):
   292         transcoder = self._get_transcoder()
   293         try:
   294             obj = transcoder(self.query)
   295         except Exception, e:
   296             self.send_error(500, str(e))
   297             return
   298 
   299         self.send_response(200)
   300         self.send_header("Content-Type", obj.get_mimetype())
   301         self.send_header('Connection', 'close')
   302         self.end_headers()
   303 
   304         if body:
   305             test_tid = int(self.query.get("tid", "0")[0])
   306             if test_tid == 0 or test_tid not in self.tid_queue:
   307                 test_tid = self._get_new_id(self.server.last_tid)
   308 
   309             self.transcoders_log.insert(test_tid, "gms.%s" % obj.name)
   310             obj.tid = test_tid
   311             obj.log = self.transcoders_log
   312 
   313             self.server.add_transcoders(self, obj)
   314             obj.start(self.wfile)
   315             self.server.del_transcoders(self, obj)
   316     # serve_stream()
   317 
   318 
   319     def log_request(self, code='-', size='-'):
   320         self.log.info('"%s" %s %s', self.requestline, str(code), str(size))
   321     # log_request()
   322 
   323 
   324     def log_error(self, format, *args):
   325         self.log.error("%s: %s" % (self.address_string(), format % args))
   326     # log_error()
   327 
   328 
   329     def log_message(self, format, *args):
   330         self.log.info("%s: %s" % (self.address_string(), format % args))
   331     # log_message()
   332 # RequestHandler