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: from request_handler import RequestHandler
morphbr@718: 
morphbr@718: __all__ = ("Server", "serve_forever", "load_plugins_transcoders")
morphbr@718: 
morphbr@718: class Server(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
morphbr@718:     log = logging.getLogger("gms.server")
morphbr@718:     last_tid = 0
morphbr@718:     run = True
morphbr@718:     _transcoders = {}
morphbr@718:     _lock = threading.RLock()
morphbr@718: 
morphbr@718:     def serve_forever(self):
morphbr@718:         self.log.info("GMyth-Streamer serving HTTP on %s:%s" %
morphbr@718:                       self.socket.getsockname())
morphbr@718:         try:
morphbr@718:             while self.run:
morphbr@718:                 self.handle_request()
morphbr@718:         except KeyboardInterrupt, e:
morphbr@718:             pass
morphbr@718: 
morphbr@718:         self.log.debug("Stopping all remaining transcoders...")
morphbr@718:         self.stop_transcoders()
morphbr@718:         self.log.debug("Transcoders stopped!")
morphbr@718:     # serve_forever()
morphbr@718: 
morphbr@718: 
morphbr@718:     def get_request(self):
morphbr@718:         skt = self.socket
morphbr@718:         old = skt.gettimeout()
morphbr@718:         skt.settimeout(0.5)
morphbr@718:         while self.run:
morphbr@718:             try:
morphbr@718:                 r = skt.accept()
morphbr@718:                 skt.settimeout(old)
morphbr@718:                 return r
morphbr@718:             except socket.timeout, e:
morphbr@718:                 pass
morphbr@718:         raise socket.error("Not running")
morphbr@718:     # get_request()
morphbr@718: 
morphbr@718: 
morphbr@718:     def server_close(self):
morphbr@718:         self.run = False
morphbr@718:         self.stop_transcoders()
morphbr@718: 
morphbr@718:         BaseHTTPServer.HTTPServer.server_close(self)
morphbr@718:     # server_close()
morphbr@718: 
morphbr@718: 
morphbr@718:     def stop_transcoders(self):
morphbr@718:         self._lock.acquire()
morphbr@718:         for transcoder, request in self._transcoders.iteritems():
morphbr@718:             self.log.info("Stop transcoder: %s, client=%s" %
morphbr@718:                           (transcoder, request.client_address))
morphbr@718:             transcoder.stop()
morphbr@718:         self._lock.release()
morphbr@718:     # stop_transcoders()
morphbr@718: 
morphbr@718: 
morphbr@718:     def get_transcoders(self):
morphbr@718:         self._lock.acquire()
morphbr@718:         try:
morphbr@718:             return self._transcoders.items()
morphbr@718:         finally:
morphbr@718:             self._lock.release()
morphbr@718:     # get_transcoders()
morphbr@718: 
morphbr@718: 
morphbr@718:     def add_transcoders(self, request, transcoder):
morphbr@718:         self._lock.acquire()
morphbr@718:         try:
morphbr@718:             self._transcoders[transcoder] = request
morphbr@718:         finally:
morphbr@718:             self._lock.release()
morphbr@718:     # add_transcoders()
morphbr@718: 
morphbr@718: 
morphbr@718:     def del_transcoders(self, request, transcoder):
morphbr@718:         self._lock.acquire()
morphbr@718:         try:
morphbr@718:             del self._transcoders[transcoder]
morphbr@718:         finally:
morphbr@718:             self._lock.release()
morphbr@718:     # del_transcoders()
morphbr@718: # Server
morphbr@718: 
morphbr@718: 
morphbr@718: 
morphbr@718: def serve_forever(host="0.0.0.0", port=40000):
morphbr@718:     addr = (host, port)
morphbr@718:     RequestHandler.protocol_version = "HTTP/1.0"
morphbr@718:     httpd = Server(addr, RequestHandler)
morphbr@718:     httpd.serve_forever()
morphbr@718: # serve_forever()
morphbr@718: 
morphbr@718: 
morphbr@718: def load_plugins_transcoders(directory):
morphbr@718:     RequestHandler.load_plugins_transcoders(directory)
morphbr@718: # load_plugins_transcoders()