115 lines
3.4 KiB
Python
115 lines
3.4 KiB
Python
from __future__ import unicode_literals
|
|
|
|
import logging
|
|
import json
|
|
import os
|
|
|
|
import pykka
|
|
|
|
from mopidy import exceptions, models
|
|
from mopidy.core import CoreListener
|
|
|
|
try:
|
|
import cherrypy
|
|
from ws4py.messaging import TextMessage
|
|
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
|
|
except ImportError as import_error:
|
|
raise exceptions.OptionalDependencyError(import_error)
|
|
|
|
from . import ws
|
|
|
|
|
|
logger = logging.getLogger('mopidy.frontends.http')
|
|
|
|
|
|
class HttpFrontend(pykka.ThreadingActor, CoreListener):
|
|
def __init__(self, config, core):
|
|
super(HttpFrontend, self).__init__()
|
|
self.config = config
|
|
self.core = core
|
|
self._setup_server()
|
|
self._setup_websocket_plugin()
|
|
app = self._create_app()
|
|
self._setup_logging(app)
|
|
|
|
def _setup_server(self):
|
|
cherrypy.config.update({
|
|
'engine.autoreload_on': False,
|
|
'server.socket_host': (
|
|
self.config['http']['hostname'].encode('utf-8')),
|
|
'server.socket_port': self.config['http']['port'],
|
|
})
|
|
|
|
def _setup_websocket_plugin(self):
|
|
WebSocketPlugin(cherrypy.engine).subscribe()
|
|
cherrypy.tools.websocket = WebSocketTool()
|
|
|
|
def _create_app(self):
|
|
root = RootResource()
|
|
root.mopidy = MopidyResource()
|
|
root.mopidy.ws = ws.WebSocketResource(self.core)
|
|
|
|
if self.config['http']['static_dir']:
|
|
static_dir = self.config['http']['static_dir']
|
|
else:
|
|
static_dir = os.path.join(os.path.dirname(__file__), 'data')
|
|
logger.debug('HTTP server will serve "%s" at /', static_dir)
|
|
|
|
mopidy_dir = os.path.join(os.path.dirname(__file__), 'data')
|
|
favicon = os.path.join(mopidy_dir, 'favicon.png')
|
|
|
|
config = {
|
|
b'/': {
|
|
'tools.staticdir.on': True,
|
|
'tools.staticdir.index': 'index.html',
|
|
'tools.staticdir.dir': static_dir,
|
|
},
|
|
b'/favicon.ico': {
|
|
'tools.staticfile.on': True,
|
|
'tools.staticfile.filename': favicon,
|
|
},
|
|
b'/mopidy': {
|
|
'tools.staticdir.on': True,
|
|
'tools.staticdir.index': 'mopidy.html',
|
|
'tools.staticdir.dir': mopidy_dir,
|
|
},
|
|
b'/mopidy/ws': {
|
|
'tools.websocket.on': True,
|
|
'tools.websocket.handler_cls': ws.WebSocketHandler,
|
|
},
|
|
}
|
|
|
|
return cherrypy.tree.mount(root, '/', config)
|
|
|
|
def _setup_logging(self, app):
|
|
cherrypy.log.access_log.setLevel(logging.NOTSET)
|
|
cherrypy.log.error_log.setLevel(logging.NOTSET)
|
|
cherrypy.log.screen = False
|
|
|
|
app.log.access_log.setLevel(logging.NOTSET)
|
|
app.log.error_log.setLevel(logging.NOTSET)
|
|
|
|
def on_start(self):
|
|
logger.debug('Starting HTTP server')
|
|
cherrypy.engine.start()
|
|
logger.info('HTTP server running at %s', cherrypy.server.base())
|
|
|
|
def on_stop(self):
|
|
logger.debug('Stopping HTTP server')
|
|
cherrypy.engine.exit()
|
|
logger.info('Stopped HTTP server')
|
|
|
|
def on_event(self, name, **data):
|
|
event = data
|
|
event['event'] = name
|
|
message = json.dumps(event, cls=models.ModelJSONEncoder)
|
|
cherrypy.engine.publish('websocket-broadcast', TextMessage(message))
|
|
|
|
|
|
class RootResource(object):
|
|
pass
|
|
|
|
|
|
class MopidyResource(object):
|
|
pass
|