web/lib/django/utils/http.py
changeset 0 0d40e90630ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/django/utils/http.py	Wed Jan 20 00:34:04 2010 +0100
@@ -0,0 +1,119 @@
+import re
+import urllib
+from email.Utils import formatdate
+
+from django.utils.encoding import smart_str, force_unicode
+from django.utils.functional import allow_lazy
+
+ETAG_MATCH = re.compile(r'(?:W/)?"((?:\\.|[^"])*)"')
+
+def urlquote(url, safe='/'):
+    """
+    A version of Python's urllib.quote() function that can operate on unicode
+    strings. The url is first UTF-8 encoded before quoting. The returned string
+    can safely be used as part of an argument to a subsequent iri_to_uri() call
+    without double-quoting occurring.
+    """
+    return force_unicode(urllib.quote(smart_str(url), safe))
+
+urlquote = allow_lazy(urlquote, unicode)
+
+def urlquote_plus(url, safe=''):
+    """
+    A version of Python's urllib.quote_plus() function that can operate on
+    unicode strings. The url is first UTF-8 encoded before quoting. The
+    returned string can safely be used as part of an argument to a subsequent
+    iri_to_uri() call without double-quoting occurring.
+    """
+    return force_unicode(urllib.quote_plus(smart_str(url), safe))
+urlquote_plus = allow_lazy(urlquote_plus, unicode)
+
+def urlencode(query, doseq=0):
+    """
+    A version of Python's urllib.urlencode() function that can operate on
+    unicode strings. The parameters are first case to UTF-8 encoded strings and
+    then encoded as per normal.
+    """
+    if hasattr(query, 'items'):
+        query = query.items()
+    return urllib.urlencode(
+        [(smart_str(k),
+         isinstance(v, (list,tuple)) and [smart_str(i) for i in v] or smart_str(v))
+            for k, v in query],
+        doseq)
+
+def cookie_date(epoch_seconds=None):
+    """
+    Formats the time to ensure compatibility with Netscape's cookie standard.
+
+    Accepts a floating point number expressed in seconds since the epoch, in
+    UTC - such as that outputted by time.time(). If set to None, defaults to
+    the current time.
+
+    Outputs a string in the format 'Wdy, DD-Mon-YYYY HH:MM:SS GMT'.
+    """
+    rfcdate = formatdate(epoch_seconds)
+    return '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25])
+
+def http_date(epoch_seconds=None):
+    """
+    Formats the time to match the RFC1123 date format as specified by HTTP
+    RFC2616 section 3.3.1.
+
+    Accepts a floating point number expressed in seconds since the epoch, in
+    UTC - such as that outputted by time.time(). If set to None, defaults to
+    the current time.
+
+    Outputs a string in the format 'Wdy, DD Mon YYYY HH:MM:SS GMT'.
+    """
+    rfcdate = formatdate(epoch_seconds)
+    return '%s GMT' % rfcdate[:25]
+
+# Base 36 functions: useful for generating compact URLs
+
+def base36_to_int(s):
+    """
+    Convertd a base 36 string to an integer
+    """
+    return int(s, 36)
+
+def int_to_base36(i):
+    """
+    Converts an integer to a base36 string
+    """
+    digits = "0123456789abcdefghijklmnopqrstuvwxyz"
+    factor = 0
+    # Find starting factor
+    while True:
+        factor += 1
+        if i < 36 ** factor:
+            factor -= 1
+            break
+    base36 = []
+    # Construct base36 representation
+    while factor >= 0:
+        j = 36 ** factor
+        base36.append(digits[i / j])
+        i = i % j
+        factor -= 1
+    return ''.join(base36)
+
+def parse_etags(etag_str):
+    """
+    Parses a string with one or several etags passed in If-None-Match and
+    If-Match headers by the rules in RFC 2616. Returns a list of etags
+    without surrounding double quotes (") and unescaped from \<CHAR>.
+    """
+    etags = ETAG_MATCH.findall(etag_str)
+    if not etags:
+        # etag_str has wrong format, treat it as an opaque string then
+        return [etag_str]
+    etags = [e.decode('string_escape') for e in etags]
+    return etags
+
+def quote_etag(etag):
+    """
+    Wraps a string in double quotes escaping contents as necesary.
+    """
+    return '"%s"' % etag.replace('\\', '\\\\').replace('"', '\\"')
+