app/soc/views/helper/requests.py
changeset 269 0f1acc4c3e1e
parent 267 0c008a43443b
child 365 74dec172944e
equal deleted inserted replaced
268:af1d7f48b361 269:0f1acc4c3e1e
       
     1 #!/usr/bin/python2.5
       
     2 #
       
     3 # Copyright 2008 the Melange authors.
       
     4 #
       
     5 # Licensed under the Apache License, Version 2.0 (the "License");
       
     6 # you may not use this file except in compliance with the License.
       
     7 # You may obtain a copy of the License at
       
     8 #
       
     9 #   http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 # Unless required by applicable law or agreed to in writing, software
       
    12 # distributed under the License is distributed on an "AS IS" BASIS,
       
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 # See the License for the specific language governing permissions and
       
    15 # limitations under the License.
       
    16 
       
    17 """Helpers for manipulating HTTP requests.
       
    18 """
       
    19 
       
    20 __authors__ = [
       
    21   '"Todd Larsen" <tlarsen@google.com>',
       
    22   ]
       
    23 
       
    24 import urlparse
       
    25 
       
    26 
       
    27 def getSingleIndexedParamValue(request, param_name, values=()):
       
    28   """Returns a value indexed by a query parameter in the HTTP request.
       
    29   
       
    30   Args:
       
    31     request: the Django HTTP request object
       
    32     param_name: name of the query parameter in the HTTP request
       
    33     values: list (or tuple) of ordered values; one of which is
       
    34       retrieved by the index value of the param_name argument in
       
    35       the HTTP request
       
    36       
       
    37   Returns:
       
    38     None if the query parameter was not present, was not an integer, or
       
    39       was an integer that is not a valid [0..len(values)-1] index into
       
    40       the values list.
       
    41     Otherwise, returns values[int(param_name value)]
       
    42   """
       
    43   value_idx = request.GET.get(param_name)
       
    44   
       
    45   if isinstance(value_idx, (tuple, list)):
       
    46     # keep only the first argument if multiple are present
       
    47     value_idx = value_idx[0]
       
    48 
       
    49   try:
       
    50     # GET parameter 'param_name' should be an integer value index
       
    51     value_idx = int(value_idx)
       
    52   except:
       
    53     # ignore bogus or missing parameter values, so return None (no message)
       
    54     return None
       
    55     
       
    56   if value_idx < 0:
       
    57     # value index out of range, so return None (no value)
       
    58     return None
       
    59 
       
    60   if value_idx >= len(values):
       
    61     # value index out of range, so return None (no value)
       
    62     return None
       
    63 
       
    64   # return value associated with valid value index
       
    65   return values[value_idx]
       
    66 
       
    67 
       
    68 def getSingleIndexedParamValueIfMissing(value, request, param_name,
       
    69                                         values=()):
       
    70   """Returns missing value indexed by a query parameter in the HTTP request.
       
    71   
       
    72   Args:
       
    73     value: an existing value, or a "False" value such as None
       
    74     request, param_name, values: see getSingleIndexParamValue()
       
    75     
       
    76   Returns:
       
    77     value, if value is "non-False"
       
    78     Otherwise, returns getSingleIndexedParamValue() result.
       
    79   """
       
    80   if value:
       
    81     # value already present, so return it
       
    82     return value
       
    83 
       
    84   return getSingleIndexedParamValue(request, param_name, values=values)
       
    85 
       
    86 
       
    87 # TODO(tlarsen):  write getMultipleIndexParamValues() that returns a
       
    88 #   list of values if present, omitting those values that are
       
    89 #   out of range
       
    90 
       
    91 
       
    92 def isReferrerSelf(request,
       
    93                    expected_prefix=None, suffix=None):
       
    94   """Returns True if HTTP referrer path starts with the HTTP request path.
       
    95     
       
    96   Args:
       
    97     request: the Django HTTP request object; request.path is used if
       
    98       expected_path is not supplied (the most common usage)
       
    99     expected_prefix: optional HTTP path to use instead of the one in
       
   100       request.path; default is None (use request.path)
       
   101     suffix: suffix to remove from the HTTP request path before comparing
       
   102       it to the HTTP referrer path in the HTTP request object headers
       
   103       (this is often an link name, for example, that may be changing from
       
   104       a POST referrer to a GET redirect target) 
       
   105   
       
   106   Returns:
       
   107     True if HTTP referrer path begins with the HTTP request path (either
       
   108       request.path or expected_prefix instead if it was supplied), after
       
   109       any suffix was removed from that request path
       
   110     False otherwise
       
   111        
       
   112   """
       
   113   http_from = request.META.get('HTTP_REFERER')
       
   114       
       
   115   if not http_from:
       
   116     # no HTTP referrer, so cannot possibly start with expected prefix
       
   117     return False
       
   118 
       
   119   from_path = urlparse.urlparse(http_from).path
       
   120   
       
   121   if not expected_prefix:
       
   122     # use HTTP request path, since expected_prefix was not supplied
       
   123     expected_prefix = request.path
       
   124 
       
   125   if suffix:
       
   126     # remove suffix (such as a link name) before comparison
       
   127     chars_to_remove = len(suffix)
       
   128     
       
   129     if not suffix.startswith('/'):
       
   130       chars_to_remove = chars_to_remove + 1
       
   131 
       
   132     expected_prefix = expected_prefix[:-chars_to_remove]
       
   133 
       
   134   if not from_path.startswith(expected_prefix):
       
   135     # expected prefix did not match first part of HTTP referrer path
       
   136     return False
       
   137  
       
   138   # HTTP referrer started with (possibly truncated) expected prefix
       
   139   return True
       
   140 
       
   141 
       
   142 def replaceSuffix(path, old_suffix, new_suffix=None, params=None):
       
   143   """Replace the last part of a URL path with something else.
       
   144 
       
   145   Also appends an optional list of query parameters.  Used for
       
   146   replacing, for example, one link name at the end of a relative
       
   147   URL path with another.
       
   148 
       
   149   Args:
       
   150     path: HTTP request relative URL path (with no query arguments)
       
   151     old_suffix: expected suffix at the end of request.path component;
       
   152       if any False value (such as None), the empty string '' is used
       
   153     new_suffix: if non-False, appended to request.path along with a
       
   154       '/' separator (after removing old_suffix if necessary)
       
   155     params: an optional dictionary of query parameters to append to
       
   156       the redirect target; appended as ?<key1>=<value1>&<key2>=...
       
   157       
       
   158   Returns:
       
   159     /path/with/new_suffix?a=1&b=2
       
   160   """    
       
   161   if not old_suffix:
       
   162     old_suffix = ''
       
   163 
       
   164   old_suffix = '/' + old_suffix
       
   165 
       
   166   if path.endswith(old_suffix):
       
   167     # also removes any trailing '/' if old_suffix was empty
       
   168     path = path[:-len(old_suffix)]
       
   169 
       
   170   if new_suffix:
       
   171     # if present, appends new_suffix, after '/' separator
       
   172     path = '%s/%s' % (path, new_suffix)
       
   173 
       
   174   if params:
       
   175     # appends any query parameters, after a '?' and separated by '&'
       
   176     path = '%s?%s' % (path, '&'.join(
       
   177         ['%s=%s' % (p,v) for p,v in params.iteritems()]))
       
   178 
       
   179   return path