From 9535617c5970c7695b4dfbd068d407fde3f813b9 Mon Sep 17 00:00:00 2001 From: kgriffs Date: Tue, 14 May 2013 09:03:37 -0500 Subject: [PATCH] refactor: Migrate _percent_escape to util This change makes it easier to reuse that code within Falcon, as well as making the function available to 3rd parties. --- falcon/http_error.py | 21 ++------------------- falcon/util.py | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/falcon/http_error.py b/falcon/http_error.py index 4179b33..2081fb9 100644 --- a/falcon/http_error.py +++ b/falcon/http_error.py @@ -24,7 +24,7 @@ if sys.version_info < (2, 7): # pragma: no cover else: # pragma: no cover from collections import OrderedDict -import six +from falcon import util class HTTPError(Exception): @@ -92,7 +92,7 @@ class HTTPError(Exception): if href: link = self.link = OrderedDict() link['text'] = (href_text or 'API documention for this error') - link['href'] = _percent_escape(href) + link['href'] = util.percent_escape(href) link['rel'] = 'help' else: self.link = None @@ -126,20 +126,3 @@ class HTTPError(Exception): return json.dumps(obj, indent=4, separators=(',', ': '), ensure_ascii=False) - -if six.PY3: # pragma nocover - from urllib.parse import quote as url_quote - - def _percent_escape(url): - return url_quote(url, safe='/:') - -else: # pragma nocover - from urllib import quote as url_quote - - def _percent_escape(url): - # Convert the string so that urllib.quote does not complain - # if it actually has Unicode chars in it. - if isinstance(url, unicode): - url = url.encode('utf-8') - - return url_quote(url, safe='/:') diff --git a/falcon/util.py b/falcon/util.py index 001f6aa..3afc3d7 100644 --- a/falcon/util.py +++ b/falcon/util.py @@ -17,6 +17,12 @@ limitations under the License. """ import datetime +import six + +if six.PY3: # pragma nocover + from urllib.parse import quote as url_quote +else: # pragma nocover + from urllib import quote as url_quote def dt_to_http(dt): @@ -28,7 +34,6 @@ def dt_to_http(dt): Returns: An HTTP date string, e.g., "Tue, 15 Nov 1994 12:45:26 GMT". See also: http://goo.gl/R7So4 - """ # Tue, 15 Nov 1994 12:45:26 GMT @@ -36,6 +41,15 @@ def dt_to_http(dt): def http_date_to_dt(http_date): + """Converts an HTTP date string to a datetime instance. + + Args: + http_date: An HTTP date string, e.g., "Tue, 15 Nov 1994 12:45:26 GMT". + + Returns: + A UTC datetime instance corresponding to the given HTTP date. + """ + return datetime.datetime.strptime( http_date, '%a, %d %b %Y %H:%M:%S %Z') @@ -51,8 +65,8 @@ def to_query_str(params): Returns: A URI query string starting with '?', or and empty string if there are no params (the dict is empty). - """ + if not params: return '' @@ -70,3 +84,24 @@ def to_query_str(params): query_str += k + '=' + v + '&' return query_str[:-1] + + +def percent_escape(url): + """Percent-escape reserved characters in the given url. + + Args: + url: A full or relative URL. + + Returns: + An escaped version of the URL, excluding '/', ',' and ':' + characters. In Python 2, unicode URL strings will be first + encoded to a UTF-8 byte string to work around a urllib + bug. + """ + + # Convert the string so that urllib.quote does not complain + # if it actually has Unicode chars in it. + if not six.PY3 and isinstance(url, six.text_type): # pragma nocover + url = url.encode('utf-8') + + return url_quote(url, safe='/:,')