# HG changeset patch # User Todd Larsen # Date 1223071172 0 # Node ID 0c008a43443b2565329c60e49ebc5af5016ce544 # Parent 3b47bfd4f1b30d818cc65e9e9d9699033b7182d4 Replace soc/views/helpers/request_helpers with soc/views/helpers/request.py and replace uses of request_helpers. with helpers.request. instead. Patch by: Todd Larsen Review by: to-be-reviewed diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/helpers/request.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/soc/views/helpers/request.py Fri Oct 03 21:59:32 2008 +0000 @@ -0,0 +1,179 @@ +#!/usr/bin/python2.5 +# +# Copyright 2008 the Melange authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Helpers for manipulating HTTP requests. +""" + +__authors__ = [ + '"Todd Larsen" ', + ] + +import urlparse + + +def getSingleIndexedParamValue(request, param_name, values=()): + """Returns a value indexed by a query parameter in the HTTP request. + + Args: + request: the Django HTTP request object + param_name: name of the query parameter in the HTTP request + values: list (or tuple) of ordered values; one of which is + retrieved by the index value of the param_name argument in + the HTTP request + + Returns: + None if the query parameter was not present, was not an integer, or + was an integer that is not a valid [0..len(values)-1] index into + the values list. + Otherwise, returns values[int(param_name value)] + """ + value_idx = request.GET.get(param_name) + + if isinstance(value_idx, (tuple, list)): + # keep only the first argument if multiple are present + value_idx = value_idx[0] + + try: + # GET parameter 'param_name' should be an integer value index + value_idx = int(value_idx) + except: + # ignore bogus or missing parameter values, so return None (no message) + return None + + if value_idx < 0: + # value index out of range, so return None (no value) + return None + + if value_idx >= len(values): + # value index out of range, so return None (no value) + return None + + # return value associated with valid value index + return values[value_idx] + + +def getSingleIndexedParamValueIfMissing(value, request, param_name, + values=()): + """Returns missing value indexed by a query parameter in the HTTP request. + + Args: + value: an existing value, or a "False" value such as None + request, param_name, values: see getSingleIndexParamValue() + + Returns: + value, if value is "non-False" + Otherwise, returns getSingleIndexedParamValue() result. + """ + if value: + # value already present, so return it + return value + + return getSingleIndexedParamValue(request, param_name, values=values) + + +# TODO(tlarsen): write getMultipleIndexParamValues() that returns a +# list of values if present, omitting those values that are +# out of range + + +def isReferrerSelf(request, + expected_prefix=None, suffix=None): + """Returns True if HTTP referrer path starts with the HTTP request path. + + Args: + request: the Django HTTP request object; request.path is used if + expected_path is not supplied (the most common usage) + expected_prefix: optional HTTP path to use instead of the one in + request.path; default is None (use request.path) + suffix: suffix to remove from the HTTP request path before comparing + it to the HTTP referrer path in the HTTP request object headers + (this is often an link name, for example, that may be changing from + a POST referrer to a GET redirect target) + + Returns: + True if HTTP referrer path begins with the HTTP request path (either + request.path or expected_prefix instead if it was supplied), after + any suffix was removed from that request path + False otherwise + + """ + http_from = request.META.get('HTTP_REFERER') + + if not http_from: + # no HTTP referrer, so cannot possibly start with expected prefix + return False + + from_path = urlparse.urlparse(http_from).path + + if not expected_prefix: + # use HTTP request path, since expected_prefix was not supplied + expected_prefix = request.path + + if suffix: + # remove suffix (such as a link name) before comparison + chars_to_remove = len(suffix) + + if not suffix.startswith('/'): + chars_to_remove = chars_to_remove + 1 + + expected_prefix = expected_prefix[:-chars_to_remove] + + if not from_path.startswith(expected_prefix): + # expected prefix did not match first part of HTTP referrer path + return False + + # HTTP referrer started with (possibly truncated) expected prefix + return True + + +def replaceSuffix(path, old_suffix, new_suffix=None, params=None): + """Replace the last part of a URL path with something else. + + Also appends an optional list of query parameters. Used for + replacing, for example, one link name at the end of a relative + URL path with another. + + Args: + path: HTTP request relative URL path (with no query arguments) + old_suffix: expected suffix at the end of request.path component; + if any False value (such as None), the empty string '' is used + new_suffix: if non-False, appended to request.path along with a + '/' separator (after removing old_suffix if necessary) + params: an optional dictionary of query parameters to append to + the redirect target; appended as ?=&=... + + Returns: + /path/with/new_suffix?a=1&b=2 + """ + if not old_suffix: + old_suffix = '' + + old_suffix = '/' + old_suffix + + if path.endswith(old_suffix): + # also removes any trailing '/' if old_suffix was empty + path = path[:-len(old_suffix)] + + if new_suffix: + # if present, appends new_suffix, after '/' separator + path = '%s/%s' % (path, new_suffix) + + if params: + # appends any query parameters, after a '?' and separated by '&' + path = '%s?%s' % (path, '&'.join( + ['%s=%s' % (p,v) for p,v in params.iteritems()])) + + return path diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/helpers/request_helpers.py --- a/app/soc/views/helpers/request_helpers.py Fri Oct 03 21:41:12 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -#!/usr/bin/python2.5 -# -# Copyright 2008 the Melange authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Helpers for manipulating HTTP requests. -""" - -__authors__ = [ - '"Todd Larsen" ', - ] - -import urlparse - - -def getSingleIndexedParamValue(request, param_name, values=()): - """Returns a value indexed by a query parameter in the HTTP request. - - Args: - request: the Django HTTP request object - param_name: name of the query parameter in the HTTP request - values: list (or tuple) of ordered values; one of which is - retrieved by the index value of the param_name argument in - the HTTP request - - Returns: - None if the query parameter was not present, was not an integer, or - was an integer that is not a valid [0..len(values)-1] index into - the values list. - Otherwise, returns values[int(param_name value)] - """ - value_idx = request.GET.get(param_name) - - if isinstance(value_idx, (tuple, list)): - # keep only the first argument if multiple are present - value_idx = value_idx[0] - - try: - # GET parameter 'param_name' should be an integer value index - value_idx = int(value_idx) - except: - # ignore bogus or missing parameter values, so return None (no message) - return None - - if value_idx < 0: - # value index out of range, so return None (no value) - return None - - if value_idx >= len(values): - # value index out of range, so return None (no value) - return None - - # return value associated with valid value index - return values[value_idx] - - -def getSingleIndexedParamValueIfMissing(value, request, param_name, - values=()): - """Returns missing value indexed by a query parameter in the HTTP request. - - Args: - value: an existing value, or a "False" value such as None - request, param_name, values: see getSingleIndexParamValue() - - Returns: - value, if value is "non-False" - Otherwise, returns getSingleIndexedParamValue() result. - """ - if value: - # value already present, so return it - return value - - return getSingleIndexedParamValue(request, param_name, values=values) - - -# TODO(tlarsen): write getMultipleIndexParamValues() that returns a -# list of values if present, omitting those values that are -# out of range - - -def isReferrerSelf(request, - expected_prefix=None, suffix=None): - """Returns True if HTTP referrer path starts with the HTTP request path. - - Args: - request: the Django HTTP request object; request.path is used if - expected_path is not supplied (the most common usage) - expected_prefix: optional HTTP path to use instead of the one in - request.path; default is None (use request.path) - suffix: suffix to remove from the HTTP request path before comparing - it to the HTTP referrer path in the HTTP request object headers - (this is often an link name, for example, that may be changing from - a POST referrer to a GET redirect target) - - Returns: - True if HTTP referrer path begins with the HTTP request path (either - request.path or expected_prefix instead if it was supplied), after - any suffix was removed from that request path - False otherwise - - """ - http_from = request.META.get('HTTP_REFERER') - - if not http_from: - # no HTTP referrer, so cannot possibly start with expected prefix - return False - - from_path = urlparse.urlparse(http_from).path - - if not expected_prefix: - # use HTTP request path, since expected_prefix was not supplied - expected_prefix = request.path - - if suffix: - # remove suffix (such as a link name) before comparison - chars_to_remove = len(suffix) - - if not suffix.startswith('/'): - chars_to_remove = chars_to_remove + 1 - - expected_prefix = expected_prefix[:-chars_to_remove] - - if not from_path.startswith(expected_prefix): - # expected prefix did not match first part of HTTP referrer path - return False - - # HTTP referrer started with (possibly truncated) expected prefix - return True - - -def replaceSuffix(path, old_suffix, new_suffix=None, params=None): - """Replace the last part of a URL path with something else. - - Also appends an optional list of query parameters. Used for - replacing, for example, one link name at the end of a relative - URL path with another. - - Args: - path: HTTP request relative URL path (with no query arguments) - old_suffix: expected suffix at the end of request.path component; - if any False value (such as None), the empty string '' is used - new_suffix: if non-False, appended to request.path along with a - '/' separator (after removing old_suffix if necessary) - params: an optional dictionary of query parameters to append to - the redirect target; appended as ?=&=... - - Returns: - /path/with/new_suffix?a=1&b=2 - """ - if not old_suffix: - old_suffix = '' - - old_suffix = '/' + old_suffix - - if path.endswith(old_suffix): - # also removes any trailing '/' if old_suffix was empty - path = path[:-len(old_suffix)] - - if new_suffix: - # if present, appends new_suffix, after '/' separator - path = '%s/%s' % (path, new_suffix) - - if params: - # appends any query parameters, after a '?' and separated by '&' - path = '%s?%s' % (path, '&'.join( - ['%s=%s' % (p,v) for p,v in params.iteritems()])) - - return path diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/helpers/response_helpers.py --- a/app/soc/views/helpers/response_helpers.py Fri Oct 03 21:41:12 2008 +0000 +++ b/app/soc/views/helpers/response_helpers.py Fri Oct 03 21:59:32 2008 +0000 @@ -41,9 +41,9 @@ from soc.logic import system from soc.logic.site import id_user from soc.logic.site import sidebar - +from soc.views import helpers +import soc.views.helpers.request from soc.views.helpers import html_menu -from soc.views.helpers import request_helpers def respond(request, template, context=None, response_args=None): @@ -142,11 +142,11 @@ Args: request: the Django HTTP request object; redirect path is derived from request.path - old_suffix, new_suffix, params: see request_helpers.replaceSuffix() + old_suffix, new_suffix, params: see helpers.request.replaceSuffix() Returns: a Django HTTP redirect response pointing to the altered path """ - path = request_helpers.replaceSuffix(request.path, old_suffix, new_suffix, + path = helpers.request.replaceSuffix(request.path, old_suffix, new_suffix, params=params) return http.HttpResponseRedirect(path) diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/site/docs/edit.py --- a/app/soc/views/site/docs/edit.py Fri Oct 03 21:41:12 2008 +0000 +++ b/app/soc/views/site/docs/edit.py Fri Oct 03 21:59:32 2008 +0000 @@ -32,10 +32,11 @@ from soc.logic import out_of_band from soc.logic import path_linkname from soc.logic.site import id_user +from soc.views import helpers +import soc.views.helpers.request from soc.views import simple from soc.views.helpers import custom_widgets from soc.views.helpers import forms_helpers -from soc.views.helpers import request_helpers from soc.views.helpers import response_helpers from soc.views.user import profile @@ -162,14 +163,14 @@ # is 'Profile saved' parameter present, but referrer was not ourself? # (e.g. someone bookmarked the GET that followed the POST submit) if (request.GET.get(profile.SUBMIT_MSG_PARAM_NAME) - and (not request_helpers.isReferrerSelf(request, suffix=path))): + and (not helpers.request.isReferrerSelf(request, suffix=path))): # redirect to aggressively remove 'Profile saved' query parameter return http.HttpResponseRedirect(request.path) # referrer was us, so select which submit message to display # (may display no message if ?s=0 parameter is not present) context['submit_message'] = ( - request_helpers.getSingleIndexedParamValue( + helpers.request.getSingleIndexedParamValue( request, profile.SUBMIT_MSG_PARAM_NAME, values=profile.SUBMIT_MESSAGES)) diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/site/sponsor/list.py --- a/app/soc/views/site/sponsor/list.py Fri Oct 03 21:41:12 2008 +0000 +++ b/app/soc/views/site/sponsor/list.py Fri Oct 03 21:59:32 2008 +0000 @@ -24,6 +24,7 @@ from soc.logic import sponsor from soc.views import simple + from soc.views import helpers import soc.views.helpers.list from soc.views.helpers import response_helpers diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/site/sponsor/profile.py --- a/app/soc/views/site/sponsor/profile.py Fri Oct 03 21:41:12 2008 +0000 +++ b/app/soc/views/site/sponsor/profile.py Fri Oct 03 21:59:32 2008 +0000 @@ -31,11 +31,12 @@ from soc.logic import out_of_band from soc.logic import sponsor from soc.logic.site import id_user +from soc.views import helpers +import soc.views.helpers.request from soc.views import simple from soc.views.helpers import custom_widgets from soc.views.helpers import forms_helpers from soc.views.helpers import response_helpers -from soc.views.helpers import request_helpers from soc.views.user import profile import soc.models.sponsor @@ -158,14 +159,14 @@ # is 'Profile saved' parameter present, but referrer was not ourself? # (e.g. someone bookmarked the GET that followed the POST submit) if (request.GET.get(profile.SUBMIT_MSG_PARAM_NAME) - and (not request_helpers.isReferrerSelf(request, suffix=linkname))): + and (not helpers.request.isReferrerSelf(request, suffix=linkname))): # redirect to aggressively remove 'Profile saved' query parameter return http.HttpResponseRedirect(request.path) # referrer was us, so select which submit message to display # (may display no message if ?s=0 parameter is not present) context['submit_message'] = ( - request_helpers.getSingleIndexedParamValue( + helpers.request.getSingleIndexedParamValue( request, profile.SUBMIT_MSG_PARAM_NAME, values=profile.SUBMIT_MESSAGES)) diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/site/user/profile.py --- a/app/soc/views/site/user/profile.py Fri Oct 03 21:41:12 2008 +0000 +++ b/app/soc/views/site/user/profile.py Fri Oct 03 21:59:32 2008 +0000 @@ -34,8 +34,8 @@ from soc.views import simple from soc.views import helpers import soc.views.helpers.list +import soc.views.helpers.request from soc.views.helpers import forms_helpers -from soc.views.helpers import request_helpers from soc.views.helpers import response_helpers from soc.views.user import profile @@ -169,7 +169,7 @@ if request.path.endswith('lookup'): # convert /lookup path into /profile/link_name path - context['edit_link'] = request_helpers.replaceSuffix( + context['edit_link'] = helpers.request.replaceSuffix( request.path, 'lookup', 'profile/%s' % user.link_name) # else: URL is not one that was expected, so do not display edit link elif not form: @@ -296,7 +296,7 @@ # is 'Profile saved' parameter present, but referrer was not ourself? # (e.g. someone bookmarked the GET that followed the POST submit) if (request.GET.get(profile.SUBMIT_MSG_PARAM_NAME) - and (not request_helpers.isReferrerSelf(request, + and (not helpers.request.isReferrerSelf(request, suffix=linkname))): # redirect to aggressively remove 'Profile saved' query parameter return http.HttpResponseRedirect(request.path) @@ -304,7 +304,7 @@ # referrer was us, so select which submit message to display # (may display no message if ?s=0 parameter is not present) context['submit_message'] = ( - request_helpers.getSingleIndexedParamValue( + helpers.request.getSingleIndexedParamValue( request, profile.SUBMIT_MSG_PARAM_NAME, values=profile.SUBMIT_MESSAGES)) diff -r 3b47bfd4f1b3 -r 0c008a43443b app/soc/views/user/profile.py --- a/app/soc/views/user/profile.py Fri Oct 03 21:41:12 2008 +0000 +++ b/app/soc/views/user/profile.py Fri Oct 03 21:59:32 2008 +0000 @@ -31,9 +31,10 @@ from soc.logic import validate from soc.logic import out_of_band from soc.logic.site import id_user +from soc.views import helpers +import soc.views.helpers.request from soc.views import simple from soc.views.helpers import forms_helpers -from soc.views.helpers import request_helpers from soc.views.helpers import response_helpers import soc.models.user @@ -139,7 +140,7 @@ # is 'Profile saved' parameter present, but referrer was not ourself? # (e.g. someone bookmarked the GET that followed the POST submit) if (request.GET.get(SUBMIT_MSG_PARAM_NAME) - and (not request_helpers.isReferrerSelf(request, + and (not helpers.request.isReferrerSelf(request, suffix=linkname))): # redirect to aggressively remove 'Profile saved' query parameter return http.HttpResponseRedirect(request.path) @@ -147,7 +148,7 @@ # referrer was us, so select which submit message to display # (may display no message if ?s=0 parameter is not present) context['submit_message'] = ( - request_helpers.getSingleIndexedParamValue( + helpers.request.getSingleIndexedParamValue( request, SUBMIT_MSG_PARAM_NAME, values=SUBMIT_MESSAGES)) # populate form with the existing User entity