3
# Copyright 2009 Facebook
5
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6
# not use this file except in compliance with the License. You may obtain
7
# a copy of the License at
9
# http://www.apache.org/licenses/LICENSE-2.0
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
# License for the specific language governing permissions and limitations
17
"""Escaping/unescaping methods for HTML, JSON, URLs, and others."""
21
import xml.sax.saxutils
26
assert hasattr(json, "loads") and hasattr(json, "dumps")
27
_json_decode = lambda s: json.loads(s)
28
_json_encode = lambda v: json.dumps(v)
32
_json_decode = lambda s: simplejson.loads(_unicode(s))
33
_json_encode = lambda v: simplejson.dumps(v)
36
# For Google AppEngine
37
from django.utils import simplejson
38
_json_decode = lambda s: simplejson.loads(_unicode(s))
39
_json_encode = lambda v: simplejson.dumps(v)
41
raise Exception("A JSON parser is required, e.g., simplejson at "
42
"http://pypi.python.org/pypi/simplejson/")
45
def xhtml_escape(value):
46
"""Escapes a string so it is valid within XML or XHTML."""
47
return utf8(xml.sax.saxutils.escape(value, {'"': """}))
50
def xhtml_unescape(value):
51
"""Un-escapes an XML-escaped string."""
52
return re.sub(r"&(#?)(\w+?);", _convert_entity, _unicode(value))
55
def json_encode(value):
56
"""JSON-encodes the given Python object."""
57
return _json_encode(value)
60
def json_decode(value):
61
"""Returns Python objects for the given JSON string."""
62
return _json_decode(value)
66
"""Replace all sequences of whitespace chars with a single space."""
67
return re.sub(r"[\x00-\x20]+", " ", value).strip()
70
def url_escape(value):
71
"""Returns a valid URL-encoded version of the given value."""
72
return urllib.quote_plus(utf8(value))
75
def url_unescape(value):
76
"""Decodes the given value from a URL."""
77
return _unicode(urllib.unquote_plus(value))
81
if isinstance(value, unicode):
82
return value.encode("utf-8")
83
assert isinstance(value, str)
88
if isinstance(value, str):
89
return value.decode("utf-8")
90
assert isinstance(value, unicode)
94
def _convert_entity(m):
97
return unichr(int(m.group(2)))
99
return "&#%s;" % m.group(2)
101
return _HTML_UNICODE_MAP[m.group(2)]
103
return "&%s;" % m.group(2)
106
def _build_unicode_map():
108
for name, value in htmlentitydefs.name2codepoint.iteritems():
109
unicode_map[name] = unichr(value)
112
_HTML_UNICODE_MAP = _build_unicode_map()