1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
from common import *
import json
DUMPABLE_CLASSES_BY_NAME = {}
DUMPABLE_CLASS_NAMES = {}
DUMPABLE_PROXIES = {}
LOADABLE_PROXIES = {}
def dumpClassAs(cls, name=None):
def __add_it(function):
DUMPABLE_PROXIES[cls] = (name, function)
return function
return __add_it
def loadClassFrom(name):
def __add_it(function):
LOADABLE_PROXIES[name] = function
return function
return __add_it
def dumpable(name):
def __add_it(cls):
DUMPABLE_CLASSES_BY_NAME[name] = cls
DUMPABLE_CLASS_NAMES[cls] = name
return cls
return __add_it
def dump(rootObj):
def _dumpPiece(piece):
try:
clsObj = type(piece)
clsName = DUMPABLE_CLASS_NAMES[clsObj]
except KeyError:
# let's give this one more shot with the dumpable proxies
try:
dumpName, dumpFunc = DUMPABLE_PROXIES[clsObj]
except KeyError:
return piece
dest = dumpFunc(piece)
if dumpName is not None:
dest['_t'] = dumpName
return dest
dest = {'_t': clsName}
for attrName in clsObj.__dump_attribs__:
dest[attrName] = getattr(piece, attrName)
if hasattr(piece, '_dump'):
piece._dump(rootObj, dest)
return dest
return json.dumps(rootObj, default=_dumpPiece)
def load(string):
needsSpecialCare = []
def _loadObject(source):
try:
clsName = source['_t']
clsObj = DUMPABLE_CLASSES_BY_NAME[clsName]
print "Loading %s" % clsName
except KeyError:
# let's give this one more shot with the loadable proxies
try:
loadFunc = LOADABLE_PROXIES[clsName]
except KeyError:
return source
return loadFunc(source)
obj = clsObj()
for attrName in clsObj.__dump_attribs__:
setattr(obj, attrName, source[attrName])
if hasattr(obj, '_preload'):
obj._preload(source)
if hasattr(obj, '_load'):
needsSpecialCare.append((obj, source))
return obj
root = json.loads(string, object_hook=_loadObject)
for obj, source in needsSpecialCare:
obj._load(root, source)
return root
@dumpClassAs(QtGui.QPixmap, 'pixmap')
def dumpPixmap(pm):
buf = QtCore.QBuffer()
buf.open(buf.WriteOnly)
pm.save(buf, 'PNG')
data = str(buf.data())
buf.close()
return {'png': base64.b64encode(data)}
@loadClassFrom('pixmap')
def loadPixmap(source):
pm = QtGui.QPixmap()
pm.loadFromData(base64.b64decode(source['png']), 'PNG')
return pm
@dumpClassAs(QtCore.QString)
def dumpQString(string):
return str(string)
|