app/soc/views/helpers/response_helpers.py
changeset 167 13e438623ded
parent 135 a7ccde9d9eed
child 169 a9b3d6c9d4f9
--- 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