From 03ae172a60a87625e5281eb9766aa5bf3e37d0f4 Mon Sep 17 00:00:00 2001 From: Aaron Williamson Date: Sat, 1 Oct 2011 18:05:17 -0400 Subject: Finished splitting util.py into separate files. --- mediagoblin/tools/response.py | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 mediagoblin/tools/response.py (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py new file mode 100644 index 00000000..1477b9bc --- /dev/null +++ b/mediagoblin/tools/response.py @@ -0,0 +1,44 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from webob import Response, exc +from mediagoblin.tools.template import render_template + +def render_to_response(request, template, context, status=200): + """Much like Django's shortcut.render()""" + return Response( + render_template(request, template, context), + status=status) + +def render_404(request): + """ + Render a 404. + """ + return render_to_response( + request, 'mediagoblin/404.html', {}, status=400) + +def redirect(request, *args, **kwargs): + """Returns a HTTPFound(), takes a request and then urlgen params""" + + querystring = None + if kwargs.get('querystring'): + querystring = kwargs.get('querystring') + del kwargs['querystring'] + + return exc.HTTPFound( + location=''.join([ + request.urlgen(*args, **kwargs), + querystring if querystring else ''])) -- cgit v1.2.3 From c7e1fee1b8eab3c01266c9a349812db598ca8f07 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Thu, 1 Dec 2011 16:58:56 -0600 Subject: Should be 404 for 404s, not 400 :) --- mediagoblin/tools/response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index b01d31a2..c905097c 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -30,7 +30,7 @@ def render_404(request): Render a 404. """ return render_to_response( - request, 'mediagoblin/404.html', {}, status=400) + request, 'mediagoblin/404.html', {}, status=404) def redirect(request, *args, **kwargs): -- cgit v1.2.3 From cf29e8a824e0ef4612f1144f079c80c1d20b89e5 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Thu, 2 Feb 2012 09:44:13 -0600 Subject: It's 2012 all up in here --- mediagoblin/tools/response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index c905097c..a54c32fb 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -1,5 +1,5 @@ # GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by -- cgit v1.2.3 From 6b5f1ca79b42b977ea5f436ac7ab329fd2da1b6b Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Thu, 29 Nov 2012 08:57:12 +0100 Subject: Implement generic error pages Rather than having a 404.html, a 403.html, a 500.html,... we have a generic error.html template that we pass in an error code, a title and a (html'ish) error message. Implement the common render_404 and render_403 shortcuts. More exotic cases can be achieved by the generic render_error function. Signed-off-by: Sebastian Spaeth --- mediagoblin/tools/response.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index a54c32fb..a77f68b9 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -16,6 +16,7 @@ from webob import Response, exc from mediagoblin.tools.template import render_template +from mediagoblin.tools.translate import fake_ugettext_passthrough as _ def render_to_response(request, template, context, status=200): @@ -25,14 +26,34 @@ def render_to_response(request, template, context, status=200): status=status) -def render_404(request): - """ - Render a 404. +def render_error(request, status=500, title=_('Oops!'), + err_msg=_('An error occured')): + """Render any error page with a given error code, title and text body + + Title and description are passed through as-is to allow html. Make + sure no user input is contained therein for security reasons. The + description will be wrapped in a

tag. """ - return render_to_response( - request, 'mediagoblin/404.html', {}, status=404) + return Response(render_template(request, 'mediagoblin/error.html', + {'err_code': status, 'title': title, 'err_msg': err_msg}), + status=status) +def render_403(request): + """Render a standard 403 page""" + title = _('Operation not allowed') + err_msg = _("Sorry Dave, I can't let you do that!

You have tried " + " to perform a function that you are not allowed to. Have you " + "been trying to delete all user accounts again?") + return render_error(request, 403, title, err_msg) + +def render_404(request): + """Render a standard 404 page.""" + err_msg = _("

There doesn't seem to be a page at this address. Sorry!

" + "

If you're sure the address is correct, maybe the page " + "you're looking for has been moved or deleted.") + return render_error(request, 404, err_msg=err_msg) + def redirect(request, *args, **kwargs): """Returns a HTTPFound(), takes a request and then urlgen params""" -- cgit v1.2.3 From 26c71029b44d4384020b2f928fb18f59b1d1356b Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Thu, 29 Nov 2012 14:51:24 +0100 Subject: Fix error page text Thanks to Elrond for noticing. We wrap error messages in

tags, so there is no need to start the error message with

. DOH Signed-off-by: Sebastian Spaeth --- mediagoblin/tools/response.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index a77f68b9..6d14b8b7 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -32,7 +32,7 @@ def render_error(request, status=500, title=_('Oops!'), Title and description are passed through as-is to allow html. Make sure no user input is contained therein for security reasons. The - description will be wrapped in a

tag. + description will be wrapped in

tags. """ return Response(render_template(request, 'mediagoblin/error.html', {'err_code': status, 'title': title, 'err_msg': err_msg}), @@ -49,7 +49,7 @@ def render_403(request): def render_404(request): """Render a standard 404 page.""" - err_msg = _("

There doesn't seem to be a page at this address. Sorry!

" + err_msg = _("There doesn't seem to be a page at this address. Sorry!

" "

If you're sure the address is correct, maybe the page " "you're looking for has been moved or deleted.") return render_error(request, 404, err_msg=err_msg) -- cgit v1.2.3 From 18a52dacca63a58feabdc929711590a9e889b2ee Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Fri, 14 Dec 2012 12:55:21 +0100 Subject: Use the correct translation mechanism We accidentally used the fake translation mechanism here which will not actually translate anything. Signed-off-by: Sebastian Spaeth --- mediagoblin/tools/response.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index 6d14b8b7..8edd976d 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -16,7 +16,8 @@ from webob import Response, exc from mediagoblin.tools.template import render_template -from mediagoblin.tools.translate import fake_ugettext_passthrough as _ +from mediagoblin.tools.translate import (lazy_pass_to_ugettext as L_, + pass_to_ugettext as _) def render_to_response(request, template, context, status=200): @@ -26,8 +27,8 @@ def render_to_response(request, template, context, status=200): status=status) -def render_error(request, status=500, title=_('Oops!'), - err_msg=_('An error occured')): +def render_error(request, status=500, title=L_('Oops!'), + err_msg=L_('An error occured')): """Render any error page with a given error code, title and text body Title and description are passed through as-is to allow html. Make -- cgit v1.2.3 From 00da119ec30742ec37df37022d7a15bfd4c3cf07 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 14 Dec 2012 10:49:05 -0600 Subject: Switching both gettext calls to _() so babel can find/extract them. Babel looks for _() and gettext() so this is necessary. --- mediagoblin/tools/response.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index 8edd976d..81939a77 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -16,8 +16,8 @@ from webob import Response, exc from mediagoblin.tools.template import render_template -from mediagoblin.tools.translate import (lazy_pass_to_ugettext as L_, - pass_to_ugettext as _) +from mediagoblin.tools.translate import (lazy_pass_to_ugettext as _, + pass_to_ugettext) def render_to_response(request, template, context, status=200): @@ -27,8 +27,8 @@ def render_to_response(request, template, context, status=200): status=status) -def render_error(request, status=500, title=L_('Oops!'), - err_msg=L_('An error occured')): +def render_error(request, status=500, title=_('Oops!'), + err_msg=_('An error occured')): """Render any error page with a given error code, title and text body Title and description are passed through as-is to allow html. Make @@ -42,6 +42,7 @@ def render_error(request, status=500, title=L_('Oops!'), def render_403(request): """Render a standard 403 page""" + _ = pass_to_ugettext title = _('Operation not allowed') err_msg = _("Sorry Dave, I can't let you do that!

You have tried " " to perform a function that you are not allowed to. Have you " @@ -50,6 +51,7 @@ def render_403(request): def render_404(request): """Render a standard 404 page.""" + _ = pass_to_ugettext err_msg = _("There doesn't seem to be a page at this address. Sorry!

" "

If you're sure the address is correct, maybe the page " "you're looking for has been moved or deleted.") -- cgit v1.2.3 From 4487d51c819dcf34d335dd9efc57d03cf7c7ed1e Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Fri, 16 Nov 2012 09:12:34 +0100 Subject: Extend redirect helper to take optional location keyword In order to move away from webob with its redirect(location=...) we need to provide a redirect function that allows to directly specify the URL rather than the urlgen parameters that we now use. Extend our MG.tools:redirect helper so we can pass in the direct URL via the optional "location" keyword. This commit does not switch over any redirect consumers yet. Signed-off-by: Sebastian Spaeth --- mediagoblin/tools/response.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index 81939a77..ed23f0f7 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -14,7 +14,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from webob import Response, exc +import werkzeug.utils +from webob import Response from mediagoblin.tools.template import render_template from mediagoblin.tools.translate import (lazy_pass_to_ugettext as _, pass_to_ugettext) @@ -57,15 +58,21 @@ def render_404(request): "you're looking for has been moved or deleted.") return render_error(request, 404, err_msg=err_msg) + def redirect(request, *args, **kwargs): - """Returns a HTTPFound(), takes a request and then urlgen params""" + """Redirects to an URL, using urlgen params or location string + + :param querystring: querystring to be appended to the URL + :param location: If the location keyword is given, redirect to the URL + """ + querystring = kwargs.pop('querystring', None) - querystring = None - if kwargs.get('querystring'): - querystring = kwargs.get('querystring') - del kwargs['querystring'] + # Redirect to URL if given by "location=..." + if 'location' in kwargs: + location = kwargs.pop('location') + else: + location = request.urlgen(*args, **kwargs) - return exc.HTTPFound( - location=''.join([ - request.urlgen(*args, **kwargs), - querystring if querystring else ''])) + if querystring: + location += querystring + return werkzeug.utils.redirect(location) -- cgit v1.2.3 From b745bb50d8a4c92b5adbbd6918262ff8c9cc9609 Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Fri, 16 Nov 2012 10:25:50 +0100 Subject: Remove webob from render_to_response We were still using webob's Response objects for template rendering. Transition to werkzeug's Response object. One caveat was that it seemed to have used the default mimetype "text/plain" for all pages, so we override the default Response class, setting the default mime type to "text/html". Signed-off-by: Sebastian Spaeth --- mediagoblin/tools/response.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index ed23f0f7..b02dd6b5 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -15,11 +15,15 @@ # along with this program. If not, see . import werkzeug.utils -from webob import Response +from werkzeug.wrappers import Response as wz_Response from mediagoblin.tools.template import render_template from mediagoblin.tools.translate import (lazy_pass_to_ugettext as _, pass_to_ugettext) +class Response(wz_Response): + """Set default response mimetype to HTML, otherwise we get text/plain""" + default_mimetype = u'text/html' + def render_to_response(request, template, context, status=200): """Much like Django's shortcut.render()""" -- cgit v1.2.3 From 785b287fcb42ac9130b222006097e3f68cec3543 Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Sun, 23 Dec 2012 11:57:45 +0100 Subject: Provide tools.response.render_http_exception and use that After the webob->werkzeug transition, controller functions can raise werkzeug.HttpExceptions. We need to catch these in app.py when calling the controller and handle them, rendering the corresponding error Response() object. For consistency, we also want to allow meddleware functions to raise HttpExceptions (e.g. the csrf meddleware needs to complain about lack of cookies), so wrap the request and response parts of the meddleware too. Finally, the urlmap.match() can also raise HttpExceptions, so we give it the same treatment (render_http_exception). I am not sure, if we do not need to handle the Redirect exception there in any different way though... The new function render_http_exception makes use of the render_error infrastructure to return a nicely templated error page. It also checks if the stock error messages was used in cases where we have localizations (403, 404) and use those. It is now possible to do things like "raise Forbidden(_('You suckr'))" or raise NotFound(_('where is my left show again')) if you want to return customized error messages to the user. Signed-off-by: Sebastian Spaeth --- mediagoblin/tools/response.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index b02dd6b5..80df1f5a 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -63,6 +63,25 @@ def render_404(request): return render_error(request, 404, err_msg=err_msg) +def render_http_exception(request, exc, description): + """Return Response() given a werkzeug.HTTPException + + :param exc: werkzeug.HTTPException or subclass thereof + :description: message describing the error.""" + # If we were passed the HTTPException stock description on + # exceptions where we have localized ones, use those: + stock_desc = (description == exc.__class__.description) + + if stock_desc and exc.code == 403: + return render_403(request) + elif stock_desc and exc.code == 404: + return render_404(request) + + return render_error(request, title=exc.args[0], + err_msg=description, + status=exc.code) + + def redirect(request, *args, **kwargs): """Redirects to an URL, using urlgen params or location string -- cgit v1.2.3 From 2e6ee596ad9dbc794979069f2f14b856db02343b Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 28 Apr 2013 00:14:50 +0200 Subject: Create redir_obj and use it around. This is a shortcut function to redirect to the main page for an object. Objects currently supported: media entries and collections. And go around and replace various places to use this. --- mediagoblin/tools/response.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'mediagoblin/tools/response.py') diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index 80df1f5a..aaf31d0b 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -99,3 +99,10 @@ def redirect(request, *args, **kwargs): if querystring: location += querystring return werkzeug.utils.redirect(location) + + +def redirect_obj(request, obj): + """Redirect to the page for the given object. + + Requires obj to have a .url_for_self method.""" + return redirect(request, location=obj.url_for_self(request.urlgen)) -- cgit v1.2.3