1
2 """PermanentStorage
3
4 Store data permanently in the metadata of a notebook
5 """
6
7 from IPython.display import Javascript,display
8 from PyFoam.ThirdParty.six.moves import cPickle as pickle
9 import base64
10 from IPython.utils.py3compat import str_to_bytes, bytes_to_str
11 from time import sleep
12
14 """Access the stored values in the notebook
15
16 To make sure that only one object is created (so that multiple objects
17 can't interfer) it is created as a singleton. See:
18 A python singleton: http://code.activestate.com/recipes/52558/"""
19
20
21 _data={}
22
23
25 """Actual implementation of the storage """
26
27 __storePath="IPython.notebook.metadata.pyFoam.storedData"
28
29 __outputHandle="""
30 function handle_output(out){
31 console.log(out);
32 var res = null;
33 // if output is a print statement
34 if(out.msg_type == "stream"){
35 res = out.content.data;
36 }
37 // if output is a python object
38 else if(out.msg_type === "pyout"){
39 res = out.content.data["text/plain"];
40 }
41 // if output is a python error
42 else if(out.msg_type == "pyerr"){
43 res = out.content.ename + ": " + out.content.evalue;
44 }
45 // if output is something we haven't thought of
46 else{
47 res = "[out type not implemented]";
48 }
49 console.log(res);
50 }
51 var callbacks = {'iopub' : {'output' : handle_output}};
52 """
53
55 """Make sure that there is a subdictionary in the notebook-metadata"""
56 self.__autowrite=False
57 self.__autoread=True
58 display(Javascript(self.__outputHandle+"""
59 function ensurePyFoamStorage() {
60 if (typeof IPython =="undefined") {
61 alert("Trying to use PyFoam.IPythonHelpers.PermanentStorage outside of IPython");
62 return;
63 } else if(IPython.notebook==undefined) {
64 alert("Trying to use PyFoam.IPythonHelpers.PermanentStorage outside of an IPython-notebook");
65 return;
66 } else if(IPython.notebook.metadata.pyFoam==undefined) {
67 IPython.notebook.metadata.pyFoam=Object();
68 console.log("IPython.notebook.metadata.pyFoam created");
69 } else {
70 console.log("IPython.notebook.metadata.pyFoam found");
71 }
72 if(IPython.notebook.metadata.pyFoam.storedData==undefined) {
73 IPython.notebook.metadata.pyFoam.storedData=Object();
74 console.log("IPython.notebook.metadata.pyFoam.storedData created");
75 } else {
76 console.log("IPython.notebook.metadata.pyFoam.storedData found");
77 }
78
79 var store=IPython.notebook.metadata.pyFoam.storedData;
80 var expr="from PyFoam.IPythonHelpers.PermanentStorage import PermanentStorage as perm\\nperm._data={}";
81 status="Starting transfer";
82 var kernel=IPython.notebook.kernel;
83 kernel.execute(expr, callbacks, {silent:false});
84 for(var k in store) {
85 var totalLen=store[k].length;
86 console.log("Found stored "+k+" Length: "+totalLen);
87 // expr+="'"+k+"' : '"+store[k]+"' ,";
88 var chunk=400; // seems to be the best compromise
89 var nChunks=(totalLen/chunk|0)+1;
90 for(var i=0;i<nChunks;i++) {
91 status="chunk "+(i+1)+" of "+nChunks+" of "+k;
92 var value = store[k].substring(i*chunk,(i+1)*chunk);
93 var command ="perm._data['"+k+"']";
94 if(i>0) {
95 command+="+=";
96 } else {
97 command+="=";
98 }
99 command += "'"+value+"'";
100 kernel.execute(command);
101 }
102 }
103 status="Starting transfer (this can take some time)";
104 console.log("Execution of python done");
105 }
106 ensurePyFoamStorage();
107 """))
108 self.__displayModes()
109
111 try:
112 return pickle.loads(
113 bytes_to_str(base64.b64decode(str_to_bytes(
114 PermanentStorage._data[attr]))))
115 except TypeError as e:
116 return "TypeError: "+str(e)
117
119 """Set property in the metadata"""
120 pick=bytes_to_str(base64.b64encode(str_to_bytes(pickle.dumps(value))))
121 name=attr
122 PermanentStorage._data[attr]=pick
123 display(Javascript('%s["%s"]="%s";console.log("Setting %s");' % (self.__storePath,
124 name,
125 pick,
126 name)));
127
129 """Remove the property from the metadata"""
130 name=attr
131 del PermanentStorage._data[attr]
132 display(Javascript('delete %s.%s;console.log("Deleting %s");' % (self.__storePath,
133 name,name)));
134
137
140
143
146
148 """Get value or evaluate it.
149 @param name: name of the item to get/set
150 @param f: function to evaluate if the item is not present. If
151 item is not callable (strings for instance) it is set 'as-is'
152 @param call: Use f() if possible (otherwise f)"""
153 val=None
154 if self.__autoread:
155 try:
156 val=self[name]
157 except KeyError:
158 val=None
159 if val is None:
160 if hasattr(f,'__call__') and call:
161 val=f()
162 else:
163 val=f
164 if self.__autowrite:
165 self[name]=val
166 return val
167
169 msg="Storage status: Autowrite: "+str(self.__autowrite)+" Autoread: "+str(self.__autoread)
170 display(Javascript('status="'+msg+'"'))
171
173 """The ()-operator should automatically set the value in the metadata"""
174 self.__autowrite=True
175 self.__displayModes()
176
178 """The ()-operator should not automatically set the value in the metadata"""
179 self.__autowrite=False
180 self.__displayModes()
181
183 """The ()-operator should automatically get the value from the metadata"""
184 self.__autoread=True
185 self.__displayModes()
186
188 """The ()-operator should not automatically get the value from the metadata"""
189 self.__autoread=False
190 self.__displayModes()
191
192
193 __instance = None
194
204
206 """ Delegate access to implementation """
207 return getattr(self.__instance, attr)
208
210 """ Delegate access to implementation """
211 return setattr(self.__instance, attr, value)
212
216
220
224
228
232
235