source: mauRepo/MolesManager/trunk/cedaMoles/MolesManager/djencoder.py @ 8569

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/MolesManager/trunk/cedaMoles/MolesManager/djencoder.py@8569
Revision 8569, 2.8 KB checked in by mnagni, 7 years ago (diff)

Complete - # 22551: List resources / display single file
 http://team.ceda.ac.uk/trac/ceda/ticket/22551

fixes an error on parsing datatime module

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        # Convert objects to a dictionary of their representation
24        d = {}
25        try:
26            d = { '__module__':obj.__module__,
27                 }
28        except Exception as e:
29            print e
30            return d
31        if obj.__class__.__name__ == 'EnumSymbol':
32            d['__class__'] = obj._cls.__name__
33        else:
34            d['__class__'] = obj.__class__.__name__
35           
36        if d['__module__'].startswith('sqlalchemy'):
37            return d
38
39        if d['__class__'] == 'Decimal':
40            d.update({'value': str(obj)})
41        else:   
42            for key in obj.__dict__.keys():
43                if not (key.startswith("_") or self.__pattern.match(key) or self.__pattern2.match(key)):
44                    d.update({key: getattr(obj, key)})
45        getters = list(methodsWithDecorator(type(obj), "property"))
46        for name in getters:
47            try:
48                d.update({name: getattr(obj, name)})
49            except Exception as e:
50                DJEncoder.log.error(e)
51       
52        for key, value in d.items():
53            if value is not None and id(value) in self.__markers and not isinstance(value, str) and not isinstance(value, int):
54                continue
55                #return {}
56            else:
57                self.__markers[id(value)] = value
58                if isinstance(value, str) or isinstance(value, unicode):                   
59                    self.__markers[id(value)] = escapeForJSON(value)
60                else:
61                    self.__markers[id(value)] = value
62        return d
63
64def methodsWithDecorator(cls, decoratorName):
65    #if type(cls).__name__ == 'type' or type(cls).__name__ == 'instancemetho':
66    #    return
67    sourcelines = inspect.getsourcelines(cls)[0]
68    for i,line in enumerate(sourcelines):
69        line = line.strip()
70        if line.split('(')[0].strip() == '@'+decoratorName: # leaving a bit out
71            nextLine = sourcelines[i+1]
72            name = nextLine.split('def')[1].split('(')[0].strip()
73            yield(name)
74
75def encodeToJSON(toEncode):
76    return DJEncoder().encode(toEncode)   
77   
78def escapeForJSON(toEscape):
79    res = toEscape.replace('"', '"')
80    res = res.replace("'", "'")       
81    #res = res.replace("'", "'")
82    res = res.replace('\\', '\\')
83    #res = res.replace('(', '(')       
84    #res = res.replace(')', ')')               
85    return res         
Note: See TracBrowser for help on using the repository browser.