コード例 #1
0
 def __init__(self, util, peppy):
     """ Initializer. Start web server in separate thread
     
     :param util: utility object contains configuration settings
     :param peppy: the reference to the root object
     """
     self.lock = RLock()
     self.config = util.config
     self.peppy = peppy
     self.web_clients = []
     self.player_listeners = []
     self.json_factory = JsonFactory(util, peppy)
     thread = Thread(target=self.start_web_server)
     thread.daemon = True
     thread.start()
コード例 #2
0
ファイル: webserver.py プロジェクト: project-owner/Peppy
 def __init__(self, util, peppy):
     """ Initializer
     
     :param util: utility object contains configuration settings
     :param peppy: the reference to the root object
     """
     self.config = util.config
     self.peppy = peppy
     self.jason_factory = JsonFactory(util, peppy)
     self.web_server_thread = threading.Thread(target=self.start)
     self.web_server_thread.start()
コード例 #3
0
ファイル: webserver.py プロジェクト: project-owner/Peppy
class WebServer(object):
    """ Starts simple HTTPServer in a separate thread """
    
    def __init__(self, util, peppy):
        """ Initializer
        
        :param util: utility object contains configuration settings
        :param peppy: the reference to the root object
        """
        self.config = util.config
        self.peppy = peppy
        self.jason_factory = JsonFactory(util, peppy)
        self.web_server_thread = threading.Thread(target=self.start)
        self.web_server_thread.start()
    
    def get_ip(self):
        """ Returns current IP address """
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            s.connect(('10.255.255.255', 0))
            ip = s.getsockname()[0]
        except:
            ip = '127.0.0.1'
        finally:
            s.close()
        return ip
        
    def start(self):
        """ Prepares request handler and starts web server """
        
        host = self.get_ip()

        port = self.config[WEB_SERVER][HTTP_PORT]
        handler = RequestHandler
        
        handler.screen_to_json = self.screen_to_json        
        self.create_screen = handler.create_screen = web.server.requesthandler.create_screen
        
        handler.title_to_json = self.title_to_json        
        self.title_change = handler.update_title = web.server.requesthandler.update_title
        
        handler.volume_to_json = self.volume_to_json        
        self.volume_change = handler.update_volume = web.server.requesthandler.update_volume
        
        handler.genre_button_to_json = self.genre_button_to_json        
        self.genre_button_pressed = handler.update_genre_button = web.server.requesthandler.update_genre_button
        
        handler.home_button_to_json = self.home_button_to_json        
        self.home_button_pressed = handler.update_home_button = web.server.requesthandler.update_home_button
        
        handler.left_button_to_json = self.left_button_to_json        
        self.left_button_pressed = handler.update_left_button = web.server.requesthandler.update_left_button
        
        handler.page_down_button_to_json = self.page_down_button_to_json        
        self.page_down_button_pressed = handler.update_page_down_button = web.server.requesthandler.update_page_down_button
        
        handler.right_button_to_json = self.right_button_to_json        
        self.right_button_pressed = handler.update_right_button = web.server.requesthandler.update_right_button
        
        handler.page_up_button_to_json = self.page_up_button_to_json        
        self.page_up_button_pressed = handler.update_page_up_button = web.server.requesthandler.update_page_up_button
        
        handler.station_menu_to_json = self.station_menu_to_json        
        self.update_station_menu = handler.update_station_menu = web.server.requesthandler.update_station_menu
        
        handler.genre_menu_to_json = self.genre_menu_to_json        
        self.update_genre_menu = handler.update_genre_menu = web.server.requesthandler.update_genre_menu
        
        handler.home_menu_to_json = self.home_menu_to_json        
        self.update_home_menu = handler.update_home_menu = web.server.requesthandler.update_home_menu
        
        handler.language_menu_to_json = self.language_menu_to_json        
        self.update_language_menu = handler.update_language_menu = web.server.requesthandler.update_language_menu
        
        handler.saver_screen_to_json = self.saver_screen_to_json        
        self.update_saver_screen = handler.update_saver_menu = web.server.requesthandler.update_saver_screen
        
        handler.about_screen_to_json = self.about_screen_to_json        
        self.update_about_screen = handler.update_about_screen = web.server.requesthandler.update_about_screen
        
        self.mode_listener = handler.mode_listener = web.server.requesthandler.mode_listener
        
        handler.play_button_to_json = self.play_button_to_json        
        self.play_button_pressed = handler.update_play_button = web.server.requesthandler.update_play_button
        
        handler.shutdown_button_to_json = self.shutdown_button_to_json        
        self.shutdown_button_pressed = handler.update_shutdown_button = web.server.requesthandler.update_shutdown_button
        
        handler.start_screensaver_to_json = self.start_screensaver_to_json
        handler.stop_screensaver_to_json = self.stop_screensaver_to_json
        self.start_screensaver = handler.start_screensaver = web.server.requesthandler.start_screensaver
        self.stop_screensaver = handler.stop_screensaver = web.server.requesthandler.stop_screensaver
        
        self.web_server = HTTPServer((host, int(port)), handler)        
        logging.debug("Web Server Started at %s:%s", host, port)
        
        try:
            self.web_server.serve_forever()
        except:
            pass

    def get_station_screen(self):
        """ Return Station Screen
        
        :return: the reference to the Station Screen
        """
        return self.peppy.screens["stations"]
    
    def get_genre_screen(self):
        """ Return Genre Screen
        
        :return: the reference to the Genre Screen
        """
        return self.peppy.screens["genres"]
    
    def get_home_screen(self):
        """ Return Home Screen
        
        :return: the reference to the Home Screen
        """
        return self.peppy.screens["home"]
    
    def get_language_screen(self):
        """ Return Language Screen
        
        :return: the reference to the Language Screen
        """
        return self.peppy.screens["language"]
    
    def get_saver_screen(self):
        """ Return Screensaver Screen
        
        :return: the reference to the Screensaver Screen
        """
        return self.peppy.screens["saver"]
    
    def get_about_screen(self):
        """ Return About Screen
        
        :return: the reference to the About Screen
        """
        return self.peppy.screens["about"]

    def screen_to_json(self):
        """ Convert current screen to JSON objects
        
        :return: list of JSON objects representing current screen
        """
        if self.peppy.screensaver_dispatcher.saver_running:
            self.peppy.screensaver_dispatcher.cancel_screensaver()
            self.peppy.screensaver_dispatcher.restart_dispatcher_thread()     
        current_screen = self.peppy.current_screen
        screen = self.peppy.screens[current_screen]        
        return self.jason_factory.screen_to_json(current_screen, screen)    
    
    def title_to_json(self):
        """ Convert title object into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.title_to_json(self.get_station_screen().screen_title)
        
    def volume_to_json(self):
        """ Convert volume object into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().volume)
        
    def genre_button_to_json(self):
        """ Convert genre button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().genres_button)
    
    def home_button_to_json(self):
        """ Convert home button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().home_button)
        
    def left_button_to_json(self):
        """ Convert left button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().left_button)
        
    def page_down_button_to_json(self):
        """ Convert page down button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().page_down_button)
        
    def right_button_to_json(self):
        """ Convert right button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().right_button)
        
    def page_up_button_to_json(self):
        """ Convert page up button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().page_up_button)
        
    def station_menu_to_json(self):
        """ Convert station menu into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.station_menu_to_json(self.get_station_screen().station_menu)
        
    def play_button_to_json(self):
        """ Convert play button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().play_button)
        
    def shutdown_button_to_json(self):
        """ Convert shutdown button into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.container_to_json(self.get_station_screen().shutdown_button)
    
    def genre_menu_to_json(self):
        """ Convert genre menu into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.genre_menu_to_json(self.get_genre_screen().genre_menu)
        
    def home_menu_to_json(self):
        """ Convert home menu into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.home_menu_to_json(self.get_home_screen().home_menu)
    
    def language_menu_to_json(self):
        """ Convert language menu into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.language_menu_to_json(self.get_language_screen().language_menu)
        
    def saver_screen_to_json(self):
        """ Convert screensaver screen into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.saver_screen_to_json(self.get_saver_screen())
    
    def about_screen_to_json(self):
        """ Convert about screen into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.about_screen_to_json(self.get_about_screen())
    
    def start_screensaver_to_json(self):
        """ Convert start screensaver event into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.start_screensaver_to_json()
    
    def stop_screensaver_to_json(self):
        """ Convert stop screensaver event into JSON object
        
        :return: JSON object
        """
        return self.jason_factory.stop_screensaver_to_json()

    def add_station_screen_web_listeners(self, stations):
        """ Add web listeners to station screen components
        
        :param stations: the stations screen
        """
        stations.screen_title.add_listener(self.title_change)
            
        stations.volume.add_slide_listener(self.volume_change)
        stations.volume.add_knob_listener(self.volume_change)
        stations.volume.add_press_listener(self.volume_change)
        stations.volume.add_motion_listener(self.volume_change)
            
        stations.genres_button.add_press_listener(self.genre_button_pressed)
        stations.genres_button.add_release_listener(self.create_screen)
            
        stations.home_button.add_press_listener(self.home_button_pressed)
        stations.home_button.add_release_listener(self.create_screen)
            
        stations.station_menu.add_menu_click_listener(self.update_station_menu)
        stations.station_menu.add_menu_click_listener(self.left_button_pressed)
        stations.station_menu.add_menu_click_listener(self.right_button_pressed)
        stations.station_menu.add_menu_click_listener(self.page_down_button_pressed)
        stations.station_menu.add_menu_click_listener(self.page_up_button_pressed)
        stations.station_menu.add_mode_listener(self.mode_listener)
            
        stations.left_button.add_press_listener(self.left_button_pressed)
        stations.left_button.add_release_listener(self.left_button_pressed)
        stations.left_button.add_release_listener(self.update_station_menu)
        stations.left_button.add_release_listener(self.right_button_pressed)
            
        stations.page_down_button.add_press_listener(self.page_down_button_pressed)
        stations.page_down_button.add_release_listener(self.page_down_button_pressed)
        stations.page_down_button.add_release_listener(self.update_station_menu)
        stations.page_down_button.add_release_listener(self.page_up_button_pressed)
            
        stations.right_button.add_press_listener(self.right_button_pressed)
        stations.right_button.add_release_listener(self.right_button_pressed)
        stations.right_button.add_release_listener(self.update_station_menu)
        stations.right_button.add_release_listener(self.left_button_pressed)
            
        stations.page_up_button.add_press_listener(self.page_up_button_pressed)
        stations.page_up_button.add_release_listener(self.page_up_button_pressed)
        stations.page_up_button.add_release_listener(self.update_station_menu)
        stations.page_up_button.add_release_listener(self.page_down_button_pressed)
            
        stations.play_button.add_press_listener(self.play_button_pressed)
        stations.play_button.add_release_listener(self.play_button_pressed)
            
        stations.shutdown_button.add_press_listener(self.shutdown_button_pressed)
        stations.shutdown_button.add_release_listener(self.shutdown_button_pressed)
        stations.shutdown_button.add_cancel_listener(self.shutdown_button_pressed)
        
    def add_genre_screen_web_listeners(self, genres):
        """ Add web listeners to genre screen components
        
        :param genres: the genres screen
        """
        genres.genre_menu.add_listener(self.create_screen)
        genres.genre_menu.add_move_listener(self.update_genre_menu)
    
    def add_home_screen_web_listeners(self, home):
        """ Add web listeners to home screen components
        
        :param home: the home screen
        """
        home.home_menu.add_listener(self.create_screen)
        home.home_menu.add_move_listener(self.update_home_menu)
        
    def add_language_screen_web_listeners(self, language):
        """ Add web listeners to language screen components
        
        :param language: the language screen
        """
        language.language_menu.add_listener(self.create_screen)
        language.language_menu.add_move_listener(self.update_language_menu)
        
    def add_saver_screen_web_listeners(self, saver):
        """ Add web listeners to screensaver screen components
        
        :param saver: the screensaver screen
        """
        saver.saver_menu.add_listener(self.create_screen)
        saver.delay_menu.add_listener(self.create_screen)
        saver.saver_menu.add_move_listener(self.update_saver_screen)
        saver.delay_menu.add_move_listener(self.update_saver_screen)
        
    def add_about_screen_web_listeners(self, about):
        """ Add web listeners to about screen
        
        :param about: the about screen
        """
        about.add_listener(self.create_screen)
        
    def add_screensaver_web_listener(self, screensaver_dispatcher):
        """ Add web listeners to screensaver start and stop events
        
        :param screensaver_dispatcher: the screensaver dispatcher
        """
        screensaver_dispatcher.add_start_listener(self.start_screensaver)
        screensaver_dispatcher.add_stop_listener(self.stop_screensaver)
    
    def shutdown(self):
        """ Shutdown Web Server """
        
        self.web_server.socket.close()
        
        
コード例 #4
0
ファイル: webserver.py プロジェクト: danpgh/Peppy
class WebServer(object):
    """ Starts Tornado web server in a separate thread """
    
    def __init__(self, util, peppy):
        """ Initializer. Start web server in separate thread
        
        :param util: utility object contains configuration settings
        :param peppy: the reference to the root object
        """
        self.util = util
        self.lock = RLock()
        self.config = util.config
        self.config_class = util.config_class
        self.peppy = peppy
        self.web_clients = []
        self.player_listeners = []
        self.json_factory = JsonFactory(util, peppy)
        thread = Thread(target=self.start_web_server)
        thread.daemon = True        
        thread.start()
     
    def start_web_server(self):
        """ Prepare request handlers and start server """
        
        root = os.getcwd()
        app = Application([
            (r"/()", StaticFileHandler, {"path": root, "default_filename": "index.html"}),
            (r"/web/client/(.*)", StaticFileHandler, {"path": root + "/web/client"}),
            (r"/font/(.*)", StaticFileHandler, {"path": root + "/font"}),
            (r"/icon/(.*)", StaticFileHandler, {"path": root + "/icons"}),
            (r"/flag/(.*)", StaticFileHandler, {"path": root + "/languages"}),
            (r"/ws", WebSocketHandler, {"redraw_web_ui": self.redraw_web_ui, "web_clients": self.web_clients}),
            (r"/config/()", StaticFileHandler, {"path": root + "/web/client/config", "default_filename": "index.html"}),
            (r"/config/icon/(.*)", StaticFileHandler, {"path": root + "/languages"}),
            (r"/config/default/(.*)", StaticFileHandler, {"path": root + "/icons"}),
            (r"/static/js/(.*)", StaticFileHandler, {"path": root + "/web/client/config/static/js"}),
            (r"/static/css/(.*)", StaticFileHandler, {"path": root + "/web/client/config/static/css"}),
            (r"/static/media/(.*)", StaticFileHandler, {"path": root + "/web/client/config/static/media"}),
            (r"/parameters", ParametersHandler, {"config_class": self.config_class}),
            (r"/players", PlayersHandler, {"config_class": self.config_class}),
            (r"/savers", ScreensaversHandler, {"config": self.config}),
            (r"/podcasts", PodcastsHandler, {"util": self.util}),
            (r"/streams", StreamsHandler, {"util": self.util}),
            (r"/streamimage/(.*)", StaticFileHandler, {"path": root + "/streams"}),
            (r"/playlists", PlaylistsHandler, {"util": self.util}),
            (r"/labels", LabelsHandler, {"util": self.util}),
            (r"/command/(.*)", CommandHandler, {"peppy": self.peppy}),
            (r"/upload", UploadHandler, {"path": root})
        ])

        if self.config[WEB_SERVER][HTTPS]:
            http_server = tornado.httpserver.HTTPServer(app, ssl_options={"certfile": "cert", "keyfile": "key"})
        else:
            http_server = tornado.httpserver.HTTPServer(app)

        port = self.config[WEB_SERVER][HTTP_PORT]
        http_server.listen(port)
        logging.debug("Web Server Started")
        tornado.ioloop.IOLoop.current().start()
    
    def update_web_ui(self, state):
        """ Update Web UI component
        
        :param state: object with Web UI component as event_origin attribute
        """
        if not (state and getattr(state, "event_origin", None) != None): return
        
        j = self.json_factory.container_to_json(state.event_origin)
        self.send_json_to_web_ui(j)
    
    def update_player_listeners(self, state=None):
        """ Update player listeners """
        
        for c in self.player_listeners:
            self.send_json_to_web_ui(self.json_factory.container_to_json(c))
    
    def redraw_web_ui(self, state=None):
        """ Redraw the whole screen in web UI """
        
        self.send_json_to_web_ui(self.screen_to_json())
            
    def start_screensaver_to_json(self, state=None):
        """ Send command to web UI to start screensaver """
        if state == None:
            self.send_json_to_web_ui(self.json_factory.start_screensaver_to_json())
        else:
            name = self.config[SCREENSAVER][NAME]
            screen = state.screen
            command = self.json_factory.screen_to_json(name, screen)
            self.send_json_to_web_ui(command)
    
    def start_time_control_to_json(self, state=None):
        """ Send start time control command to all web clients """
        
        j = self.json_factory.file_player_start_to_json()
        self.send_json_to_web_ui(j)        
        
    def stop_time_control_to_json(self, state=None):
        """ Send stop time control command to all web clients """
        
        j = self.json_factory.file_player_stop_to_json()
        self.send_json_to_web_ui(j)
    
    def stop_screensaver_to_json(self, state=None):
        """ Send command to web UI to stop screensaver """
        
        self.send_json_to_web_ui(self.json_factory.stop_screensaver_to_json())        
    
    def screen_to_json(self):
        """ Convert current screen to JSON objects
        
        :return: list of JSON objects representing current screen
        """
        current_screen = self.peppy.current_screen
        screen = self.peppy.screens[current_screen]
        if not screen.visible:
            if self.peppy.screensaver_dispatcher.saver_running:
                screen = self.peppy.screensaver_dispatcher.current_screensaver
                current_screen = self.peppy.screensaver_dispatcher.current_screensaver.name
                if current_screen not in WEB_SAVERS:
                    current_screen = KEY_ABOUT
                    screen = self.peppy.screens[KEY_ABOUT]
                    screen.visible = True
        return self.json_factory.screen_to_json(current_screen, screen)

    def station_menu_to_json(self, state):
        """ Convert station menu object into Json object
        
        :param menu: the station menu object
        
        :return: Json object
        """
        self.send_json_to_web_ui(self.screen_to_json())
    
    def title_to_json(self, title):
        """ Convert screen title to Json object
        
        :param title: screen title object
        """
        j = self.json_factory.title_to_json(title)
        self.send_json_to_web_ui(j)
    
    def send_json_to_web_ui(self, j):
        """ Send provided Json object to all web clients
        
        "param j": Json object to send
        """
        for c in self.web_clients:
            e = json.dumps(j).encode(encoding="utf-8")
            ioloop = tornado.ioloop.IOLoop.instance()
            ioloop.add_callback(c.write_message, e)

    def add_player_listener(self, listener):
        """ Add player web listener
        
        :param listener: player listener
        """
        if listener not in self.player_listeners:
            self.player_listeners.append(listener)
        
    def shutdown(self):
        """ Shutdown Web Server """
        
        ioloop = tornado.ioloop.IOLoop.instance()
        ioloop.add_callback(ioloop.stop)
コード例 #5
0
class WebServer(object):
    """ Starts Tornado web server in a separate thread """
    def __init__(self, util, peppy):
        """ Initializer. Start web server in separate thread
        
        :param util: utility object contains configuration settings
        :param peppy: the reference to the root object
        """
        self.lock = RLock()
        self.config = util.config
        self.peppy = peppy
        self.web_clients = []
        self.player_listeners = []
        self.json_factory = JsonFactory(util, peppy)
        thread = Thread(target=self.start_web_server)
        thread.daemon = True
        thread.start()

    def start_web_server(self):
        """ Prepare request handlers and start server """

        root = os.getcwd()
        index = "index.html"
        host = socket.gethostbyname(socket.gethostname())
        port = self.config[WEB_SERVER][HTTP_PORT]

        if tornado.version.startswith("5"):
            import asyncio
            asyncio.set_event_loop(asyncio.new_event_loop())

        indexHandler = (r"/()", tornado.web.StaticFileHandler, {
            "path": root,
            "default_filename": "index.html"
        })
        staticHandler = (r"/web/client/(.*)", tornado.web.StaticFileHandler, {
            "path": root + "/web/client"
        })
        fontHandler = (r"/font/(.*)", tornado.web.StaticFileHandler, {
            "path": root + "/font"
        })
        d = {
            "redraw_web_ui": self.redraw_web_ui,
            "web_clients": self.web_clients
        }
        webSocketHandler = (r"/ws", WebSocketHandler, d)
        application = tornado.web.Application(
            [indexHandler, staticHandler, fontHandler, webSocketHandler])
        http_server = tornado.httpserver.HTTPServer(application)
        http_server.listen(port)
        logging.debug("Web Server Started at %s:%s", host, port)
        tornado.ioloop.IOLoop.current().start()

    def update_web_ui(self, state):
        """ Update Web UI component
        
        :param state: object with Web UI component as event_origin attribute
        """
        if not (state and state.event_origin): return

        j = self.json_factory.container_to_json(state.event_origin)
        self.send_json_to_web_ui(j)

    def update_player_listeners(self, state=None):
        """ Update player listeners """

        for c in self.player_listeners:
            self.send_json_to_web_ui(self.json_factory.container_to_json(c))

    def redraw_web_ui(self, state=None):
        """ Redraw the whole screen in web UI """

        self.send_json_to_web_ui(self.screen_to_json())

    def start_screensaver_to_json(self, state=None):
        """ Send command to web UI to start screensaver """

        self.send_json_to_web_ui(self.json_factory.start_screensaver_to_json())

    def start_time_control_to_json(self, state=None):
        """ Send start time control command to all web clients """

        j = self.json_factory.file_player_start_to_json()
        self.send_json_to_web_ui(j)

    def stop_time_control_to_json(self, state=None):
        """ Send stop time control command to all web clients """

        j = self.json_factory.file_player_stop_to_json()
        self.send_json_to_web_ui(j)

    def stop_screensaver_to_json(self, state=None):
        """ Send command to web UI to stop screensaver """

        self.send_json_to_web_ui(self.json_factory.stop_screensaver_to_json())

    def screen_to_json(self):
        """ Convert current screen to JSON objects
        
        :return: list of JSON objects representing current screen
        """
        current_screen = self.peppy.current_screen
        screen = self.peppy.screens[current_screen]
        if not screen.visible:
            current_screen = KEY_ABOUT
            screen = self.peppy.screens[KEY_ABOUT]
            screen.visible = True
        return self.json_factory.screen_to_json(current_screen, screen)

    def station_menu_to_json(self, state):
        """ Convert station menu object into Json object
        
        :param menu: the station menu object
        
        :return: Json object
        """
        self.send_json_to_web_ui(self.screen_to_json())

    def title_to_json(self, title):
        """ Convert screen title to Json object
        
        :param title: screen title object
        """
        j = self.json_factory.title_to_json(title)
        self.send_json_to_web_ui(j)

    def send_json_to_web_ui(self, j):
        """ Send provided Json object to all web clients
        
        "param j" Json object to send
        """
        for c in self.web_clients:
            e = json.dumps(j).encode(encoding="utf-8")
            ioloop = tornado.ioloop.IOLoop.instance()
            ioloop.add_callback(c.write_message, e)

    def add_player_listener(self, listener):
        """ Add player web listener
        
        :param listener: player listener
        """
        if listener not in self.player_listeners:
            self.player_listeners.append(listener)

    def shutdown(self):
        """ Shutdown Web Server """

        ioloop = tornado.ioloop.IOLoop.instance()
        ioloop.add_callback(ioloop.stop)