| 1 | # -*- coding: utf-8 -*- |
---|
| 2 | # |
---|
| 3 | # Copyright (C)2006-2009 Edgewall Software |
---|
| 4 | # Copyright (C) 2006 Christopher Lenz <cmlenz@gmx.de> |
---|
| 5 | # All rights reserved. |
---|
| 6 | # |
---|
| 7 | # This software is licensed as described in the file COPYING, which |
---|
| 8 | # you should have received as part of this distribution. The terms |
---|
| 9 | # are also available at http://trac.edgewall.org/wiki/TracLicense. |
---|
| 10 | # |
---|
| 11 | # This software consists of voluntary contributions made by many |
---|
| 12 | # individuals. For the exact contribution history, see the revision |
---|
| 13 | # history and logs, available at http://trac.edgewall.org/log/. |
---|
| 14 | |
---|
1 | 15 | """Utility functions for converting to web formats""" |
---|
| 16 | |
---|
| 17 | # to_json is really a wrapper for trac.util.presentation.to_json, but we have lots of fallbacks for compatibility |
---|
| 18 | # trac.util.presentation.to_json is present from Trac 0.12 |
---|
| 19 | # If that's not present, we fall back to the default Python json module, present from Python 2.6 onwards |
---|
| 20 | # If that's not present, we have a copy of the to_json method, which we will remove once Trac 0.11 support is removed |
---|
| 21 | # And finally, the to_json method requires trac.util.text.javascript_quote, which is only present from Trac 0.11.3, so we have a copy of that too |
---|
| 22 | |
---|
1 | 23 | import re |
---|
| 24 | |
---|
1 | 25 | try: |
---|
| 26 | # to_json is present from Trac 0.12 onwards - should remove once Trac 0.11 support is removed |
---|
1 | 27 | from trac.util.presentation import to_json |
---|
0 | 28 | except ImportError: |
---|
0 | 29 | try: |
---|
| 30 | # If we have Python 2.6 onwards, use the json method directly |
---|
0 | 31 | from json import dumps |
---|
| 32 | |
---|
0 | 33 | def to_json(value): |
---|
| 34 | """Encode `value` to JSON.""" |
---|
0 | 35 | return dumps(value, sort_keys=True, separators=(',', ':')) |
---|
0 | 36 | except ImportError: |
---|
| 37 | # javascript_quote is present from Trac 0.11.3 onwards - should remove once Trac 0.11.2 support is removed |
---|
0 | 38 | try: |
---|
0 | 39 | from trac.util.text import javascript_quote |
---|
0 | 40 | except ImportError: |
---|
0 | 41 | _js_quote = {'\\': '\\\\', '"': '\\"', '\b': '\\b', '\f': '\\f', |
---|
0 | 42 | '\n': '\\n', '\r': '\\r', '\t': '\\t', "'": "\\'"} |
---|
0 | 43 | for i in range(0x20): |
---|
0 | 44 | _js_quote.setdefault(chr(i), '\\u%04x' % i) |
---|
0 | 45 | _js_quote_re = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t\']') |
---|
0 | 46 | def javascript_quote(text): |
---|
| 47 | """Quote strings for inclusion in javascript""" |
---|
0 | 48 | if not text: |
---|
0 | 49 | return '' |
---|
0 | 50 | def replace(match): |
---|
0 | 51 | return _js_quote[match.group(0)] |
---|
0 | 52 | return _js_quote_re.sub(replace, text) |
---|
| 53 | |
---|
0 | 54 | def to_json(value): |
---|
| 55 | """Encode `value` to JSON.""" |
---|
0 | 56 | if isinstance(value, basestring): |
---|
0 | 57 | return '"%s"' % javascript_quote(value) |
---|
0 | 58 | elif value is None: |
---|
0 | 59 | return 'null' |
---|
0 | 60 | elif value is False: |
---|
0 | 61 | return 'false' |
---|
0 | 62 | elif value is True: |
---|
0 | 63 | return 'true' |
---|
0 | 64 | elif isinstance(value, (int, long)): |
---|
0 | 65 | return str(value) |
---|
0 | 66 | elif isinstance(value, float): |
---|
0 | 67 | return repr(value) |
---|
0 | 68 | elif isinstance(value, (list, tuple)): |
---|
0 | 69 | return '[%s]' % ','.join(to_json(each) for each in value) |
---|
0 | 70 | elif isinstance(value, dict): |
---|
0 | 71 | return '{%s}' % ','.join('%s:%s' % (to_json(k), to_json(v)) |
---|
0 | 72 | for k, v in sorted(value.iteritems())) |
---|
0 | 73 | else: |
---|
0 | 74 | raise TypeError('Cannot encode type %s' % value.__class__.__name__) |
---|