gmyth-stream/server/0.3/lib/request_handler.py
author morphbr
Fri Jun 01 19:41:45 2007 +0100 (2007-06-01)
branchtrunk
changeset 741 ffc7212656a5
parent 736 1bc4c47e4ad8
child 742 fe8ddffd7f5c
permissions -rw-r--r--
[svn r747] * GMyth-Stream
- status.do able to list all running transcoders
     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.3"
     7 
     8 import os
     9 import cgi
    10 import socket
    11 import logging
    12 import urlparse
    13 import threading
    14 import SocketServer
    15 import BaseHTTPServer
    16 
    17 import lib.utils as utils
    18 import lib.file_handler as files
    19 import lib.transcoder as transcoder
    20 
    21 from log import Log
    22 
    23 __all__ = ("RequestHandler")
    24 
    25 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    26     """Class that implements an HTTP request handler for our server."""
    27     log = logging.getLogger("gms.request")
    28     def_transcoder = None
    29     transcoders = utils.PluginSet(transcoder.Transcoder)
    30     transcoders_log = Log()
    31     tid_queue = []
    32 
    33     menu = {
    34         "Log": "/get_log.do",
    35         "Stop": "/stop-transcoder.do",
    36         "Status": "/status.do",
    37         "All Log": "/get_all_log.do",
    38         "Version": "/version.do",
    39         "Shutdown": "/shutdown.do"
    40         }
    41 
    42     @classmethod
    43     def load_plugins_transcoders(cls, directory):
    44         cls.transcoders.load_from_directory(directory)
    45 
    46         if cls.def_transcoder is None and cls.transcoders:
    47             cls.def_transcoder = cls.transcoders[0].name
    48     # load_plugins_transcoders()
    49 
    50 
    51     def do_dispatch(self, body):
    52         self.url = self.path
    53         pieces = urlparse.urlparse(self.path)
    54         self.path = pieces[2]
    55         self.query = cgi.parse_qs(pieces[4])
    56 
    57         url = {
    58             "/": self.serve_main,
    59             "/shutdown.do": self.serve_shutdown,
    60             "/stop-transcoder.do": self.serve_stop_transcoder,
    61             "/status.do": self.serve_status,
    62             "/version.do": self.serve_version,
    63             "/new_id.do": self.serve_new_id,
    64             "/get_log.do": self.serve_get_log,
    65             "/get_all_log.do": self.serve_get_all_log,
    66             "/stream.do": self.serve_stream,
    67             "/list.do": self.serve_list,
    68             }
    69 
    70         try:
    71             url[self.path](body)
    72         except KeyError, e:
    73             action = self.query.get("action", None)
    74             if action and "stream.do" in action:
    75                 self.serve_stream(body)
    76             else:
    77                 self.send_error(404, "File not found")
    78 
    79     # do_dispatch()
    80 
    81 
    82     def do_GET(self):
    83         self.do_dispatch(True)
    84     # do_GET()
    85 
    86 
    87     def do_HEAD(self):
    88         self.do_dispatch(False)
    89     # do_HEAD()
    90 
    91 
    92     def _nav_items(self):
    93         ret = ""
    94         for name, url in self.menu.items():
    95             ret += utils.getHTML("menu", {"name": name, "url": url})
    96         return ret
    97     # _nav_items()
    98 
    99 
   100     def serve_main(self, body):
   101         self.send_response(200)
   102         self.send_header("Content-Type", "text/html")
   103         self.send_header('Connection', 'close')
   104         self.end_headers()
   105         if body:
   106             self.wfile.write(utils.getHTML("index", {"menu": self._nav_items()}))
   107     # serve_main()
   108 
   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     # serve_version
   118 
   119 
   120     def serve_shutdown(self, body):
   121         self.send_response(200)
   122         self.send_header("Content-Type", "text/html")
   123         self.send_header('Connection', 'close')
   124         self.end_headers()
   125         if body:
   126             self.wfile.write(utils.getHTML("shutdown"))
   127         self.server.server_close()
   128     # serve_shutdown()
   129 
   130 
   131     def serve_list(self, body):
   132         self.send_response(200)
   133         self.send_header("Content-Type", "text/html")
   134         self.send_header('Connection', 'close')
   135         self.end_headers()
   136 
   137         if body:
   138             file_list = []
   139             files.list_media_files(".transcoded", file_list)
   140             output = files.FileList(map(lambda x, y: x+y, file_list,
   141                                         ["<br>"]*len(file_list)))
   142             self.wfile.write(output)
   143 
   144     # serve_list()
   145 
   146 
   147     def serve_stop_all_transcoders(self, body):
   148         self.send_response(200)
   149         self.send_header("Content-Type", "text/html")
   150         self.send_header('Connection', 'close')
   151         self.end_headers()
   152         if body:
   153             self.server.stop_transcoders()
   154             self.wfile.write(utils.getHTML("stop_all",
   155                                            {"menu": self._nav_items()}))
   156     # serve_stop_all_transcoders()
   157 
   158 
   159     def serve_stop_selected_transcoders(self, body, tids=[]):
   160         self.send_response(200)
   161         self.send_header("Content-Type", "text/html")
   162         self.send_header('Connection', 'close')
   163         self.end_headers()
   164         opts = ""
   165         if body:
   166             transcoders = self.server.get_transcoders()
   167 
   168             for tid in tids:
   169                 for t, r in transcoders:
   170                     if t.tid == int(tid):
   171                         try:
   172                             t.stop()
   173                         except Exception, e:
   174                             self.log.info("Plugin already stopped")
   175 
   176                         opts += utils._create_html_item("%s" % t)
   177 
   178                         break
   179 
   180                 self.wfile.write(utils.getHTML("stop_selected",
   181                                                {"menu": self._nav_items(),
   182                                                 "opts": opts}))
   183     # serve_stop_selected_transcoders()
   184 
   185 
   186     def serve_stop_transcoder(self, body):
   187         req = self.query.get("request", None)
   188         tid = self.query.get("tid", None)
   189         if req and "all" in req:
   190             self.serve_stop_all_transcoders(body)
   191         elif tid:
   192             self.serve_stop_selected_transcoders(body, tid[0].split(";"))
   193         else:
   194             self.serve_status(body)
   195     # serve_stop_transcoder()
   196 
   197 
   198     def serve_status(self, body):
   199         self.send_response(200)
   200         self.send_header("Content-Type", "text/html")
   201         self.send_header('Connection', 'close')
   202         self.end_headers()
   203         stopone = ""
   204         running = ""
   205         stopall = ""
   206 
   207         if body:
   208             tl = self.server.get_transcoders()
   209             if not tl and not self.query.get("tid", None) and \
   210                    not self.query.get("running", None):
   211                 running = "<p>No running transcoder.</p>\n"
   212 
   213             elif not tl and self.query.get("tid", None):
   214                 tids = self.query.get("tid")
   215                 for tid in tids:
   216                     stat = self.transcoders_log.get_status(int(tid))
   217                     self.wfile.write("%s<br>" % stat)
   218 
   219             elif self.query.get("running", None):
   220                 for transcoder, request in tl:
   221                     outf = transcoder.params_first("outfile")
   222                     tid = transcoder.tid
   223                     self.wfile.write("%s:%s<br>" % (tid, outf))
   224                 return True
   225 
   226             elif self.query.get("tid", None):
   227                 req_tid = self.query.get("tid")
   228                 for transcoder, request in tl:
   229                     if str(transcoder.tid) in req_tid:
   230                         self.wfile.write("Status:%s:%s %%" % (\
   231                             transcoder.tid, transcoder.status))
   232                 return True
   233 
   234             else:
   235                 running = "<p>Running transcoders:</p>\n"
   236                 stopall = utils._create_html_item("<a href='%s?request=all'>"
   237                                                  "[STOP ALL]</a>" %
   238                                                  self.menu["Stop"])
   239 
   240                 for transcoder, request in tl:
   241                     stopone += utils._create_html_item("%s;"
   242                                                        "<a href='%s?tid=%s'>"
   243                                                        " [STOP] </a>") % (
   244                         transcoder, self.menu["Stop"], transcoder.tid)
   245 
   246             self.wfile.write(utils.getHTML("status",
   247                                            {"menu": self._nav_items(),
   248                                             "running": running,
   249                                             "stopall": stopall,
   250                                             "stopone": stopone}))
   251     # serve_status()
   252 
   253 
   254     def _get_transcoder(self):
   255         # get transcoder option: mencoder is the default
   256         request_transcoders = self.query.get("transcoder", ["mencoder"])
   257 
   258         for t in request_transcoders:
   259             transcoder = self.transcoders.get(t)
   260             if transcoder:
   261                 return transcoder
   262 
   263         if not transcoder:
   264             return self.transcoders[self.def_transcoder]
   265     # _get_transcoder()
   266 
   267 
   268     def _get_new_id(self, tid):
   269         self.server.last_tid = utils.create_tid(tid)
   270         self.tid_queue.append(self.server.last_tid)
   271         return self.server.last_tid
   272     # _get_new_id()
   273 
   274 
   275     def serve_new_id(self, body):
   276         self.send_response(200)
   277         self.send_header("Content-Type", "text/html")
   278         self.send_header('Connection', 'close')
   279         self.end_headers()
   280 
   281         if body:
   282             self.wfile.write("%s" % self._get_new_id(self.server.last_tid))
   283     # serve_new_id()
   284 
   285     def serve_get_log(self, body):
   286         self.send_response(200)
   287         self.send_header("Content-Type", "text/html")
   288         self.send_header('Connection', 'close')
   289         self.end_headers()
   290 
   291         if body:
   292             if self.query.get("tid", None):
   293                 tid = int(self.query.get("tid")[0])
   294                 stat = self.transcoders_log.get_status(tid)
   295                 self.wfile.write("Status: %s" % stat)
   296             else:
   297                 stat = self.transcoders_log.get_status()
   298                 for rtid, status in stat.iteritems():
   299                     self.wfile.write("<b>%s</b>: %s<br><br>" % (rtid, status))
   300     # serve_get_log()
   301 
   302     def serve_get_all_log(self, body):
   303         self.send_response(200)
   304         self.send_header("Content-Type", "text/html")
   305         self.send_header('Connection', 'close')
   306         self.end_headers()
   307 
   308         if body:
   309             if self.query.get("tid", None):
   310                 tid = int(self.query.get("tid")[0])
   311                 stat = self.transcoders_log.get_status(tid, True)
   312                 for status in stat:
   313                     self.wfile.write("%s<br><br>" % status)
   314             else:
   315                 stat = self.transcoders_log.get_status(None, True)
   316                 for rtid, history in stat.iteritems():
   317                     for status in history:
   318                         self.wfile.write("<b>%s</b>: %s<br>" % (rtid, status))
   319                     self.wfile.write("<br><br>")
   320     # serve_get_all_log()
   321 
   322     def serve_stream(self, body):
   323         transcoder = self._get_transcoder()
   324         try:
   325             obj = transcoder(self.query)
   326         except Exception, e:
   327             self.send_error(500, str(e))
   328             print "teste2"
   329             return
   330 
   331         self.send_response(200)
   332         self.send_header("Content-Type", obj.get_mimetype())
   333         self.send_header('Connection', 'close')
   334         self.end_headers()
   335 
   336         if body:
   337             if self.query.get("transcoder", None):
   338                 test_tid = int(self.query.get("tid", "0")[0])
   339                 if test_tid == 0 or test_tid not in self.tid_queue:
   340                     test_tid = self._get_new_id(self.server.last_tid)
   341 
   342                 self.transcoders_log.insert(test_tid, "gms.%s" % obj.name)
   343                 obj.tid = test_tid
   344                 obj.log = self.transcoders_log
   345 
   346                 self.server.add_transcoders(self, obj)
   347                 obj.start(self.wfile)
   348                 self.server.del_transcoders(self, obj)
   349                 files.TranscodedFile("", self.query)
   350 
   351             elif self.query.get("type", "")[0] == "file" and \
   352                      self.query.get("uri", None):
   353                 media = open(self.query.get("uri", None)[0])
   354                 self.wfile.write(media.read())
   355     # serve_stream()
   356 
   357 
   358     def log_request(self, code='-', size='-'):
   359         self.log.info('"%s" %s %s', self.requestline, str(code), str(size))
   360     # log_request()
   361 
   362 
   363     def log_error(self, format, *args):
   364         self.log.error("%s: %s" % (self.address_string(), format % args))
   365     # log_error()
   366 
   367 
   368     def log_message(self, format, *args):
   369         self.log.info("%s: %s" % (self.address_string(), format % args))
   370     # log_message()
   371 
   372 # RequestHandler