From 768c98d359d75c059f9065e548bcdcc428f08a7a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 11 May 2016 22:55:24 -0700 Subject: [PATCH] Fix import issues --- homeassistant/components/api.py | 6 +- homeassistant/components/frontend/__init__.py | 25 +++--- homeassistant/components/wsgi.py | 77 +++++++++++-------- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/homeassistant/components/api.py b/homeassistant/components/api.py index 7753fbe58fc..8305f78fa1c 100644 --- a/homeassistant/components/api.py +++ b/homeassistant/components/api.py @@ -9,8 +9,6 @@ import logging import re import threading -from werkzeug.exceptions import NotFound, BadRequest - import homeassistant.core as ha import homeassistant.remote as rem from homeassistant.bootstrap import ERROR_LOG_FILENAME @@ -266,13 +264,13 @@ class APIEntityStateView(HomeAssistantView): if state: return state else: - raise NotFound("State does not exist.") + raise self.NotFound("State does not exist.") def post(self, request, entity_id): try: new_state = request.values['state'] except KeyError: - raise BadRequest("state not specified") + raise self.BadRequest("state not specified") attributes = request.values.get('attributes') diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index f591fdd14be..ca8e65e27a5 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -3,9 +3,6 @@ import re import os import logging -from jinja2 import FileSystemLoader, Environment -from werkzeug.wrappers import Response - from . import version, mdi_version import homeassistant.util as util from homeassistant.const import URL_ROOT, HTTP_OK @@ -17,12 +14,6 @@ DEPENDENCIES = ['api'] INDEX_PATH = os.path.join(os.path.dirname(__file__), 'index.html.template') -TEMPLATES = Environment( - loader=FileSystemLoader( - os.path.join(os.path.dirname(__file__), 'templates/') - ) -) - _LOGGER = logging.getLogger(__name__) FRONTEND_URLS = [ @@ -99,19 +90,31 @@ class IndexView(HomeAssistantView): extra_urls = ['/logbook', '/history', '/map', '/devService', '/devState', '/devEvent', '/devInfo', '/devTemplate', '/states/'] + def __init__(self, hass): + super().__init__(hass) + + from jinja2 import FileSystemLoader, Environment + + self.TEMPLATES = Environment( + loader=FileSystemLoader( + os.path.join(os.path.dirname(__file__), 'templates/') + ) + ) + def get(self, request): + """Serve the index view.""" app_url = "frontend-{}.html".format(version.VERSION) # auto login if no password was set, else check api_password param auth = ('no_password_set' if request.api_password is None else request.values.get('api_password', '')) - template = TEMPLATES.get_template('index.html') + template = self.TEMPLATES.get_template('index.html') resp = template.render(app_url=app_url, auth=auth, icons=mdi_version.VERSION) - return Response(resp, mimetype="text/html") + return self.Response(resp, mimetype="text/html") def _handle_get_api_bootstrap(handler, path_match, data): diff --git a/homeassistant/components/wsgi.py b/homeassistant/components/wsgi.py index f2b1e319887..912c4d087a0 100644 --- a/homeassistant/components/wsgi.py +++ b/homeassistant/components/wsgi.py @@ -7,9 +7,6 @@ import logging import threading import re -from eventlet import wsgi -import eventlet - import homeassistant.core as ha import homeassistant.remote as rem from homeassistant import util @@ -17,29 +14,6 @@ from homeassistant.const import ( SERVER_PORT, HTTP_OK, HTTP_NOT_FOUND, HTTP_BAD_REQUEST ) -from static import Cling - -from werkzeug.wsgi import DispatcherMiddleware -from werkzeug.wrappers import Response, BaseRequest, AcceptMixin -from werkzeug.routing import Map, Rule -from werkzeug.exceptions import ( - MethodNotAllowed, NotFound, BadRequest, Unauthorized -) - - -class Request(BaseRequest, AcceptMixin): - pass - - -class StaticFileServer(object): - def __call__(self, environ, start_response): - app = DispatcherMiddleware(self.base_app, self.extra_apps) - # Strip out any cachebusting MD% fingerprints - fingerprinted = _FINGERPRINT.match(environ['PATH_INFO']) - if fingerprinted: - environ['PATH_INFO'] = "{}.{}".format(*fingerprinted.groups()) - return app(environ, start_response) - DOMAIN = "wsgi" REQUIREMENTS = ("eventlet==0.18.4", "static3==0.6.1", "Werkzeug==0.11.5",) @@ -82,9 +56,27 @@ def setup(hass, config): return True +class StaticFileServer(object): + def __call__(self, environ, start_response): + from werkzeug.wsgi import DispatcherMiddleware + app = DispatcherMiddleware(self.base_app, self.extra_apps) + # Strip out any cachebusting MD% fingerprints + fingerprinted = _FINGERPRINT.match(environ['PATH_INFO']) + if fingerprinted: + environ['PATH_INFO'] = "{}.{}".format(*fingerprinted.groups()) + return app(environ, start_response) + + class HomeAssistantWSGI(object): def __init__(self, hass, development, api_password, ssl_certificate, ssl_key, server_host, server_port): + from werkzeug.wrappers import BaseRequest, AcceptMixin + from werkzeug.routing import Map + + class Request(BaseRequest, AcceptMixin): + pass + + self.Request = Request self.url_map = Map() self.views = {} self.hass = hass @@ -100,6 +92,8 @@ class HomeAssistantWSGI(object): The view argument must inherit from the HomeAssistantView class, and it must have (globally unique) 'url' and 'name' attributes. """ + from werkzeug.routing import Rule + if view.name in self.views: _LOGGER.warning("View '{}' is being overwritten".format(view.name)) self.views[view.name] = view(self.hass) @@ -111,10 +105,17 @@ class HomeAssistantWSGI(object): self.url_map.add(rule) def register_static_path(self, url_root, path): + """Register a folder to serve as a static path.""" + from static import Cling + # TODO Warn if we're overwriting an existing path self.extra_apps[url_root] = Cling(path) def start(self): + """Start the wsgi server.""" + from eventlet import wsgi + import eventlet + sock = eventlet.listen(('', 8090)) if self.ssl_certificate: eventlet.wrap_ssl(sock, certfile=self.ssl_certificate, @@ -122,6 +123,10 @@ class HomeAssistantWSGI(object): wsgi.server(sock, self) def dispatch_request(self, request): + """Handle incoming request.""" + from werkzeug.exceptions import ( + MethodNotAllowed, NotFound, BadRequest, Unauthorized + ) adapter = self.url_map.bind_to_environ(request.environ) try: endpoint, values = adapter.match() @@ -139,13 +144,15 @@ class HomeAssistantWSGI(object): # itself def base_app(self, environ, start_response): - request = Request(environ) + request = self.Request(environ) request.api_password = self.api_password request.development = self.development response = self.dispatch_request(request) return response(environ, start_response) def __call__(self, environ, start_response): + from werkzeug.wsgi import DispatcherMiddleware + app = DispatcherMiddleware(self.base_app, self.extra_apps) # Strip out any cachebusting MD5 fingerprints fingerprinted = _FINGERPRINT.match(environ.get('PATH_INFO', '')) @@ -154,6 +161,7 @@ class HomeAssistantWSGI(object): return app(environ, start_response) def _handle_error(self, request, message, status): + from werkzeug.wrappers import Response if request.accept_mimetypes.accept_json: message = json.dumps({ "result": "error", @@ -170,9 +178,18 @@ class HomeAssistantView(object): requires_auth = True # Views inheriting from this class can override this def __init__(self, hass): + from werkzeug.wrappers import Response + from werkzeug.exceptions import NotFound, BadRequest + self.hass = hass + self.Response = Response + self.NotFound = NotFound + self.BadRequest = BadRequest def handle_request(self, request, **values): + """Handle request to url.""" + from werkzeug.exceptions import MethodNotAllowed + try: handler = getattr(self, request.method.lower()) except AttributeError: @@ -180,7 +197,7 @@ class HomeAssistantView(object): # TODO This would be a good place to check the auth if # self.requires_auth is true, and raise Unauthorized on a failure result = handler(request, **values) - if isinstance(result, Response): + if isinstance(result, self.Response): # The method handler returned a ready-made Response, how nice of it return result elif (isinstance(result, dict) or @@ -197,5 +214,5 @@ class HomeAssistantView(object): sort_keys=True, cls=rem.JSONEncoder ).encode('UTF-8') - return Response(msg, mimetype="application/json", - status_code=status_code) + return self.Response(msg, mimetype="application/json", + status_code=status_code)