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)
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)