<s> from __future__ import absolute_import , unicode_literals <EOL> import functools <EOL> import logging <EOL> import os <EOL> import socket <EOL> import tornado . escape <EOL> import tornado . ioloop <EOL> import tornado . web <EOL> import tornado . websocket <EOL> import mopidy <EOL> from mopidy import core , models <EOL> from mopidy . internal import encoding , jsonrpc <EOL> logger = logging . getLogger ( __name__ ) <EOL> def make_mopidy_app_factory ( apps , statics ) : <EOL> def mopidy_app_factory ( config , core ) : <EOL> return [ <EOL> ( r'<STR_LIT>' , WebSocketHandler , { <EOL> '<STR_LIT>' : core , <EOL> } ) , <EOL> ( r'<STR_LIT>' , JsonRpcHandler , { <EOL> '<STR_LIT>' : core , <EOL> } ) , <EOL> ( r'<STR_LIT>' , StaticFileHandler , { <EOL> '<STR_LIT:path>' : os . path . join ( os . path . dirname ( __file__ ) , '<STR_LIT:data>' ) , <EOL> } ) , <EOL> ( r'<STR_LIT:/>' , ClientListHandler , { <EOL> '<STR_LIT>' : apps , <EOL> '<STR_LIT>' : statics , <EOL> } ) , <EOL> ] <EOL> return mopidy_app_factory <EOL> def make_jsonrpc_wrapper ( core_actor ) : <EOL> inspector = jsonrpc . JsonRpcInspector ( <EOL> objects = { <EOL> '<STR_LIT>' : core . Core . get_uri_schemes , <EOL> '<STR_LIT>' : core . Core . get_version , <EOL> '<STR_LIT>' : core . HistoryController , <EOL> '<STR_LIT>' : core . LibraryController , <EOL> '<STR_LIT>' : core . MixerController , <EOL> '<STR_LIT>' : core . PlaybackController , <EOL> '<STR_LIT>' : core . PlaylistsController , <EOL> '<STR_LIT>' : core . TracklistController , <EOL> } ) <EOL> return jsonrpc . JsonRpcWrapper ( <EOL> objects = { <EOL> '<STR_LIT>' : inspector . describe , <EOL> '<STR_LIT>' : core_actor . get_uri_schemes , <EOL> '<STR_LIT>' : core_actor . get_version , <EOL> '<STR_LIT>' : core_actor . history , <EOL> '<STR_LIT>' : core_actor . library , <EOL> '<STR_LIT>' : core_actor . mixer , <EOL> '<STR_LIT>' : core_actor . playback , <EOL> '<STR_LIT>' : core_actor . playlists , <EOL> '<STR_LIT>' : core_actor . tracklist , <EOL> } , <EOL> decoders = [ models . model_json_decoder ] , <EOL> encoders = [ models . ModelJSONEncoder ] <EOL> ) <EOL> def _send_broadcast ( client , msg ) : <EOL> try : <EOL> client . write_message ( msg ) <EOL> except Exception as e : <EOL> error_msg = encoding . locale_decode ( e ) <EOL> logger . debug ( '<STR_LIT>' , <EOL> client . request . remote_ip , error_msg ) <EOL> class WebSocketHandler ( tornado . websocket . WebSocketHandler ) : <EOL> clients = set ( ) <EOL> @ classmethod <EOL> def broadcast ( cls , msg ) : <EOL> if hasattr ( tornado . ioloop . IOLoop , '<STR_LIT>' ) : <EOL> loop = tornado . ioloop . IOLoop . current ( ) <EOL> else : <EOL> loop = tornado . ioloop . IOLoop . instance ( ) <EOL> for client in cls . clients : <EOL> loop . add_callback ( functools . partial ( _send_broadcast , client , msg ) ) <EOL> def initialize ( self , core ) : <EOL> self . jsonrpc = make_jsonrpc_wrapper ( core ) <EOL> def open ( self ) : <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> self . set_nodelay ( True ) <EOL> else : <EOL> self . stream . socket . setsockopt ( <EOL> socket . IPPROTO_TCP , socket . TCP_NODELAY , <NUM_LIT:1> ) <EOL> self . clients . add ( self ) <EOL> logger . debug ( <EOL> '<STR_LIT>' , self . request . remote_ip ) <EOL> def on_close ( self ) : <EOL> self . clients . discard ( self ) <EOL> logger . debug ( <EOL> '<STR_LIT>' , <EOL> self . request . remote_ip ) <EOL> def on_message ( self , message ) : <EOL> if not message : <EOL> return <EOL> logger . debug ( <EOL> '<STR_LIT>' , <EOL> self . request . remote_ip , message ) <EOL> try : <EOL> response = self . jsonrpc . handle_json ( <EOL> tornado . escape . native_str ( message ) ) <EOL> if response and self . write_message ( response ) : <EOL> logger . debug ( <EOL> '<STR_LIT>' , <EOL> self . request . remote_ip , response ) <EOL> except Exception as e : <EOL> error_msg = encoding . locale_decode ( e ) <EOL> logger . error ( '<STR_LIT>' , error_msg ) <EOL> if self . ws_connection : <EOL> self . close ( ) <EOL> def check_origin ( self , origin ) : <EOL> return True <EOL> def set_mopidy_headers ( request_handler ) : <EOL> request_handler . set_header ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> request_handler . set_header ( <EOL> '<STR_LIT>' , mopidy . __version__ . encode ( '<STR_LIT:utf-8>' ) ) <EOL> class JsonRpcHandler ( tornado . web . RequestHandler ) : <EOL> def initialize ( self , core ) : <EOL> self . jsonrpc = make_jsonrpc_wrapper ( core ) <EOL> def head ( self ) : <EOL> self . set_extra_headers ( ) <EOL> self . finish ( ) <EOL> def post ( self ) : <EOL> data = self . request . body <EOL> if not data : <EOL> return <EOL> logger . debug ( <EOL> '<STR_LIT>' , self . request . remote_ip , data ) <EOL> try : <EOL> self . set_extra_headers ( ) <EOL> response = self . jsonrpc . handle_json ( <EOL> tornado . escape . native_str ( data ) ) <EOL> if response and self . write ( response ) : <EOL> logger . debug ( <EOL> '<STR_LIT>' , <EOL> self . request . remote_ip , response ) <EOL> except Exception as e : <EOL> logger . error ( '<STR_LIT>' , e ) <EOL> self . write_error ( <NUM_LIT> ) <EOL> def set_extra_headers ( self ) : <EOL> set_mopidy_headers ( self ) <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT:application/json>' ) <EOL> self . set_header ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) <EOL> class ClientListHandler ( tornado . web . RequestHandler ) : <EOL> def initialize ( self , apps , statics ) : <EOL> self . apps = apps <EOL> self . statics = statics <EOL> def get_template_path ( self ) : <EOL> return os . path . dirname ( __file__ ) <EOL> def get ( self ) : <EOL> set_mopidy_headers ( self ) <EOL> names = set ( ) <EOL> for app in self . apps : <EOL> names . add ( app [ '<STR_LIT:name>' ] ) <EOL> for static in self . statics : <EOL> names . add ( static [ '<STR_LIT:name>' ] ) <EOL> names . discard ( '<STR_LIT>' ) <EOL> self . render ( '<STR_LIT>' , apps = sorted ( list ( names ) ) ) <EOL> class StaticFileHandler ( tornado . web . StaticFileHandler ) : <EOL> def set_extra_headers ( self , path ) : <EOL> set_mopidy_headers ( self ) <EOL> class AddSlashHandler ( tornado . web . RequestHandler ) : <EOL> @ tornado . web . addslash <EOL> def prepare ( self ) : <EOL> return super ( AddSlashHandler , self ) . prepare ( ) </s>
