Display xpointer details to simplify debugging.
[treecutter.git] / treecutter / page.py
1 #!/usr/bin/python
2 import os
3 import subprocess
4 import tempfile
5 from amara import bindery
6 from amara.xslt import transform
7 from Cheetah.Template import Template
8 from pkg_resources import resource_filename, resource_listdir
9 from time import time
10 import treecutter.const as const
11 from treecutter.tools import mkdir_p
12
13 class Page():
14     """Class representing a version of a webpage"""
15     def __init__(self,link,page):
16         self._link = link
17         self._file = page[1]
18         self._lang = page[0]
19         self._doc = None
20         self._resources = []
21         self._title = None
22         self._menu = None
23         self._rendered_article = None
24
25     def language(self):
26         return self._lang
27
28     def resources(self):
29         return set(self._resources)
30
31     def menu(self):
32         return self._menu
33
34     def set_article(self,art):
35         self._rendered_article = art
36
37     def prepare(self):
38         self._doc = bindery.parse(self._file, prefixes=const.PREFIXES)
39         if self._doc.xml_select(u'/db:article/db:info/db:title'):
40             self._title = unicode(self._doc.article.info.title)
41         if self._doc.xml_select(u'/db:article/db:info/db:titleabbrev'):
42             self._menu = unicode(self._doc.article.info.titleabbrev)
43
44         dirname = os.path.dirname(self._file)
45         cwd = os.getcwd()
46         code  = self._doc.xml_select(u"//xi:include[@parse='text']")
47         if code:
48             for c in code:
49                 (p, ext) = os.path.splitext(c.href)
50                 if ext in const.valid_scripts:
51                     exe = []
52                     script = os.path.join(os.path.abspath(dirname)+'/'+c.href)
53                     if os.path.isfile(script):
54                         exe.append(script)
55                     else:
56                         if c.href in resource_listdir('xinclude', ''):
57                             script = resource_filename('xinclude', c.href)
58                             exe.append(script)
59                         else:
60                             print "Script "+c.href+" in "+self._file+" missing"
61                     if c.xml_select(u"//xi:include[@accept-language]"):
62                         alang = c.xml_attributes[None, "accept-language"]
63                         exe.append("lang="+alang)
64                     if c.xml_select(u"//xi:include[@xpointer]"):
65                         exe.append("xptr="+c.xpointer)
66                     print "  executing %15s" % (c.href),
67                     ts = time()
68                     os.chdir(dirname)
69                     xml = subprocess.Popen(exe,stdout=subprocess.PIPE)
70                     os.chdir(cwd)
71                     xmlblock = str(xml.stdout.read())
72                     te = time()
73                     print " [%5.2f s]  (%s)" % (round(te-ts,2),c.xpointer)
74                     xstr = bindery.parse(xmlblock)
75                     idp = c.xml_index_on_parent
76                     for x in xstr.xml_children:
77                         c.xml_parent.xml_insert(idp,x)
78                         c.xml_parent.xml_remove(c)
79
80         for r in self._doc.xml_select(u"//db:link[@xl:href]"):
81             rf = os.path.join(dirname,r.href)
82             if os.path.isfile(rf):
83                 self._resources.append(rf)
84         for i in self._doc.xml_select(u"//db:imagedata[@fileref]"):
85             im = os.path.join(dirname,i.fileref)
86             if os.path.isfile(im):
87                 self._resources.append(im)
88         for i in self._doc.xml_select(u"//html:form[@action]"):
89             pyscript = re.split('\.py',i.action,1)[0]+'.py'
90             im = os.path.join(dirname,pyscript)
91             if os.path.isfile(im):
92                 self._resources.append(im)
93
94     def render(self, style):
95         #  amara can not handle the docbook stylesheets
96         #  xmlarticle = transform(doc,style_xslt)
97         cwd = os.getcwd()
98         dirname = os.path.dirname(self._file)
99         os.chdir(dirname)
100         infile  = os.path.basename(tempfile.mktemp())
101         outfile = tempfile.mktemp()
102         tfi = open(infile,'w')
103         tfi.write(self._doc.xml_encode(omit_xml_declaration=True))
104         tfi.close()
105 #  cmd = ["saxon-xslt-xinclude","-o",outfile,infile,style_xslt]
106         cmd = ["xsltproc","--xinclude","--output",outfile,style+"docbook.xsl",infile]
107         retcode = subprocess.call(cmd)
108         if retcode:
109             print 'Error: '+' '.join(cmd)+' Returncode ['+str(retcode)+']'
110         tfo = open(outfile,'r')
111         self._rendered_article = tfo.read()
112         tfo.close()
113         os.remove(infile)
114         os.remove(outfile)
115         os.chdir(cwd)
116
117     def template(self,sitemap,style,tdir):
118         htmlmenu =  sitemap.gen_menu(self._lang,None,"menu")
119         levelmenu = sitemap.gen_menu(self._lang,self,"tree")
120         langmenu = sitemap.lang_menu(self._lang,self._link)
121         template = Template(file=style+'index.'+self._lang+'.html.tmpl',
122                             searchList=[{'title':self._title},
123                                         {'menu':htmlmenu},
124                                         {'article':self._rendered_article},
125                                         {'levelmenu':levelmenu},
126                                         {'langmenu':langmenu}])
127         outfile = tdir+'html'.join(self._file.rsplit('xml',1))
128         mkdir_p(os.path.dirname(outfile))
129         out = open(outfile, 'w')
130         out.write(str(template))
131         out.close()