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