8 from lxml.builder import ElementMaker
10 from pkg_resources import resource_filename, resource_listdir
13 import treecutter.constants as const
14 from treecutter.image import Image
15 #from treecutter.tools import warning
18 """Class representing a docbook document"""
19 def __init__(self,filename):
20 self._filename = filename
21 self._doc = etree.parse(self._filename)
22 self._dirname = os.path.dirname(self._filename)
25 t = self._doc.xpath(u'/db:article/db:info/db:title',namespaces=const.XPATH)
27 t = unicode(t[0].text)
28 ta = self._doc.xpath(u'/db:article/db:info/db:titleabbrev',namespaces=const.XPATH)
30 ta = unicode(ta[0].text)
34 status = self._doc.xpath(u'/db:article[@status]',namespaces=const.XPATH)
36 return unicode(status[0].get('status'))
40 art = self._doc.xpath(u'/db:article[@role]',namespaces=const.XPATH)
42 return unicode(art[0].get('role'))
46 lvl = self._doc.xpath(u'/db:article[@userlevel]',namespaces=const.XPATH)
48 lvlstr = unicode(lvl[0].get('userlevel'))
58 def expand_imageobjects(self):
60 db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
61 images = self._doc.xpath(u"//db:imageobject/db:imagedata[@fileref]",namespaces=const.XPATH)
63 os.chdir(self._dirname)
66 caption = db.caption()
67 for p in img.caption().split('\n\n'):
68 caption.append(db.para(p))
69 link = db.para(db.link(img.infostr(),
70 **{const.XLINK+"href": img.filename()}))
72 mo = db.mediaobject(db.imageobject(
73 db.imagedata(fileref=img.resize(800,600))),caption)
76 mopp = mop.getparent()
77 mopp.insert(mopp.index(mop)+1,mo)
82 def parse_xincludes(self):
84 for c in self._doc.xpath(u"//xi:include[@parse='text']",namespaces=const.XPATH):
86 alang = c.get('accept-language')
87 xpointer = c.get('xpointer')
88 (p, ext) = os.path.splitext(href)
89 if ext in const.valid_scripts:
91 script = os.path.join(os.path.abspath(self._dirname)+'/'+href)
92 if os.path.isfile(script) and os.access(script, os.X_OK):
95 if href in resource_listdir('xinclude', ''):
96 script = resource_filename('xinclude', href)
99 print "Script "+href+" in "+self._filename+" missing"
101 exe.append("lang="+alang)
103 exe.append("xptr="+xpointer)
106 print " executing %15s" % (href),
108 os.chdir(self._dirname)
109 xml = subprocess.Popen(exe,stdout=subprocess.PIPE,
110 stderr=subprocess.PIPE)
111 (stdout, stderr) = xml.communicate()
112 #print xml.returnvalue
114 # warning("%s : %s" % (" ".join(exe),stderr))
119 print " [%5.2f s] (%s)" % (round(te-ts,2),xpointer)
120 xstr = etree.fromstring(stdout)
121 # inserting the generated code and remove the xinclude reference
123 idp.insert(idp.index(c)+1,xstr)
129 def collect_links(self):
131 for r in self._doc.xpath(u"//db:link[@xlink:href]",namespaces=const.XPATH):
132 rf = os.path.join(self._dirname,r.get(const.XLINK+'href'))
133 if os.path.isfile(rf):
134 if r.get('security')=='encrypt':
135 with open(rf, 'rb') as f:
137 status = gpg.encrypt_file(
138 f, None, passphrase=getpass.getpass(rf+' password:'), symmetric=True,
140 r.set(const.XLINK+'href', r.get(const.XLINK+'href')+'.gpg')
145 def collect_images(self):
147 for i in self._doc.xpath(u"//db:imagedata[@fileref]",namespaces=const.XPATH):
148 im = os.path.join(self._dirname,i.get('fileref'))
149 if os.path.isfile(im):
152 print "WARNING: File "+im+" is missing!"
155 def collect_videos(self):
157 for i in self._doc.xpath(u"//db:videodata[@fileref]",namespaces=const.XPATH):
158 im = os.path.join(self._dirname,i.get('fileref'))
159 if os.path.isfile(im):
162 print "WARNING: File "+im+" is missing!"
165 def collect_forms(self):
167 for i in self._doc.xpath(u"//html:form[@action]",namespaces=const.XPATH):
168 pyscript = re.split('\.py',i.get('action'),1)[0]+'.py'
169 im = os.path.join(self._dirname,pyscript)
170 if os.path.isfile(im):
175 return etree.tostring(self._doc,encoding='UTF-8',pretty_print=False)
177 def xslt(self,transform):
178 return etree.tostring(transform(self._doc))
181 def recursively_empty(e):
184 return all((recursively_empty(c) for c in e.iterchildren()))
186 context = etree.iterwalk(self._doc)
187 for action, elem in context:
188 parent = elem.getparent()
189 if recursively_empty(elem):