TurboJson-1.3.2/0000755000175000017500000000000011617562645012135 5ustar citocitoTurboJson-1.3.2/PKG-INFO0000644000175000017500000000131611617562645013233 0ustar citocitoMetadata-Version: 1.0 Name: TurboJson Version: 1.3.2 Summary: Python template plugin that supports JSON Home-page: http://docs.turbogears.org/TurboJson Author: TurboGears project Author-email: turbogears@googlegroups.com License: MIT Download-URL: http://pypi.python.org/pypi/TurboJson Description: UNKNOWN Keywords: python.templating.engines,turbogears Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Framework :: TurboGears Classifier: Environment :: Web Environment :: Buffet Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Software Development :: Libraries :: Python Modules TurboJson-1.3.2/release_howto.txt0000644000175000017500000000267311617562574015547 0ustar citocitoMaking a TurboJson release How-to ================================= :Authors: Florent Aide, Christopher Arndt, Christoph Zwerschke :Date: 2011-08-07 :Revision: 4 1) Make sure all tests pass and setup.py contains the desired version number. .. note:: The TurboJson trunk starting with version 1.2 removed the dependency on RuleDispatch and uses PEAK-Rules instead. TurboJson versions >= 1.2 are intended to be used with TurboGears 1.1 and 1.5. If you want to update TurboJson for TurboGears 1.0, please use the TurboJson 1.1 branch. You should run the tests with Python 2.4 to 2.7, and various versions of SQLObject and SQLAlchemy (e.g. SQLAlchemy 0.4.3, 0.5.x, 0.6.x, 0.7.x). Also check with the minimum required and current versions of PEAK-Rules. 2) Create the eggs with the desired Python version using the following command line. This command will ignore the version numbers and svn tagging put in the setup.cfg file:: python setup.py egg_info -RDb "" sdist bdist_egg 3) Upload the eggs to the TurboGears Egg Basket (http://pypi.turbogears.org): python setup.py egg_info -RDb "" sdist bdist_egg upload -r http://pypi.turbogears.org/upload 4) Upload the eggs to the Cheese Shop (http://pypi.python.org):: python setup.py egg_info -RDb "" sdist bdist_egg register upload 5) Create a tag in SVN and increase the version number in the trunk. 6) Announce at the ML, etc, etc... TurboJson-1.3.2/setup.py0000644000175000017500000000323011617562574013646 0ustar citocito# -*- coding: UTF-8 -*- from sys import version_info as python_version from setuptools import setup, find_packages if python_version < (2, 4): raise SystemExit("TurboJson 1.3 requires Python 2.4 or later.") setup( name = 'TurboJson', version = '1.3.2', description = 'Python template plugin that supports JSON', author = 'Elvelind Grandin et al', author_email = 'elvelind+turbogears@gmail.com', maintainer = 'TurboGears project', maintainer_email = 'turbogears@googlegroups.com', url = 'http://docs.turbogears.org/TurboJson', download_url = 'http://pypi.python.org/pypi/TurboJson', license = 'MIT', keywords = [ 'python.templating.engines', 'turbogears' ], install_requires = [ 'PEAK-Rules >= 0.5a1.dev-r2600', # simplejson is actually available as json in the standard library # since Python 2.6, but the externally maintained package is newer # and can be substantially faster, so we always require it here 'simplejson >= 1.9.1' ], tests_require = [ 'SQLAlchemy', 'SQLObject' ], zip_safe = True, packages = find_packages(), classifiers = [ 'Development Status :: 4 - Beta', 'Framework :: TurboGears', 'Environment :: Web Environment :: Buffet', 'Operating System :: OS Independent', 'Programming Language :: Python', 'License :: OSI Approved :: MIT License', 'Topic :: Software Development :: Libraries :: Python Modules' ], entry_points = """\ [python.templating.engines] json = turbojson.jsonsupport:JsonSupport """, test_suite = 'nose.collector' ) TurboJson-1.3.2/README.txt0000644000175000017500000000100211617562574013625 0ustar citocitoTurboJson ========= This package provides a template engine plugin, allowing you to easily use JSON via the simplejson module with TurboGears, Buffet or other systems that support python.templating.engines. For information on simplejson, go here: http://simplejson.github.com/simplejson/ For information on using a template engine plugin with TurboGears or writing a template engine plugin, go here: http://www.turbogears.org/1.0/docs/TemplatePlugins http://www.turbogears.org/1.0/docs/AlternativeTemplating TurboJson-1.3.2/turbojson/0000755000175000017500000000000011617562645014162 5ustar citocitoTurboJson-1.3.2/turbojson/tests/0000755000175000017500000000000011617562645015324 5ustar citocitoTurboJson-1.3.2/turbojson/tests/test_sqlobject.py0000644000175000017500000000415711617562574020733 0ustar citocitofrom turbojson.jsonify import jsonify, encode, GenericJSON try: try: import sqlite3 except ImportError: # Python < 2.5 import pysqlite2 from sqlobject import sqlhub, connectionForURI, SQLObject, StringCol from sqlobject.inheritance import InheritableSQLObject sqlhub.processConnection = connectionForURI('sqlite:/:memory:') class Person(SQLObject): fname = StringCol() mi = StringCol(length=1, default=None) lname = StringCol() Person.createTable() class ExplicitPerson(SQLObject): fname = StringCol() def __json__(self): return {'customized': True} ExplicitPerson.createTable() class A(InheritableSQLObject): foo = StringCol() A.createTable() class B(A): bar = StringCol() B.createTable() class C(A): baz = StringCol() def __json__(self): return {'customized': True} C.createTable() except ImportError: from warnings import warn warn('SQLObject or PySqlite not installed - cannot run these tests.') else: def test_soobj(): p = Person(fname="Peter", mi="P", lname="Pasulke") pj = jsonify(p) assert pj == {'fname': "Peter", 'mi': "P", 'lname': "Pasulke", 'id': 1} b = B(foo="foo", bar="bar") bj = jsonify(b) assert bj == {'foo': "foo", 'bar': "bar", 'id': b.id, 'childName': None} def test_customized_soobj(): ep = ExplicitPerson(fname="Peter") epj = jsonify(ep) assert epj == {'customized': True} c = C(foo="foo", baz="baz") cj = jsonify(c) assert cj == {'customized': True} def test_so_select_result(): p = Person(fname="Willy", mi="P", lname="Millowitsch") sr = Person.select(Person.q.fname == "Willy") srj = jsonify(sr) assert srj == [p] def test_descent_bases(): b = B(foo="foo", bar="bar") bj = jsonify(b) assert 'foo' in bj and 'bar' in bj no_descent_encoder = GenericJSON(descent_bases=False) bj = no_descent_encoder.encode(b) assert 'foo' not in bj and 'bar' in bj TurboJson-1.3.2/turbojson/tests/test_sqlalchemy.py0000644000175000017500000000607011617562574021103 0ustar citocitofrom turbojson.jsonify import jsonify, encode try: try: import sqlite3 except ImportError: # Python < 2.5 import pysqlite2 from sqlalchemy import (MetaData, Table, Column, ForeignKey, Integer, String) from sqlalchemy.orm import create_session, mapper, relation metadata = MetaData('sqlite:///:memory:') test1 = Table('test1', metadata, Column('id', Integer, primary_key=True), Column('val', String(8))) test2 = Table('test2', metadata, Column('id', Integer, primary_key=True), Column('test1id', Integer, ForeignKey('test1.id')), Column('val', String(8))) test3 = Table('test3', metadata, Column('id', Integer, primary_key=True), Column('val', String(8))) test4 = Table('test4', metadata, Column('id', Integer, primary_key=True), Column('val', String(8))) metadata.create_all() class Test2(object): pass mapper(Test2, test2) class Test1(object): pass mapper(Test1, test1, properties={'test2s': relation(Test2)}) class Test3(object): def __json__(self): return {'id': self.id, 'val': self.val, 'customized': True} mapper(Test3, test3) class Test4(object): pass mapper(Test4, test4) test1.insert().execute({'id': 1, 'val': 'bob'}) test2.insert().execute({'id': 1, 'test1id': 1, 'val': 'fred'}) test2.insert().execute({'id': 2, 'test1id': 1, 'val': 'alice'}) test3.insert().execute({'id': 1, 'val': 'bob'}) test4.insert().execute({'id': 1, 'val': 'alberto'}) except ImportError: from warnings import warn warn('SQLAlchemy or PySqlite not installed - cannot run these tests.') else: def test_saobj(): s = create_session() t = s.query(Test1).get(1) encoded = encode(t) assert encoded == '{"id": 1, "val": "bob"}' def test_salist(): s = create_session() t = s.query(Test1).get(1) encoded = encode(t.test2s) assert encoded == ('[{"test1id": 1, "id": 1, "val": "fred"},' ' {"test1id": 1, "id": 2, "val": "alice"}]') def test_select_row(): s = create_session() t = test1.select().execute() encoded = encode(t) assert encoded == '[{"id": 1, "val": "bob"}]' def test_select_rows(): s = create_session() t = test2.select().execute() encoded = encode(t) assert encoded == ('[{"test1id": 1, "id": 1, "val": "fred"},' ' {"test1id": 1, "id": 2, "val": "alice"}]') def test_explicit_saobj(): s = create_session() t = s.query(Test3).get(1) encoded = encode(t) assert encoded == '{"id": 1, "val": "bob", "customized": true}' def test_priority_override(): s = create_session() t = s.query(Test4).get(1) encoded = encode(t) assert encoded == '{"id": 1, "val": "alberto"}' @jsonify.when((Test4,)) def jsonify_test4(obj): return {'val': obj.val} encoded = encode(t) assert encoded == '{"val": "alberto"}' TurboJson-1.3.2/turbojson/tests/__init__.py0000644000175000017500000000002211617562574017430 0ustar citocito# TurboJson tests TurboJson-1.3.2/turbojson/tests/test_jsonify.py0000644000175000017500000000475711617562574020434 0ustar citocitofrom datetime import date, datetime from decimal import Decimal from turbojson.jsonify import jsonify, encode, encode_iter class Foo(object): def __init__(self, bar): self.bar = bar class Bar(object): def __init__(self, bar): self.bar = bar def __json__(self): return 'bar-%s' % self.bar class Baz(object): pass @jsonify.when("isinstance(obj, Foo)") def jsonify_foo(obj): return "foo-%s" % obj.bar def test_none(): assert encode(None) == 'null' def test_bool(): assert encode(True) == 'true' assert encode(False) == 'false' def test_str(): assert encode("bla") == '"bla"' def test_unicode(): assert encode(u"bla") == '"bla"' def test_int(): assert encode(42) == '42' def test_long(): assert encode(424242424242424242424242L) == '424242424242424242424242' def test_float(): assert encode(1234.5) == '1234.5' def test_list(): d = ['a', 1, 'b', 2] encoded = encode(d) assert encoded == '["a", 1, "b", 2]' def test_list_iter(): d = range(3) encoded = encode_iter(d) assert ''.join(encode_iter(d)) == encode(d) def test_dictionary(): d = {'a': 1, 'b': 2} encoded = encode(d) assert encoded == '{"a": 1, "b": 2}' def test_tuple(): assert encode((1, 2, 3)) == '[1, 2, 3]' def test_set(): assert encode(set([1, 2, 3])) == '[1, 2, 3]' assert encode(frozenset([1, 2, 3])) == '[1, 2, 3]' def test_decimal(): assert encode(Decimal('2.5') == '2.5') def test_datetime(): assert encode(date(1917, 10, 25)) == '"1917-10-25"' assert encode(datetime(1917, 10, 25, 21, 45)) == '"1917-10-25 21:45:00"' def test_specific_json(): a = Foo("baz") encoded = encode(a) assert encoded == '"foo-baz"' def test_specific_in_list(): a = Foo("baz") d = [a] encoded = encode(d) assert encoded == '["foo-baz"]' def test_specific_in_dict(): a = Foo("baz") d = {"a": a} encoded = encode(d) assert encoded == '{"a": "foo-baz"}' def test_no_specific_json(): b = Baz() try: encoded = encode(b) except Exception, e: encoded = e.__class__.__name__ assert encoded == 'NoApplicableMethods' def test_exlicit_json(): b = Bar("bq") encoded = encode(b) assert encoded == '"bar-bq"' def test_exlicit_json_in_list(): b = Bar("bq") d = [b] encoded = encode(d) assert encoded == '["bar-bq"]' def test_exlicit_json_in_dict(): b = Bar("bq") d = {"b": b} encoded = encode(d) assert encoded == '{"b": "bar-bq"}' TurboJson-1.3.2/turbojson/jsonify.py0000644000175000017500000001344011617562574016220 0ustar citocito"""JSON encoding functions using PEAK-Rules.""" from datetime import date, datetime from decimal import Decimal from peak.rules import abstract, around, when # simplejson is actually available as json in the standard library # since Python 2.6, but the externally maintained package is newer # and can be substantially faster, so we try to import this first try: from simplejson import JSONEncoder # externally maintained version except ImportError: from json import JSONEncoder # standard lib version __all__ = ['jsonify', 'encode', 'encode_iter'] # Global options descent_bases = True # Specific encoding functions def jsonify(obj): """Generic function for converting objects to JSON. Specific functions should return a string or an object that can be serialized with JSON, i.e., it is made up of only lists, dictionaries (with string keys), strings, ints, and floats. """ return jsonify_default(obj) # This is for easier usage and backward compatibility: jsonify.when = when.__get__(jsonify) jsonify.around = around.__get__(jsonify) # Explicit encoding function @jsonify.around("hasattr(obj, '__json__')") def jsonify_explicit(obj): """JSONify objects with explicit JSONification method.""" return obj.__json__() # Default encoding functions @abstract def jsonify_default(obj): """Default JSONify method for Python objects.""" return NotImplementedError jsonify_default.when = when.__get__(jsonify_default) jsonify_default.around = around.__get__(jsonify_default) @jsonify_default.when("obj is None" " or isinstance(obj, (basestring, bool, int, long, float, list, dict))") def jsonify_serializable(obj): """JSONify simple serializable objects.""" return obj @jsonify_default.when("isinstance(obj, (set, frozenset, tuple))") def jsonify_list_like(obj): """JSONify simple list-like objects.""" return list(obj) @jsonify_default.when("isinstance(obj, Decimal)") def jsonify_decimal(obj): """JSONify Decimal objects.""" return float(obj) @jsonify.when("isinstance(obj, (date, datetime))") def jsonify_datetime(obj): """JSONify date and datetime objects.""" return str(obj) # SQLObject support try: from sqlobject import SQLObject def _sqlobject_attrs(obj): """Get all attributes of an SQLObject.""" sm = obj.__class__.sqlmeta try: while sm is not None: # we need to exclude the ID-keys, as for some reason # this won't work for subclassed items for key in sm.columns: if key[-2:] != 'ID': yield key sm = descent_bases and sm.__base__ or None except AttributeError: # happens if we descent to pass def is_sqlobject(obj): return (isinstance(obj, SQLObject) and hasattr(obj.__class__, 'sqlmeta')) @jsonify_default.when("is_sqlobject(obj)") def jsonify_sqlobject(obj): """JSONify SQLObjects.""" result = {'id': obj.id} for name in _sqlobject_attrs(obj): result[name] = getattr(obj, name) return result try: SelectResultsClass = SQLObject.SelectResultsClass except AttributeError: pass else: @jsonify_default.when("isinstance(obj, SelectResultsClass)") def jsonify_select_results(obj): """JSONify SQLObject.SelectResults.""" return list(obj) except ImportError: pass # SQLAlchemy support try: import sqlalchemy try: import sqlalchemy.ext.selectresults from sqlalchemy.util import OrderedProperties except ImportError: # SQLAlchemy >= 0.5 def is_saobject(obj): return hasattr(obj, '_sa_class_manager') @jsonify_default.when("is_saobject(obj)") def jsonify_saobject(obj): """JSONify SQLAlchemy objects.""" props = {} for key in obj.__dict__: if not key.startswith('_sa_'): props[key] = getattr(obj, key) return props else: # SQLAlchemy < 0.5 def is_saobject(obj): return (hasattr(obj, 'c') and isinstance(obj.c, OrderedProperties)) @jsonify_default.when("is_saobject(obj)") def jsonify_saobject(obj): """JSONify SQLAlchemy objects.""" props = {} for key in obj.c.keys(): props[key] = getattr(obj, key) return props try: from sqlalchemy.orm.attributes import InstrumentedList except ImportError: # SQLAlchemy >= 0.4 pass # normal lists are used here else: # SQLAlchemy < 0.4 @jsonify_default.when("isinstance(obj, InstrumentedList)") def jsonify_instrumented_list(obj): """JSONify SQLAlchemy instrumented lists.""" return list(obj) from sqlalchemy.engine.base import ResultProxy, RowProxy @jsonify_default.when("isinstance(obj, ResultProxy)") def jsonify_saproxy(obj): return list(obj) @jsonify_default.when("isinstance(obj, RowProxy)") def jsonify_saproxy(obj): return dict(obj) except ImportError: pass # JSON encoder class class GenericJSON(JSONEncoder): def __init__(self, **opts): opt = opts.pop('descent_bases', None) if opt is not None: global descent_bases descent_bases = opt super(GenericJSON, self).__init__(**opts) def default(self, obj): return jsonify(obj) _instance = GenericJSON() # General encoding functions def encode(obj): """Return a JSON string representation of a Python object.""" return _instance.encode(obj) def encode_iter(obj): """Encode object, yielding each string representation as available.""" return _instance.iterencode(obj) TurboJson-1.3.2/turbojson/jsonsupport.py0000644000175000017500000000244611617562574017151 0ustar citocito"""Template support for JSON""" from turbojson.jsonify import GenericJSON __all__ = ['JsonSupport'] class JsonSupport(object): encoding = 'utf-8' def __init__(self, extra_vars_func=None, options=None): opts = {} for option in options: if not option.startswith('json.'): continue opt = option[5:] if opt == 'encoding': self.encoding = options[option] or self.encoding else: if opt == 'assume_encoding': opt = 'encoding' opts[opt] = options[option] self.encoder = GenericJSON(**opts) def render(self, info, format=None, fragment=False, template=None): """Renders data in the desired format. @param info: the data itself @type info: dict @param format: not used @type format: string @param fragment: not used @type fragment: bool @param template: not used @type template: string """ for item in info.keys(): if item.startswith('tg_') and item != 'tg_flash': del info[item] output = self.encoder.encode(info) if isinstance(output, unicode): output = output.encode(self.encoding) return output TurboJson-1.3.2/turbojson/__init__.py0000644000175000017500000000013611617562574016274 0ustar citocito# TurboJson package from turbojson.jsonsupport import JsonSupport __all__ = ['JsonSupport'] TurboJson-1.3.2/setup.cfg0000644000175000017500000000020111617562645013747 0ustar citocito[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 [aliases] release = egg_info -RDb "" sdist bdist_egg register upload TurboJson-1.3.2/TurboJson.egg-info/0000755000175000017500000000000011617562645015554 5ustar citocitoTurboJson-1.3.2/TurboJson.egg-info/requires.txt0000644000175000017500000000006111617562645020151 0ustar citocitoPEAK-Rules >= 0.5a1.dev-r2600 simplejson >= 1.9.1TurboJson-1.3.2/TurboJson.egg-info/dependency_links.txt0000644000175000017500000000000111617562645021622 0ustar citocito TurboJson-1.3.2/TurboJson.egg-info/PKG-INFO0000644000175000017500000000131611617562645016652 0ustar citocitoMetadata-Version: 1.0 Name: TurboJson Version: 1.3.2 Summary: Python template plugin that supports JSON Home-page: http://docs.turbogears.org/TurboJson Author: TurboGears project Author-email: turbogears@googlegroups.com License: MIT Download-URL: http://pypi.python.org/pypi/TurboJson Description: UNKNOWN Keywords: python.templating.engines,turbogears Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Framework :: TurboGears Classifier: Environment :: Web Environment :: Buffet Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Software Development :: Libraries :: Python Modules TurboJson-1.3.2/TurboJson.egg-info/zip-safe0000644000175000017500000000000111617562645017204 0ustar citocito TurboJson-1.3.2/TurboJson.egg-info/top_level.txt0000644000175000017500000000001211617562645020277 0ustar citocitoturbojson TurboJson-1.3.2/TurboJson.egg-info/entry_points.txt0000644000175000017500000000012111617562645021044 0ustar citocito [python.templating.engines] json = turbojson.jsonsupport:JsonSupport TurboJson-1.3.2/TurboJson.egg-info/SOURCES.txt0000644000175000017500000000073011617562645017440 0ustar citocitoREADME.txt release_howto.txt setup.cfg setup.py TurboJson.egg-info/PKG-INFO TurboJson.egg-info/SOURCES.txt TurboJson.egg-info/dependency_links.txt TurboJson.egg-info/entry_points.txt TurboJson.egg-info/requires.txt TurboJson.egg-info/top_level.txt TurboJson.egg-info/zip-safe turbojson/__init__.py turbojson/jsonify.py turbojson/jsonsupport.py turbojson/tests/__init__.py turbojson/tests/test_jsonify.py turbojson/tests/test_sqlalchemy.py turbojson/tests/test_sqlobject.py