1
2 """Read and create IPython-Notebooks
3 """
4
5 import json
6 from copy import deepcopy
7 from time import asctime
8
9 from PyFoam.Error import error,warning
10
11 from PyFoam.ThirdParty.six import string_types,text_type,u
14 """Class that represents an IPython-notebook in memory"""
15
16 - def __init__(self,input=None,
17 nbformat=3,
18 nbformat_minor=0,
19 name=None):
20 """@param input: If this is a string then it is interpreted as
21 a filename. Otherwise as a filehandle. If unset then an empty
22 notebook is contructed
23 @param name: name of the notebook. Only used if a new notebook is created
24 """
25 self.__content={}
26 if input==None:
27 if name==None:
28 error("Specify at least a name")
29 self.__content={
30 u("metadata") : {
31 u("name"):text_type(name),
32 u("pyFoam") : {
33 u("createdBy") : "pyFoam",
34 u("createdTime") : asctime()
35 }
36 },
37 u("nbformat") : nbformat,
38 u("nbformat_minor") : nbformat_minor,
39 u("worksheets") : [
40 {
41 u("cells"):[]
42 }
43 ]
44 }
45 else:
46 if isinstance(input,string_types):
47 fh=open(input)
48 else:
49 fh=input
50 self.__content=json.load(fh)
51 if ("metadata" not in self.__content or
52 "name" not in self.__content["metadata"] or
53 "nbformat" not in self.__content or
54 "worksheets" not in self.__content):
55 error(str(input),"Notebook does not have the expected format")
56 if len(self.__content["worksheets"])>1:
57 warning(str(input),"has more than one worksheet. Only using the first")
58 elif len(self.__content["worksheets"])==0:
59 error(str(input),"has no worksheets")
60 if "cells" not in self.__content["worksheets"][0]:
61 error(str(input),"has no cells")
62 self.reset([Cell(**c) for c in self])
63 if u("pyFoam") not in self.__content[u("metadata")]:
64 self.__content[u("metadata")][u("pyFoam")]={
65 u("createdBy") : "other",
66 u("createdTime") : "unknown"
67 }
68
69 @property
72
73 @property
75 return self.__content["metadata"]["name"]
76
77 @name.setter
78 - def name(self,newName):
79 self.__content["metadata"]["name"]=newName
80
82 return self.__content["worksheets"][0]["cells"]
83
85 self.__content["worksheets"][0]["cells"]=new
86
88 for c in self._cells():
89 yield c
90
93
95 data=Cell(**kwargs)
96 for ct in ["input","source"]:
97 if ct in data:
98 if isinstance(data[ct],string_types):
99 raw=[text_type(l) for l in data[ct].split("\n")]
100 data[ct]=[l+"\n" for l in raw[:-1]]+raw[-1:]
101 self._cells().append(data)
102
110
112 self.__addCell(cell_type=u("heading"),
113 source=title,
114 level=level,
115 **kwargs)
116
117 - def addCode(self,input,collapsed=False,language=u("python"),**kwargs):
118 self.__addCell(cell_type=u("code"),
119 collapsed=collapsed,
120 input=input,
121 language=text_type(language),
122 outputs=[],
123 **kwargs)
124
126 self.__addCell(cell_type=u("markdown"),
127 source=text,
128 **kwargs)
129
130 - def addRaw(self,text,**kwargs):
134
136 self.__content[u("metadata")][u("pyFoam")][u("modificationTime")]=asctime()
137 with open(fName,"w") as fh:
138 json.dump(self.__content,
139 fh,
140 indent=1)
141
143 """Wrapper for the dictionaries that represent notebook cells.
144 Mostly for conveniently querying metadata"""
145
146 - def __init__(self,classes=(),pyFoam={},**kwargs):
147 dict.__init__(self,deepcopy(kwargs))
148 if not u("metadata") in self:
149 self[u("metadata")]={}
150 if len(classes)>0 or len(pyFoam)>0:
151 py=deepcopy(pyFoam)
152 if not "pyFoam" in self[u("metadata")]:
153 self[u("metadata")]["pyFoam"]=py
154 else:
155 self[u("metadata")]["pyFoam"].update(py)
156 if len(classes)>0:
157 if isinstance(classes,string_types):
158 self[u("metadata")]["pyFoam"]["classes"]=(classes,)
159 else:
160 cl=deepcopy(classes)
161 self[u("metadata")]["pyFoam"]["classes"]=tuple(cl)
162
165
167 """Checks whether a cell is of a specific class. If a string is passed
168 the string is checked. Otherwise it is assumed that it is a container
169 and the """
170 try:
171 if isinstance(name,string_types):
172 return name in self[u("metadata")]["pyFoam"]["classes"]
173 else:
174 for n in name:
175 if n in self[u("metadata")]["pyFoam"]["classes"]:
176 return True
177 return False
178
179 except KeyError:
180 return False
181