aboutsummaryrefslogtreecommitdiff
path: root/template.py
diff options
context:
space:
mode:
Diffstat (limited to 'template.py')
-rwxr-xr-xtemplate.py369
1 files changed, 295 insertions, 74 deletions
diff --git a/template.py b/template.py
index 94dac8cf..a5b3119b 100755
--- a/template.py
+++ b/template.py
@@ -19,7 +19,7 @@
19# 19#
20# We import unicode_literals until people have understood how unicode 20# We import unicode_literals until people have understood how unicode
21# with bytes and strings changed in python2->python3. 21# with bytes and strings changed in python2->python3.
22from __future__ import unicode_literals 22# from __future__ import unicode_literals
23import os 23import os
24import os.path 24import os.path
25import sys 25import sys
@@ -29,6 +29,8 @@ import glob
29import codecs 29import codecs
30import jinja2 30import jinja2
31import i18nfix 31import i18nfix
32from pathlib import Path
33import hashlib
32 34
33# TODO: Turn repetition into a class. 35# TODO: Turn repetition into a class.
34 36
@@ -51,93 +53,312 @@ langs_full = {
51 "de": "Deutsch" 53 "de": "Deutsch"
52} 54}
53 55
54for in_file in glob.glob("template/*.j2"): 56# A construction has:
55 name, ext = re.match(r"(.*)\.([^.]+)$", in_file.rstrip(".j2")).groups() 57# symlinks (dict)
56 tmpl = env.get_template(in_file) 58# staticfiles (dict)
59# robot.txt files (list)
60# locales (list)
61# shells out to siteindex (todo: python siteindex)
62# generation_directories: the one we are building right now
63# the one we will be replacing
64# other directories get trashed upon successful build
57 65
58 def self_localized(other_locale): 66symlinks = {
59 """ 67 "frontpage.html": "frontpage",
60 Return URL for the current page in another locale. 68 "gsoc.html": "gsoc",
61 """ 69 "about.html": "philosophy",
62 return "../" + other_locale + "/" + in_file.replace('template/', 70 "gns.html": "gns",
63 '').rstrip(".j2") 71 "node/about.html": "397"
72}
64 73
65 def url_localized(filename): 74# Mostly from static/ to rendered/
66 return "../" + locale + "/" + filename 75staticfiles = {
76 "favicon.ico": "favicon.ico",
77 "moved.html": "frontpage.html",
78 "robots.txt": ["static", "dist", list(langs_full)],
79 "moved_gsoc.html": "gsoc.html",
80 "moved_about.html": "about.html",
81 "moved_gns.html": "gns.html"
82}
67 83
68 def svg_localized(filename): 84
69 lf = filename + "." + locale + ".svg" 85def localized(filename, locale, *args):
70 if locale == "en" or not os.path.isfile(lf): 86 if len(args) == 0:
71 return "../" + filename + ".svg" 87 return "../" + locale + "/" + filename
88 ext = kwargs.get('ext', None)
89 if ext is not None:
90 lf = filename + "." + locale + "." + ext
91 lp = Path(lf)
92 if locale == "en" or not lp.is_file():
93 return "../" + filename + "." + ext
72 else: 94 else:
73 return "../" + lf 95 return "../" + lf
74 96
75 def url(x):
76 # TODO: look at the app root environment variable
77 # TODO: check if file exists
78 return "../" + x
79 97
80 for l in glob.glob("locale/*/"): 98def fileop(infile, outfile, action):
81 locale = os.path.basename(l[:-1]) 99 """
100 infile: inputfile, Path object
101 outfile: outputfile, Path object
102 action: action if any, String
103 """
104 i = Path(infile)
105 o = Path(outfile)
106 outdir = Path("rendered")
107 if i.is_file() is not False:
108 if action == "copy":
109 # Write content of i to o.
110 o.write_text(i.read_text())
111 if action == "link":
112 o.symlink_to(i)
82 113
83 tr = gettext.translation("messages",
84 localedir="locale",
85 languages=[locale])
86 114
87 tr.gettext = i18nfix.wrap_gettext(tr.gettext) 115def write_name(filename, infile, locale, replacer):
116 return "./rendered/" + locale + "/" + infile.replace(replacer,
117 '').rstrip(".j2")
88 118
89 env.install_gettext_translations(tr, newstyle=True)
90 119
91 content = tmpl.render(lang=locale, 120def sha256sum(_):
92 lang_full=langs_full[locale], 121 sha256 = hashlib.sha256()
93 url=url, 122 with io.open(_, mode="rb") as fd:
94 self_localized=self_localized, 123 content = fd.read()
95 url_localized=url_localized, 124 sha256.update(content)
96 svg_localized=svg_localized, 125 return sha256.hexdigest()
97 filename=name + "." + ext)
98 out_name = "./rendered/" + locale + "/" + in_file.replace(
99 'template/', '').rstrip(".j2")
100 os.makedirs("./rendered/" + locale, exist_ok=True)
101 with codecs.open(out_name, "w", encoding='utf-8') as f:
102 f.write(content)
103 126
104 127
105for in_file in glob.glob("news/*.j2"): 128def walksum(_):
106 name, ext = re.match(r"(.*)\.([^.]+)$", in_file.rstrip(".j2")).groups() 129 sha256 = hashlib.sha256()
107 tmpl = env.get_template(in_file) 130 x = Path(_)
131 if not x.exists():
132 return -1
133 try:
134 for root, directories, files in os.walk(_):
135 for names in sorted(files):
136 filepath = os.path.join(root, names)
137 try:
138 fl = open(filepath, 'rb')
139 except:
140 fl.close()
141 continue
142 while 1:
143 buf = fl.read(4096)
144 if not buf:
145 break
146 sha256.update(hashlib.sha256(buf).hexdigest())
147 fl.close()
148 except:
149 import traceback
150 traceback.print_exc()
151 return -2
152 return sha256.hexdigest()
108 153
109 def self_localized(other_locale):
110 """
111 Return URL for the current page in another locale.
112 """
113 return "../" + other_locale + "/" + in_file.replace('news/',
114 '').rstrip(".j2")
115 154
116 def url_localized(filename): 155def rm_rf(directory):
117 return "../" + locale + "/" + filename 156 directory = Path(directory)
118 157 for child in directory.glob('*'):
119 def svg_localized(filename): 158 if child.is_file():
120 lf = filename + "." + locale + ".svg" 159 child.unlink()
121 if locale == "en" or not os.path.isfile(lf):
122 return "../" + filename + ".svg"
123 else: 160 else:
124 return "../" + lf 161 rm_rf(child)
162 directory.rmdir()
163
164
165# This generates and switches sites generations, preventing
166# in-place modification of the website.
167# * save old generation directory name
168# * jinja2 creates content in "rendered" (happened before calling this function)
169# * calculate sum of "rendered"
170# * move "rendered" to out/$sum
171# * remove symlink "html_dir"
172# * symlink out/$sum to "html_dir"
173# * delete old generation directory
174def generation_dir(htmldir):
175 oldgen = Path(htmldir).resolve()
176 # precondition: jinja2 has created the files in "rendered".
177 newgen = Path("rendered")
178 newgen_sum = walksum(newgen)
179 outdir = Path("out")
180 outdir.mkdir(parents=True, exist_ok=True)
181 newgen_target = Path("out") / newgen_sum
182 newgen.rename(newgen_target)
183 html = Path(htmldir)
184 html.unlink()
185 fileop(newgen, html, "link")
186 rm_rf(oldgen)
187
188
189def copy_static (locale, indict):
190 for key, value in indict.items():
191 print(locale + "/" + key + " ...to... " + locale + "/" + value)
192# fileop(in, out, "copy")
193
194# At this moment in time, constructing this list dynamically would be
195# too much pointless code. In fact all of what we use in jinja is
196# no real use of jinja yet and furthermore we would be better off
197# just using static html + css + some awk and other base tools.
198newsposts = [
199 {'page': '2019-0.11.8.html', 'date': '2019-10-30', 'title': 'GNUnet 0.11.8'},
200 {'page': '2019-0.11.7.html', 'date': '2019-10-27', 'title': 'GNUnet 0.11.7'},
201 {'page': '2019-10-ICANNPanel.html', 'date': '2019-10-20', 'title': 'ICANN Panel'},
202 {'page': '2019-10-GNSSpec1.html', 'date': '2019-10-04', 'title': 'GNS Spec 1'},
203 {'page': '2019-0.11.6.html', 'date': '2019-07-24', 'title': 'GNUnet 0.11.6'},
204 {'page': '2019-07-GHM_Aug_2019.html', 'date': '2019-07-17', 'title': 'GNUnet Hacker Meeting 2019'},
205 {'page': '2019-06-DSTJ.html', 'date': '2019-06-28', 'title': 'DSTJ'},
206 {'page': '2019-0.11.5.html', 'date': '2019-06-05', 'title': 'GNUnet 0.11.5'},
207 {'page': '2019-06.html', 'date': '2019-06-01', 'title': '2019-06'},
208 {'page': '2019-0.11.4.html', 'date': '2019-05-12', 'title': 'GNUnet 0.11.4'},
209 {'page': '2019-0.11.3.html', 'date': '2019-04-07', 'title': 'GNUnet 0.11.3'},
210 {'page': '2019-0.11.2.html', 'date': '2019-04-04', 'title': 'GNUnet 0.11.2'},
211 {'page': '2019-0.11.1.html', 'date': '2019-04-03', 'title': 'GNUnet 0.11.1'},
212 {'page': '2019-0.11.0.html', 'date': '2019-02-28', 'title': 'GNUnet 0.11.0'},
213 {'page': '2019-02.html', 'date': '2019-02-01', 'title': 'Google Summer of Code 2019'},
214]
215
216
217def generate_site(root):
218 for in_file in glob.glob(root + "/*.j2"):
219 name, ext = re.match(r"(.*)\.([^.]+)$", in_file.rstrip(".j2")).groups()
220 tmpl = env.get_template(in_file)
221
222 def self_localized(other_locale):
223 """
224 Return URL for the current page in another locale.
225 """
226 return "../" + other_locale + "/" + in_file.replace(
227 root + '/', '').rstrip(".j2")
228
229 def url_localized(filename):
230 if root == "news":
231 return "../../" + locale + "/" + filename
232 else:
233 return "../" + locale + "/" + filename
234
235 def url_static (filename):
236 if root == "news":
237 return "../../static/" + filename
238 else:
239 return "../static/" + filename
240
241 def url_dist (filename):
242 if root == "news":
243 return "../../dist/" + filename
244 else:
245 return "../dist/" + filename
246
247 def svg_localized(filename):
248 lf = filename + "." + locale + ".svg"
249 if locale == "en" or not os.path.isfile(lf):
250 return "../" + filename + ".svg"
251 else:
252 return "../" + lf
253
254 def url(x):
255 # TODO: look at the app root environment variable
256 # TODO: check if file exists
257 #if root == "news":
258 # return "../" + "../" + x
259 #else:
260 # return "../" + x
261 return "../" + x
262
263
264 for l in glob.glob("locale/*/"):
265 locale = os.path.basename(l[:-1])
266
267 tr = gettext.translation("messages",
268 localedir="locale",
269 languages=[locale])
270
271 tr.gettext = i18nfix.wrap_gettext(tr.gettext)
272
273 env.install_gettext_translations(tr, newstyle=True)
274
275 content = tmpl.render(lang=locale,
276 lang_full=langs_full[locale],
277 url=url,
278 newsdata=newsposts,
279 self_localized=self_localized,
280 url_localized=url_localized,
281 url_static=url_static,
282 url_dist=url_dist,
283 svg_localized=svg_localized,
284 filename=name + "." + ext)
285
286 if root == "news":
287 out_name = "./rendered/" + locale + "/" + root + "/" + in_file.replace(
288 root + '/', '').rstrip(".j2")
289 else:
290 out_name = "./rendered/" + locale + "/" + in_file.replace(
291 root + '/', '').rstrip(".j2")
292
293 outdir = Path("rendered")
294
295 if root == "news":
296 langdir = outdir / locale / root
297 else:
298 langdir = outdir / locale
299
300 langdir.mkdir(parents=True, exist_ok=True)
301 # os.makedirs("./rendered/" + locale, exist_ok=True)
302 with codecs.open(out_name, "w", encoding='utf-8') as f:
303 f.write(content)
304
305
306def main():
307 # rm_rf("rendered")
308 print("generating template")
309 generate_site("template")
310 print("generating news")
311 generate_site("news")
312# for l in glob.glob("locale/*/"):
313# locale = os.path.basename(l[:-1])
314# copy_static (locale, staticfiles)
315 # generate_rss
316 #print("running generation")
317 #generation_dir
318
319
320if __name__ == "__main__":
321 main()
322
323# for in_file in glob.glob("news/*.j2"):
324# name, ext = re.match(r"(.*)\.([^.]+)$", in_file.rstrip(".j2")).groups()
325# tmpl = env.get_template(in_file)
326
327# def self_localized(other_locale):
328# """
329# Return URL for the current page in another locale.
330# """
331# return "../" + other_locale + "/" + in_file.replace('news/',
332# '').rstrip(".j2")
333
334# def url_localized(filename):
335# return "../" + locale + "/" + filename
336
337# def svg_localized(filename):
338# lf = filename + "." + locale + ".svg"
339# if locale == "en" or not os.path.isfile(lf):
340# return "../" + filename + ".svg"
341# else:
342# return "../" + lf
343
344# def url(x):
345# # TODO: look at the app root environment variable
346# # TODO: check if file exists
347# return "../" + x
125 348
126 def url(x): 349# for f in glob.glob("locale/*/"):
127 # TODO: look at the app root environment variable 350# locale = os.path.basename(f[:-1])
128 # TODO: check if file exists 351# content = tmpl.render(lang=locale,
129 return "../" + x 352# lang_full=langs_full[locale],
130 353# url=url,
131 for f in glob.glob("locale/*/"): 354# self_localized=self_localized,
132 locale = os.path.basename(f[:-1]) 355# url_localized=url_localized,
133 content = tmpl.render(lang=locale, 356# svg_localized=svg_localized,
134 lang_full=langs_full[locale], 357# filename=name + "." + ext)
135 url=url, 358# out_name = "./rendered/" + locale + "/news/" + in_file.replace('news/', '').rstrip(".j2")
136 self_localized=self_localized, 359# outdir = Path("rendered")
137 url_localized=url_localized, 360# langdir = outdir / locale / "news"
138 svg_localized=svg_localized, 361# langdir.mkdir(parents=True, exist_ok=True)
139 filename=name + "." + ext) 362# # os.makedirs("./rendered/" + locale + "/news/", exist_ok=True)
140 out_name = "./rendered/" + locale + "/news/" + in_file.replace('news/', '').rstrip(".j2") 363# with codecs.open(out_name, "w", encoding='utf-8') as f:
141 os.makedirs("./rendered/" + locale + "/news/", exist_ok=True) 364# f.write(content)
142 with codecs.open(out_name, "w", encoding='utf-8') as f:
143 f.write(content)