Browse Source

Plenty of exception handler was completed.

Rafał Pitoń 11 years ago
parent
commit
fe379da3cd

+ 1 - 2
misago/conf/defaults.py

@@ -29,7 +29,6 @@ INSTALLED_APPS = (
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 import os
 import os
 MISAGO_BASE_DIR = os.path.dirname(os.path.dirname(__file__))
 MISAGO_BASE_DIR = os.path.dirname(os.path.dirname(__file__))
-print
 
 
 
 
 # Application definition
 # Application definition
@@ -52,7 +51,7 @@ MIDDLEWARE_CLASSES = (
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
-    'misago.views.exceptions.middleware.MisagoExceptionHandlerMiddleware',
+    'misago.views.middleware.MisagoExceptionHandlerMiddleware',
 )
 )
 
 
 # Register Misago directories
 # Register Misago directories

+ 6 - 0
misago/templates/misago/front/403.html

@@ -0,0 +1,6 @@
+<h1>Misago Error 403</h1>
+{% if message %}
+<p>{{ message }}</p>
+{% else %}
+<p>Request not allowed.</p>
+{% endif %}

+ 6 - 0
misago/templates/misago/front/404.html

@@ -0,0 +1,6 @@
+<h1>Misago Error 404</h1>
+{% if message %}
+<p>{{ message }}</p>
+{% else %}
+<p>Page not found.</p>
+{% endif %}

+ 0 - 1
misago/templates/misago/front/base.html

@@ -1 +0,0 @@
-Hello world, I'm placeholder template!

+ 1 - 0
misago/templates/misago/front/index.html

@@ -0,0 +1 @@
+Hello world, I'm placeholder index template!

+ 10 - 0
misago/urls.py

@@ -0,0 +1,10 @@
+from django.conf.urls import patterns, include, url
+
+
+urlpatterns = patterns('misago.views',
+    # forum_index link symbolises "root" of Misago links space
+    # any request with path that falls below this one is assumed to be directed
+    # at Misago and will be handled by misago.views.exceptionhandler if it
+    # results in Http404 or PermissionDenied exception
+    url(r'^$', 'views.forum_index', name='forum_index'),
+)

+ 40 - 0
misago/views/errorpages.py

@@ -0,0 +1,40 @@
+from django.shortcuts import render
+
+def _error_page(request, code, message=None):
+    response = render(request,
+                      'misago/front/%s.html' % code,
+                      {'message': message})
+    response.status_code = code
+    return response
+
+
+def permission_denied(request, message=None):
+    return _error_page(request, 403, message)
+
+
+def page_not_found(request, message=None):
+    return _error_page(request, 404, message)
+
+
+"""
+Decorators for custom error page handlers
+"""
+from misago.views.utils import is_request_to_misago
+
+
+def shared_403_exception_handler(f):
+    def page_decorator(request, *args, **kwargs):
+        if is_request_to_misago(request):
+            return permission_denied(request)
+        else:
+            return f(request, *args, **kwargs)
+    return page_decorator
+
+
+def shared_404_exception_handler(f):
+    def page_decorator(request, *args, **kwargs):
+        if is_request_to_misago(request):
+            return page_not_found(request)
+        else:
+            return f(request, *args, **kwargs)
+    return page_decorator

+ 53 - 0
misago/views/exceptionhandler.py

@@ -0,0 +1,53 @@
+from django.core.exceptions import PermissionDenied
+from django.http import Http404
+from misago.views import errorpages
+from misago.views.exceptions import OutdatedSlug
+
+
+HANDLED_EXCEPTIONS = (Http404, OutdatedSlug, PermissionDenied,)
+
+
+def is_misago_exception(exception):
+    return exception.__class__ in HANDLED_EXCEPTIONS
+
+
+def _get_exception_message(exception):
+    try:
+        return exception.args[0]
+    except IndexError:
+        return None
+
+
+def handle_http404_exception(request, exception):
+    return errorpages.page_not_found(request,
+                                     _get_exception_message(exception))
+
+
+def handle_outdated_slug_exception(request, exception):
+    raise NotImplementedError()
+
+
+def handle_permission_denied_exception(request, exception):
+    return errorpages.permission_denied(request,
+                                        _get_exception_message(exception))
+
+
+EXCEPTION_HANDLERS = (
+    (Http404, handle_http404_exception),
+    (OutdatedSlug, handle_outdated_slug_exception),
+    (PermissionDenied, handle_permission_denied_exception),
+)
+
+
+def get_exception_handler(exception):
+    for exception_type, handler in EXCEPTION_HANDLERS:
+        if isinstance(exception, exception_type):
+            return handler
+    else:
+        raise ValueError(
+            "%s is not Misago exception" % exception.__class__.__name__)
+
+
+def handle_misago_exception(request, exception):
+    handler = get_exception_handler(exception)
+    return handler(request, exception)

+ 7 - 0
misago/views/exceptions.py

@@ -0,0 +1,7 @@
+"""
+Extra exceptions that can be raised by Misago Views
+"""
+
+class OutdatedSlug(Exception):
+    """The url that was used to reach view contained outdated slug"""
+    pass

+ 0 - 27
misago/views/exceptions/__init__.py

@@ -1,27 +0,0 @@
-from django.core.exceptions import PermissionDenied as DjPermissionDenied
-from django.http import Http404 as DjHttp404
-
-
-__all__ = ["Http404", "OutdatedUrl", "PermissionDenied"]
-
-
-class Http404(DjHttp404):
-    """The requested page could not be found"""
-    pass
-
-
-class OutdatedUrl(Exception):
-    """The url that was used to reach view contained outdated slug"""
-    pass
-
-
-class PermissionDenied(DjPermissionDenied):
-    """The user did not have permission to do that"""
-    pass
-
-
-MISAGO_EXCEPTIONS = (
-    Http404,
-    OutdatedUrl,
-    PermissionDenied,
-)

+ 0 - 38
misago/views/exceptions/handler.py

@@ -1,38 +0,0 @@
-from misago.views import exceptions
-
-
-def is_misago_exception(exception):
-    return exception.__class__ in exceptions.MISAGO_EXCEPTIONS
-
-
-def handle_http404_exception(request, exception):
-    raise NotImplementedError()
-
-
-def handle_outdated_url_exception(request, exception):
-    raise NotImplementedError()
-
-
-def handle_permission_denied_exception(request, exception):
-    raise NotImplementedError()
-
-
-EXCEPTION_HANDLERS = (
-    (exceptions.Http404, handle_http404_exception),
-    (exceptions.OutdatedUrl, handle_outdated_url_exception),
-    (exceptions.PermissionDenied, handle_permission_denied_exception),
-)
-
-
-def get_exception_handler(exception):
-    for exception_type, handler in EXCEPTION_HANDLERS:
-        if isinstance(exception, exception_type):
-            return handler
-    else:
-        raise ValueError(
-            "%s is not Misago exception" % exception.__class__.__name__)
-
-
-def handle_misago_exception(request, exception):
-    handler = get_exception_handler(exception)
-    return handler(request, exception)

+ 0 - 9
misago/views/exceptions/middleware.py

@@ -1,9 +0,0 @@
-from misago.views.exceptions import handler
-
-
-class MisagoExceptionHandlerMiddleware(object):
-    def process_exception(self, request, exception):
-        if handler.is_misago_exception(exception):
-            return handler.handle_misago_exception(request, exception)
-        else:
-            return None

+ 14 - 0
misago/views/middleware.py

@@ -0,0 +1,14 @@
+from misago.views import exceptionhandler
+from misago.views.utils import is_request_to_misago
+
+
+class MisagoExceptionHandlerMiddleware(object):
+    def process_exception(self, request, exception):
+        request_is_to_misago = is_request_to_misago(request)
+        misago_can_handle_exception = exceptionhandler.is_misago_exception(
+            exception)
+
+        if request_is_to_misago and misago_can_handle_exception:
+            return exceptionhandler.handle_misago_exception(request, exception)
+        else:
+            return None

+ 7 - 0
misago/views/tests/test_utils.py

@@ -0,0 +1,7 @@
+from django.test import TestCase
+from misago.views.utils import is_request_to_misago
+
+class MisagoExceptionHandlerTests(TestCase):
+    def test_is_request_to_misago(self):
+        """is_request_to_misago correctly detects requests directed at Misago"""
+        self.fail("Not yet implemented")

+ 20 - 0
misago/views/utils.py

@@ -0,0 +1,20 @@
+from django.core.urlresolvers import reverse
+
+
+def _compare_path_under_to_forum_index(request):
+    forum_index = reverse('forum_index')
+    path_info = request.path_info
+
+    if len(forum_index) > len(path_info):
+        return False
+    return path_info[:len(forum_index)] == forum_index
+
+
+def is_request_to_misago(request):
+    """Is request directed at Misago instead of... say, CMS app?"""
+    try:
+        return request._request_to_misago
+    except AttributeError:
+        request._request_to_misago = _compare_path_under_to_forum_index(request)
+        return request._request_to_misago
+

+ 6 - 0
misago/views/views.py

@@ -0,0 +1,6 @@
+from django.shortcuts import render
+from django.http import Http404
+
+
+def forum_index(request):
+    return render(request, 'misago/front/index.html')