3 __author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
4 __author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
17 import lib.utils as utils
18 import lib.file_handler as files
19 import lib.transcoder as transcoder
23 __all__ = ("RequestHandler")
25 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
26 """Class that implements an HTTP request handler for our server."""
27 log = logging.getLogger("gms.request")
29 transcoders = utils.PluginSet(transcoder.Transcoder)
30 transcoders_log = Log()
35 "Stop": "/stop-transcoder.do",
36 "Status": "/status.do",
37 "All Log": "/get_all_log.do",
38 "Version": "/version.do",
39 "Shutdown": "/shutdown.do"
43 def load_plugins_transcoders(cls, directory):
44 cls.transcoders.load_from_directory(directory)
46 if cls.def_transcoder is None and cls.transcoders:
47 cls.def_transcoder = cls.transcoders[0].name
48 # load_plugins_transcoders()
51 def do_dispatch(self, body):
53 pieces = urlparse.urlparse(self.path)
55 self.query = cgi.parse_qs(pieces[4])
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 "/get_file_info.do": self.serve_file_info,
75 action = self.query.get("action", None)
76 if action and "stream.do" in action:
77 self.serve_stream(body)
78 elif os.path.exists("html/%s" % self.path):
79 data = open("html/%s" % self.path)
80 self.wfile.write(data.read())
82 self.send_error(404, "File not found")
90 self.do_dispatch(True)
95 self.do_dispatch(False)
101 for name, url in self.menu.items():
102 ret += utils.getHTML("menu", {"name": name, "url": url})
107 def serve_main(self, body):
108 self.send_response(200)
109 self.send_header("Content-Type", "text/html")
110 self.send_header('Connection', 'close')
113 self.wfile.write(utils.getHTML("index", {"menu": self._nav_items()}))
117 def serve_version(self, body):
118 self.send_response(200)
119 self.send_header("Content-Type", "text/html")
120 self.send_header('Connection', 'close')
123 self.wfile.write("Version: %s" % __version__)
127 def serve_shutdown(self, body):
128 self.send_response(200)
129 self.send_header("Content-Type", "text/html")
130 self.send_header('Connection', 'close')
133 self.wfile.write(utils.getHTML("shutdown"))
134 self.server.server_close()
138 def serve_list(self, body):
139 self.send_response(200)
140 self.send_header("Content-Type", "text/html")
141 self.send_header('Connection', 'close')
146 files.list_media_files(".transcoded", file_list)
147 output = files.FileList(map(lambda x, y: x+y, file_list,
148 ["<br>"]*len(file_list)))
149 self.wfile.write(output)
154 def serve_stop_all_transcoders(self, body):
155 self.send_response(200)
156 self.send_header("Content-Type", "text/html")
157 self.send_header('Connection', 'close')
160 self.server.stop_transcoders()
161 self.wfile.write(utils.getHTML("stop_all",
162 {"menu": self._nav_items()}))
163 # serve_stop_all_transcoders()
166 def serve_stop_selected_transcoders(self, body, tids=[]):
167 self.send_response(200)
168 self.send_header("Content-Type", "text/html")
169 self.send_header('Connection', 'close')
173 transcoders = self.server.get_transcoders()
176 for t, r in transcoders:
177 if t.tid == int(tid):
181 self.log.info("Plugin already stopped")
183 opts += utils._create_html_item("%s" % t)
187 self.wfile.write(utils.getHTML("stop_selected",
188 {"menu": self._nav_items(),
190 # serve_stop_selected_transcoders()
193 def serve_stop_transcoder(self, body):
194 req = self.query.get("request", None)
195 tid = self.query.get("tid", None)
196 if req and "all" in req:
197 self.serve_stop_all_transcoders(body)
199 self.serve_stop_selected_transcoders(body, tid[0].split(";"))
201 self.serve_status(body)
202 # serve_stop_transcoder()
205 def serve_status(self, body):
206 self.send_response(200)
207 self.send_header("Content-Type", "text/html")
208 self.send_header('Connection', 'close')
215 tl = self.server.get_transcoders()
216 if not tl and not self.query.get("tid", None) and \
217 not self.query.get("running", None):
218 running = "<p>No running transcoder.</p>\n"
220 elif not tl and self.query.get("tid", None):
221 tids = self.query.get("tid")
223 stat = self.transcoders_log.get_status(int(tid))
224 self.wfile.write("%s<br>" % stat)
227 elif self.query.get("running", None):
228 for transcoder, request in tl:
229 outf = transcoder.params_first("outfile")
231 self.wfile.write("%s:%s<br>" % (tid, outf))
234 elif self.query.get("tid", None):
235 req_tid = self.query.get("tid")
236 for transcoder, request in tl:
237 if str(transcoder.tid) in req_tid:
238 self.wfile.write("Status:%s:%s %%" % (\
239 transcoder.tid, transcoder.status))
243 running = "<p>Running transcoders:</p>\n"
244 stopall = utils._create_html_item("<a href='%s?request=all'>"
248 for transcoder, request in tl:
249 stopone += utils._create_html_item("%s;"
250 "<a href='%s?tid=%s'>"
252 transcoder, self.menu["Stop"], transcoder.tid)
254 self.wfile.write(utils.getHTML("status",
255 {"menu": self._nav_items(),
258 "stopone": stopone}))
262 def _get_transcoder(self):
263 # get transcoder option: mencoder is the default
264 request_transcoders = self.query.get("transcoder", ["mencoder"])
266 for t in request_transcoders:
267 transcoder = self.transcoders.get(t)
272 return self.transcoders[self.def_transcoder]
276 def _get_new_id(self, tid):
277 self.server.last_tid = utils.create_tid(tid)
278 self.tid_queue.append(self.server.last_tid)
279 return self.server.last_tid
283 def serve_new_id(self, body):
284 self.send_response(200)
285 self.send_header("Content-Type", "text/html")
286 self.send_header('Connection', 'close')
290 self.wfile.write("%s" % self._get_new_id(self.server.last_tid))
293 def serve_get_log(self, body):
294 self.send_response(200)
295 self.send_header("Content-Type", "text/html")
296 self.send_header('Connection', 'close')
300 if self.query.get("tid", None):
301 tid = int(self.query.get("tid")[0])
302 stat = self.transcoders_log.get_status(tid)
303 self.wfile.write("Status: %s" % stat)
305 stat = self.transcoders_log.get_status()
306 for rtid, status in stat.iteritems():
307 self.wfile.write("<b>%s</b>: %s<br><br>" % (rtid, status))
310 def serve_get_all_log(self, body):
311 self.send_response(200)
312 self.send_header("Content-Type", "text/html")
313 self.send_header('Connection', 'close')
317 if self.query.get("tid", None):
318 tid = int(self.query.get("tid")[0])
319 stat = self.transcoders_log.get_status(tid, True)
321 self.wfile.write("%s<br><br>" % status)
323 stat = self.transcoders_log.get_status(None, True)
324 for rtid, history in stat.iteritems():
325 for status in history:
326 self.wfile.write("<b>%s</b>: %s<br>" % (rtid, status))
327 self.wfile.write("<br><br>")
328 # serve_get_all_log()
331 def serve_file_info(self, body):
334 file_dat = self.query.get("file", None)
337 self.send_response(200)
338 self.send_header("Content-Type", "text/html")
339 self.send_header('Connection', 'close')
343 opts = files.TranscodedFile(filename, self.query).opts
344 for key in opts.keys():
345 self.wfile.write("%s=%s<br>" % (key, opts.get(key, "None")))
347 self.send_error(500, str(e))
351 def serve_stream(self, body):
352 transcoder = self._get_transcoder()
354 obj = transcoder(self.query)
356 self.send_error(500, str(e))
359 self.send_response(200)
360 self.send_header("Content-Type", obj.get_mimetype())
361 self.send_header("Cache-Control","no-cache")
363 if (obj.name == "gmencoder"):
364 self.send_header("Transfer-Encoding", "chunked")
366 self.send_header("Connection", "close")
371 test_tid = int(self.query.get("tid", "0")[0])
372 if test_tid == 0 or test_tid not in self.tid_queue:
373 test_tid = self._get_new_id(self.server.last_tid)
376 if self.query.get("transcoder", None):
377 self.transcoders_log.insert(test_tid, "gms.%s" % obj.name)
379 obj.log = self.transcoders_log
381 self.server.add_transcoders(self, obj)
382 obj.start(self.wfile)
383 self.server.del_transcoders(self, obj)
384 files.TranscodedFile("", self.query)
386 elif self.query.get("type", "")[0] == "file" and \
387 self.query.get("uri", None):
389 filename = self.query.get("uri", None)[0]
390 self.transcoders_log.insert(test_tid, "gms.%s" % filename)
393 media = open(filename)
396 size = int(os.path.getsize(filename))
399 data_in = media.read(4096)
401 self.wfile.write(data_in)
402 status = utils.progress_bar(total_read, size, 50)
403 msg_status = "Status:%s:%s%%" % (test_tid, status)
404 self.transcoders_log._update_status(test_tid,
407 self.transcoders_log._update_status(test_tid, "OK: Done")
410 self.log.error("Stream error: %s" %e)
411 self.transcoders_log._update_status(test_tid,
416 def log_request(self, code='-', size='-'):
417 self.log.info('"%s" %s %s', self.requestline, str(code), str(size))
421 def log_error(self, format, *args):
422 self.log.error("%s: %s" % (self.address_string(), format % args))
426 def log_message(self, format, *args):
427 self.log.info("%s: %s" % (self.address_string(), format % args))