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

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

Complete - # 22489: CEDA Observation Collection - phenomenonTime
 http://team.ceda.ac.uk/trac/ceda/ticket/22489
Incomplete - # 22531: CedaMoles3 MO_Party
 http://team.ceda.ac.uk/trac/ceda/ticket/22531

Many more unitests
Better structure for database operation (see MolesManager?.db.after_flux and moles3epb)
Documented many method but not updated docs folder

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