]> git.ipfire.org Git - ipfire.org.git/blob - www/ipfire.py
Define "heading" XML tag to set as HTML-anchor
[ipfire.org.git] / www / ipfire.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 import os
5 import sys
6 import cgi
7
8 sys.path.append(os.environ['DOCUMENT_ROOT'])
9
10 import xml.dom.minidom
11
12 class Error404(Exception):
13 pass
14
15 class Error500(Exception):
16 pass
17
18 class SItem:
19 def __init__(self, xml, page, lang):
20 self.xml = xml
21 self.page = page
22 self.lang = lang
23
24 self.data = u""
25
26 def write(self, s):
27 self.data += s #.encode("utf-8")
28
29 def read(self):
30 return self.data
31
32
33 class Menu(SItem):
34 def __init__(self, file, page, lang):
35 SItem.__init__(self, Xml(file, lang), page, lang)
36 self.xml.load()
37
38 self.items = XItem(self.xml.dom).childs("Item")
39
40 def __call__(self):
41 self.write("""<div id="menu"><ul>""")
42 for item in self.items:
43 uri = item.attr("uri")
44 active = ""
45 if self.page == uri:
46 active = "class=\"active\""
47
48 if not uri.startswith("http://"):
49 uri = "/%s/%s" % (uri, self.lang)
50
51 for name in item.childs("Name"):
52 if name.attr("lang") in (self.lang, ""):
53 self.write("<li><a %s href=\"%s\">%s</a></li>" % \
54 (active, uri, name.text()))
55 self.write("</ul></div>")
56 return self.read()
57
58
59 class Body(SItem):
60 def __init__(self, xml, page, lang):
61 SItem.__init__(self, xml, page, lang)
62
63 self.paragraphs = XItem(self.xml.dom, "Paragraphs").childs("Paragraph")
64
65 self.news = News("news", self.page, self.lang)
66
67 def __call__(self):
68 self.write("""<div id="primaryContent_2columns">
69 <div id="columnA_2columns">""")
70 for paragraph in self.paragraphs:
71 for heading in paragraph.childs("Heading"):
72 if heading.attr("lang") in (self.lang, ""):
73 self.write('<h3>' + heading.text() + '</h3><a name="' + heading.text() +'"></a>')
74 for content in paragraph.childs("Content"):
75 if content.attr("lang") in (self.lang, ""):
76 if content.attr("raw"):
77 self.write(content.text())
78 else:
79 self.write("<p>" + content.text() + "</p>\n")
80 self.write("""<br class="clear" />\n""")
81
82 if self.page in ("index", "news",):
83 self.write(self.news(3))
84 self.write("""</div></div>""")
85 return self.read()
86
87
88 class News(SItem):
89 def __init__(self, file, page, lang):
90 SItem.__init__(self, Xml(file, lang), page, lang)
91 self.xml.load()
92
93 self.posts = XItem(self.xml.dom).childs("Posts")
94
95 def __call__(self, limit=None):
96 a = 1
97 for post in self.posts:
98 self.write("""<div class="post">""")
99 for id in post.childs("Id"):
100 self.write("""<a name="%s"></a>""" % id.text())
101 for heading in post.childs("Heading"):
102 if heading.attr("lang") in (self.lang, ""):
103 self.write("""<h3>%s - %s</h3>""" % (post.childs("Date")[0].text(), heading.text()))
104 for subtitle in post.childs("Subtitle"):
105 if subtitle.attr("lang") in (self.lang, ""):
106 self.write("""<ul class="post_info">
107 <li class="date">%s</li></ul>""" % \
108 subtitle.text())
109 for content in post.childs("Content"):
110 if content.attr("lang") in (self.lang, ""):
111 if content.attr("raw"):
112 self.write(content.text())
113 else:
114 self.write("<p>" + content.text() + "</p>\n")
115 self.write("""</div>""")
116 a += 1
117 if limit and a > limit:
118 break
119 return self.read()
120
121
122 class Sidebar(SItem):
123 def __init__(self, xml, page, lang):
124 SItem.__init__(self, xml, page, lang)
125
126 self.paragraphs = XItem(self.xml.dom, "Sidebar").childs("Paragraph")
127
128 def __call__(self):
129 self.write("""<div id="secondaryContent_2columns">
130 <div id="columnC_2columns">""")
131 for post in self.paragraphs:
132 for heading in post.childs("Heading"):
133 if heading.attr("lang") in (self.lang, ""):
134 self.write("<h4>" + heading.text() + "</h4>")
135 for content in post.childs("Content"):
136 if content.attr("lang") in (self.lang, ""):
137 if content.attr("raw"):
138 self.write(content.text())
139 else:
140 self.write("<p>" + content.text() + "</p>\n")
141 self.write("""</div></div>""")
142 return self.read()
143
144
145 class XItem:
146 def __init__(self, dom, node=None):
147 self.dom = self.node = dom
148 if node:
149 self.node = self.dom.getElementsByTagName(node)[0]
150 self.lang = lang
151
152 def attr(self, name):
153 return self.node.getAttribute(name).strip()
154
155 def text(self):
156 ret = ""
157 for i in self.node.childNodes:
158 ret = ret + i.data
159 return ret
160
161 def element(self, name):
162 return XItem(self.node, name)
163
164 def childs(self, name):
165 ret = []
166 for i in self.node.getElementsByTagName(name):
167 ret.append(XItem(i))
168 return ret
169
170
171 class Xml:
172 def __init__(self, page, lang):
173 self.page = page
174 self.lang = lang
175
176 self.path = None
177
178 self.data = None
179 self.dom = None
180
181 self._config = {}
182
183 def load(self):
184 self.path = \
185 os.path.join(os.path.dirname(os.environ['SCRIPT_FILENAME']), "data/%s.xml" % self.page)
186 try:
187 f = open(self.path)
188 self.data = f.read()
189 f.close()
190 self.dom = \
191 xml.dom.minidom.parseString(self.data).getElementsByTagName("Site")[0]
192 #except IOError:
193 #self.page = "404"
194 #self.load()
195 # raise Error404
196 except:
197 #self.page = "500"
198 #self.load()
199 raise
200
201 def config(self):
202 elements = ("Title", "Columns",)
203 for element in elements:
204 self._config[element.lower()] = ""
205
206 config = XItem(self.dom, "Config")
207 for element in elements:
208 for lang in config.childs(element):
209 if lang.attr("lang") == self.lang:
210 self._config[element.lower()] = lang.text()
211 return self._config
212
213
214 class Site:
215 def __init__(self, page, lang="en"):
216 self.code = "200 - OK"
217 self.mime = "text/html"
218
219 self.page = page
220 self.lang = lang
221 self.xml = Xml(page=page, lang=lang)
222
223 self.data = u""
224
225 self.menu = Menu("../menu", self.page, self.lang)
226
227 self.config = { "document_name" : page,
228 "lang" : self.lang,
229 "menu" : self.menu() }
230
231 try:
232 self.xml.load()
233 except Error404:
234 self.code = "404 - Not found"
235 #except:
236 # self.code = "500 - Internal Server Error"
237
238 def write(self, s):
239 self.data += s #.encode("utf-8")
240
241 def include(self, file):
242 f = open(file)
243 data = f.read()
244 f.close()
245 self.write(data % self.config)
246
247 def prepare(self):
248 for key, val in self.xml.config().items():
249 self.config[key] = val
250
251 self.config["title"] = "%s - %s" % \
252 (os.environ["SERVER_NAME"], self.config["title"],)
253
254 self.body = Body(self.xml, self.page, self.lang)
255 self.sidebar = Sidebar(self.xml, self.page, self.lang)
256
257 def run(self):
258 # First, return the http header
259 print "Status: %s" % self.code
260 print "Content-Type: %s" % self.mime
261 print # End header
262
263 # Include the site's header
264 self.include("header.inc")
265
266 # Import body and side elements
267 self.write(self.body())
268 self.write(self.sidebar())
269
270 # Include the site's footer
271 self.include("footer.inc")
272
273 return self.data.encode("utf-8")
274
275
276 page = cgi.FieldStorage().getfirst("page")
277 lang = cgi.FieldStorage().getfirst("lang")
278
279 if not lang:
280 lang = "en"
281
282 site = Site(page=page, lang=lang)
283 site.prepare()
284
285 print site.run()