source: mauRepo/MolesManager/trunk/src/MolesManager/djencoder.py @ 8480

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/MolesManager/trunk/src/MolesManager/djencoder.py@8480
Revision 8480, 2.7 KB checked in by mnagni, 8 years ago (diff)

Fixed a bug in objectEncoding

RevLine 
[8088]1'''
2Created on 9 Feb 2012
3
4@author: mnagni
5'''
6from json.encoder import JSONEncoder
[8143]7import re
[8221]8import logging
[8480]9import inspect
[8088]10
11class DJEncoder(JSONEncoder):
[8143]12
[8221]13    log = logging.getLogger('DJEncoder')
[8088]14   
15    def __init__(self):
16        self.__markers = {}
17        super(DJEncoder, self).__init__()
[8143]18        self.__pattern = re.compile('\D\D__*')
19        self.__pattern2 = re.compile('\A\w+__id\Z')
20       
21
[8088]22    def default(self, obj):
23        # Convert objects to a dictionary of their representation
24        d = { '__module__':obj.__module__,
25              }
26        if obj.__class__.__name__ == 'EnumSymbol':
27            d['__class__'] = obj._cls.__name__
28        else:
29            d['__class__'] = obj.__class__.__name__
30           
31        if d['__module__'].startswith('sqlalchemy'):
32            return d
[8182]33
34        if d['__class__'] == 'Decimal':
35            d.update({'value': str(obj)})
36        else:   
37            for key in obj.__dict__.keys():
38                if not (key.startswith("_") or self.__pattern.match(key) or self.__pattern2.match(key)):
39                    d.update({key: getattr(obj, key)})
[8088]40        getters = list(methodsWithDecorator(type(obj), "property"))
41        for name in getters:
[8221]42            try:
43                d.update({name: getattr(obj, name)})
44            except Exception as e:
45                DJEncoder.log.error(e)
[8088]46       
47        for key, value in d.items():
48            if value is not None and id(value) in self.__markers and not isinstance(value, str) and not isinstance(value, int):
[8248]49                continue
50                #return {}
[8088]51            else:
[8335]52                if isinstance(value, str) or isinstance(value, unicode):                   
[8426]53                    self.__markers[id(value)] = escapeForJSON(value)
[8335]54                else:
55                    self.__markers[id(value)] = value
[8200]56        return d
[8426]57
[8480]58def methodsWithDecorator(cls, decoratorName):
59    #if type(cls).__name__ == 'type' or type(cls).__name__ == 'instancemetho':
60    #    return
61    sourcelines = inspect.getsourcelines(cls)[0]
62    for i,line in enumerate(sourcelines):
63        line = line.strip()
64        if line.split('(')[0].strip() == '@'+decoratorName: # leaving a bit out
65            nextLine = sourcelines[i+1]
66            name = nextLine.split('def')[1].split('(')[0].strip()
67            yield(name)
68
[8426]69def encodeToJSON(toEncode):
[8433]70    return DJEncoder().encode(toEncode)   
[8200]71   
[8426]72def escapeForJSON(toEscape):
73    res = toEscape.replace('"', '"')
74    res = res.replace("'", "'")       
75    #res = res.replace("'", "'")
76    res = res.replace('\\', '\\')
77    #res = res.replace('(', '(')       
78    #res = res.replace(')', ')')               
79    return res         
Note: See TracBrowser for help on using the repository browser.