Skip to content

Commit

Permalink
Merge pull request #3 from tony/whitespace
Browse files Browse the repository at this point in the history
Clean trailing whitespace
  • Loading branch information
Jon L committed Sep 19, 2012
2 parents 3af37b9 + 470499c commit d93bb11
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 196 deletions.
104 changes: 52 additions & 52 deletions dynamicresponse/emitters.py
Expand Up @@ -28,7 +28,7 @@ class Emitter(object):
usually the only method you want to use in your
emitter. See below for examples.
"""

EMITTERS = {}
RESERVED_FIELDS = set([
'read',
Expand All @@ -41,48 +41,48 @@ class Emitter(object):
'fields',
'exclude'
])

def __init__(self, payload, typemapper, handler, fields=(), anonymous=True):

self.typemapper = typemapper
self.data = payload
self.handler = handler
self.fields = fields
self.anonymous = anonymous

if isinstance(self.data, Exception):
raise

def method_fields(self, handler, fields):

if not handler:
return {}

ret = dict()
for field in fields - Emitter.RESERVED_FIELDS:
t = getattr(handler, str(field), None)

if t and callable(t):
ret[field] = t

return ret

def construct(self):
"""
Recursively serialize a lot of types, and
in cases where it doesn't recognize the type,
it will fall back to Django's `smart_unicode`.
Returns `dict`.
"""

def _any(thing, fields=()):
"""
Dispatch, all types are routed through here.
"""

ret = None

if isinstance(thing, QuerySet):
ret = _qs(thing, fields=fields)
elif isinstance(thing, Page):
Expand All @@ -106,59 +106,59 @@ def _any(thing, fields=()):
ret = _any(thing.all())
else:
ret = smart_unicode(thing, strings_only=True)

return ret

def _fk(data, field):
"""
Foreign keys.
"""

return _any(getattr(data, field.name))

def _related(data, fields=()):
"""
Foreign keys.
"""

return [ _model(m, fields) for m in data.iterator() ]

def _m2m(data, field, fields=()):
"""
Many to many (re-route to `_model`.)
"""

return [ _model(m, fields) for m in getattr(data, field.name).iterator() ]

def _model(data, fields=()):
"""
Models. Will respect the `fields` and/or
`exclude` on the handler (see `typemapper`.)
"""

ret = { }
handler = None

# Does the model implement get_serialization_fields() or serialize_fields()?
# We should only serialize these fields.
if hasattr(data, 'get_serialization_fields'):
fields = set(data.get_serialization_fields())
if hasattr(data, 'serialize_fields'):
fields = set(data.serialize_fields())

# Is the model a Django user instance?
# Ensure that only core (non-sensitive fields) are serialized
if isinstance(data, User):
fields = getattr(settings, 'DYNAMICRESPONSE_DJANGO_USER_FIELDS', ('id', 'email', 'first_name', 'last_name'))

# Should we explicitly serialize specific fields?
if fields:

v = lambda f: getattr(data, f.attname)

get_fields = set(fields)
met_fields = self.method_fields(handler, get_fields)

# Serialize normal fields
for f in data._meta.local_fields:
if f.serialize and not any([ p in met_fields for p in [ f.attname, f.name ]]):
Expand All @@ -170,20 +170,20 @@ def _model(data, fields=()):
if f.attname[:-3] in get_fields:
ret[f.name] = _fk(data, f)
get_fields.remove(f.name)

# Serialize many-to-many fields
for mf in data._meta.many_to_many:
if mf.serialize and mf.attname not in met_fields:
if mf.attname in get_fields:
ret[mf.name] = _m2m(data, mf)
get_fields.remove(mf.name)

# Try to get the remainder of fields
for maybe_field in get_fields:
if isinstance(maybe_field, (list, tuple)):
model, fields = maybe_field
inst = getattr(data, model, None)

if inst:
if hasattr(inst, 'all'):
ret[model] = _related(inst, fields)
Expand All @@ -192,14 +192,14 @@ def _model(data, fields=()):
ret[model] = _any(inst(), fields)
else:
ret[model] = _model(inst, fields)

elif maybe_field in met_fields:
# Overriding normal field which has a "resource method"
# so you can alter the contents of certain fields without
# using different names.
ret[maybe_field] = _any(met_fields[maybe_field](data))
else:

else:
maybe = getattr(data, maybe_field, None)
if maybe:
if callable(maybe):
Expand All @@ -209,51 +209,51 @@ def _model(data, fields=()):
ret[maybe_field] = _any(maybe)
else:
ret[maybe_field] = _any(maybe)

else:

for f in data._meta.fields:
if not f.attname.startswith('_'):
ret[f.attname] = _any(getattr(data, f.attname))

fields = dir(data.__class__) + ret.keys()
add_ons = [k for k in dir(data) if k not in fields]

for k in add_ons:
if not k.__str__().startswith('_'):
ret[k] = _any(getattr(data, k))

return ret

def _qs(data, fields=()):
"""
Querysets.
"""

return [ _any(v, fields) for v in data ]

def _list(data, fields=()):
"""
Lists.
"""

return [ _any(v, fields) for v in data ]

def _dict(data, fields=()):
"""
Dictionaries.
"""

return dict([ (k, _any(v, fields)) for k, v in data.iteritems() ])

# Kickstart the seralizin'.
return _any(self.data, self.fields)

def in_typemapper(self, model, anonymous):
for klass, (km, is_anon) in self.typemapper.iteritems():
if model is km and is_anon is anonymous:
return klass

def render(self):
"""
This super emitter does not implement `render`,
Expand All @@ -265,12 +265,12 @@ class JSONEmitter(Emitter):
"""
JSON emitter, understands timestamps.
"""

def render(self):

indent = 0
if settings.DEBUG:
indent = 4

seria = simplejson.dumps(self.construct(), cls=DateTimeAwareJSONEncoder, ensure_ascii=False, indent=indent)
return seria
3 changes: 1 addition & 2 deletions dynamicresponse/json_response.py
Expand Up @@ -7,9 +7,8 @@ class JsonResponse(HttpResponse):
"""
Provides a JSON response to a client, performing automatic serialization.
"""

def __init__(self, object=None, **kwargs):

# Perform JSON serialization
if object:
emitter = JSONEmitter(object, {}, None)
Expand Down

0 comments on commit d93bb11

Please sign in to comment.