Added replaceSuffix(), isReferrerSelf(), and redirectToChangedSuffix() to
authorTodd Larsen <tlarsen@google.com>
Fri, 19 Sep 2008 04:28:17 +0000
changeset 167 13e438623ded
parent 166 4d2cbd0ea977
child 168 87296bdfc9c6
Added replaceSuffix(), isReferrerSelf(), and redirectToChangedSuffix() to implement the TODO in the User profile views where the link name portion of the URL needs to change when the link_name Property is updated by the form.
app/soc/views/helpers/response_helpers.py
--- a/app/soc/views/helpers/response_helpers.py	Thu Sep 18 23:07:06 2008 +0000
+++ b/app/soc/views/helpers/response_helpers.py	Fri Sep 19 04:28:17 2008 +0000
@@ -23,6 +23,8 @@
   ]
 
 
+import urlparse
+
 from google.appengine.api import users
 
 from django import http
@@ -120,3 +122,104 @@
       'sign_out', users.create_logout_url(request.path))
 
   return context
+
+
+def replaceSuffix(path, old_suffix, new_suffix, 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 ?<key1>=<value1>&<key2>=...
+      
+  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
+
+
+def redirectToChangedSuffix(
+    request, old_suffix, new_suffix, params=None):
+  """Changes suffix of URL path and returns an HTTP redirect response.
+  
+  Args:
+    request: the Django HTTP request object; redirect path is derived from
+      request.path
+    old_suffix, new_suffix, params:  see replaceSuffix()
+      
+  Returns:
+    a Django HTTP redirect response pointing to the altered path
+  """
+  path = replaceSuffix(request.path, old_suffix, new_suffix, params=params)
+  return http.HttpResponseRedirect(path)
+
+
+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
+    expected_prefix = expected_prefix[:-len(suffix)+1]
+
+  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