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