104 lines
3.0 KiB
Python
104 lines
3.0 KiB
Python
from __future__ import unicode_literals
|
|
|
|
import logging
|
|
import os
|
|
|
|
import tornado.web
|
|
|
|
import mopidy
|
|
from mopidy import config as config_lib, exceptions, ext
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class Extension(ext.Extension):
|
|
dist_name = 'Mopidy-HTTP'
|
|
ext_name = 'http'
|
|
version = mopidy.__version__
|
|
|
|
def get_default_config(self):
|
|
conf_file = os.path.join(os.path.dirname(__file__), 'ext.conf')
|
|
return config_lib.read(conf_file)
|
|
|
|
def get_config_schema(self):
|
|
schema = super(Extension, self).get_config_schema()
|
|
schema['hostname'] = config_lib.Hostname()
|
|
schema['port'] = config_lib.Port()
|
|
schema['static_dir'] = config_lib.Path(optional=True)
|
|
schema['zeroconf'] = config_lib.String(optional=True)
|
|
return schema
|
|
|
|
def validate_environment(self):
|
|
try:
|
|
import tornado.web # noqa
|
|
except ImportError as e:
|
|
raise exceptions.ExtensionError('tornado library not found', e)
|
|
|
|
def setup(self, registry):
|
|
from .actor import HttpFrontend
|
|
|
|
HttpFrontend.routers = registry['http:routers']
|
|
registry.add('frontend', HttpFrontend)
|
|
|
|
|
|
class StaticFileHandler(tornado.web.StaticFileHandler):
|
|
def set_extra_headers(self, path):
|
|
self.set_header('Cache-Control', 'no-cache')
|
|
self.set_header(
|
|
'X-Mopidy-Version', mopidy.__version__.encode('utf-8'))
|
|
|
|
|
|
class Router(object):
|
|
"""
|
|
HTTP router interface.
|
|
|
|
Extensions that wish to add custom routes to HTTP server needs to subclass
|
|
this class and have :meth:`~mopidy.ext.Extension.setup` register the class
|
|
in the extension registry.
|
|
|
|
:param config: dict structure of the entire Mopidy configuration
|
|
"""
|
|
|
|
#: Name of the HTTP router implementation, must be overridden.
|
|
name = None
|
|
|
|
#: Path to location of static files to be served.
|
|
static_file_path = None
|
|
|
|
def __init__(self, config):
|
|
self.config = config
|
|
self.hostname = config['http']['hostname']
|
|
self.port = config['http']['port']
|
|
if not self.name:
|
|
raise ValueError('Undefined name in %s' % self)
|
|
|
|
def linkify(self):
|
|
"""
|
|
Absolute URL to the root of this router.
|
|
|
|
:return: URL this router is mounted at
|
|
"""
|
|
return 'http://%s:%s/%s/' % (self.hostname, self.port, self.name)
|
|
|
|
def setup_routes(self):
|
|
"""
|
|
Configure routes for this interface.
|
|
|
|
Implementation must return list of routes, compatible with
|
|
:class:`tornado.web.Application`.
|
|
|
|
:return: list of Tornado routes
|
|
"""
|
|
|
|
if self.static_file_path is None:
|
|
raise ValueError('Undefined static file path in %s' % self)
|
|
logger.info(
|
|
'Serving HTTP extension %s at %s', type(self), self.linkify())
|
|
return [
|
|
(r'/%s/(.*)' % self.name, StaticFileHandler, {
|
|
'path': self.static_file_path,
|
|
'default_filename': 'index.html'
|
|
}),
|
|
]
|