|
@@ -11,12 +11,9 @@ import time
|
11
|
11
|
import codecs
|
12
|
12
|
from datetime import datetime
|
13
|
13
|
|
14
|
|
-DEFAULT_LANG = "en"
|
15
|
|
-BASE_URL = "https://www.xythobuz.de"
|
16
|
|
-
|
17
|
|
-# =============================================================================
|
|
14
|
+# -----------------------------------------------------------------------------
|
18
|
15
|
# Python 2/3 hacks
|
19
|
|
-# =============================================================================
|
|
16
|
+# -----------------------------------------------------------------------------
|
20
|
17
|
|
21
|
18
|
PY3 = sys.version_info[0] == 3
|
22
|
19
|
|
|
@@ -32,6 +29,50 @@ else:
|
32
|
29
|
return urlparse.parse_qs(urlparse.urlparse(link).query)['v'][0]
|
33
|
30
|
|
34
|
31
|
# -----------------------------------------------------------------------------
|
|
32
|
+# config "system"
|
|
33
|
+# -----------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+conf = {
|
|
36
|
+ "default_lang": "en",
|
|
37
|
+ "base_url": "https://www.xythobuz.de",
|
|
38
|
+
|
|
39
|
+ "birthday": datetime(1994, 1, 22, 0, 0),
|
|
40
|
+ "blog_years_back": 6,
|
|
41
|
+}
|
|
42
|
+
|
|
43
|
+def get_conf(name):
|
|
44
|
+ return conf[name]
|
|
45
|
+
|
|
46
|
+# -----------------------------------------------------------------------------
|
|
47
|
+# local vars for compatibility
|
|
48
|
+# -----------------------------------------------------------------------------
|
|
49
|
+
|
|
50
|
+DEFAULT_LANG = get_conf("default_lang")
|
|
51
|
+BASE_URL = get_conf("base_url")
|
|
52
|
+
|
|
53
|
+# -----------------------------------------------------------------------------
|
|
54
|
+# birthday calculation
|
|
55
|
+# -----------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+from datetime import timedelta
|
|
58
|
+from calendar import isleap
|
|
59
|
+
|
|
60
|
+size_of_day = 1. / 366.
|
|
61
|
+size_of_second = size_of_day / (24. * 60. * 60.)
|
|
62
|
+
|
|
63
|
+def date_as_float(dt):
|
|
64
|
+ days_from_jan1 = dt - datetime(dt.year, 1, 1)
|
|
65
|
+ if not isleap(dt.year) and days_from_jan1.days >= 31+28:
|
|
66
|
+ days_from_jan1 += timedelta(1)
|
|
67
|
+ return dt.year + days_from_jan1.days * size_of_day + days_from_jan1.seconds * size_of_second
|
|
68
|
+
|
|
69
|
+def difference_in_years(start_date, end_date):
|
|
70
|
+ return int(date_as_float(end_date) - date_as_float(start_date))
|
|
71
|
+
|
|
72
|
+def own_age():
|
|
73
|
+ return difference_in_years(get_conf("birthday"), datetime.now())
|
|
74
|
+
|
|
75
|
+# -----------------------------------------------------------------------------
|
35
|
76
|
# sub page helper macro
|
36
|
77
|
# -----------------------------------------------------------------------------
|
37
|
78
|
|
|
@@ -119,7 +160,7 @@ def githubCommitBadge(p, showInline = False):
|
119
|
160
|
ret += ".svg?logo=git&style=flat\" /></a>"
|
120
|
161
|
return ret
|
121
|
162
|
|
122
|
|
-def printMenuItem(p, yearsAsHeading = False, showDateSpan = False, showOnlyStartDate = False, nicelyFormatFullDate = False, lastyear = "0", lang = "", showLastCommit = True):
|
|
163
|
+def printMenuItem(p, yearsAsHeading = False, showDateSpan = False, showOnlyStartDate = False, nicelyFormatFullDate = False, lastyear = "0", lang = "", showLastCommit = True, hide_description = False, indent_count = 0, updates_as_heading = False):
|
123
|
164
|
title = p.title
|
124
|
165
|
if lang != "":
|
125
|
166
|
if p.get("title_" + lang, "") != "":
|
|
@@ -127,7 +168,10 @@ def printMenuItem(p, yearsAsHeading = False, showDateSpan = False, showOnlyStart
|
127
|
168
|
if title == "Blog":
|
128
|
169
|
title = p.post
|
129
|
170
|
|
130
|
|
- year = p.get("date", "")[0:4]
|
|
171
|
+ if updates_as_heading:
|
|
172
|
+ year = p.get("update", p.get("date", ""))[0:4]
|
|
173
|
+ else:
|
|
174
|
+ year = p.get("date", "")[0:4]
|
131
|
175
|
if year != lastyear:
|
132
|
176
|
lastyear = year
|
133
|
177
|
if yearsAsHeading:
|
|
@@ -146,14 +190,16 @@ def printMenuItem(p, yearsAsHeading = False, showDateSpan = False, showOnlyStart
|
146
|
190
|
if nicelyFormatFullDate:
|
147
|
191
|
dateto = " - " + datetime.strptime(p.get("update", p.date), "%Y-%m-%d").strftime("%B %d, %Y")
|
148
|
192
|
|
149
|
|
- print(" * **[%s](%s)**%s" % (title, p.url, dateto))
|
|
193
|
+ indent = " " * (indent_count + 1)
|
|
194
|
+ print(indent + "* **[%s](%s)**%s" % (title, p.url, dateto))
|
150
|
195
|
|
151
|
|
- if p.get("description", "") != "":
|
152
|
|
- description = p.get("description", "")
|
153
|
|
- if lang != "":
|
154
|
|
- if p.get("description_" + lang, "") != "":
|
155
|
|
- description = p.get("description_" + lang, "")
|
156
|
|
- print("<br><span class=\"listdesc\">" + description + "</span>")
|
|
196
|
+ if hide_description == False:
|
|
197
|
+ if p.get("description", "") != "":
|
|
198
|
+ description = p.get("description", "")
|
|
199
|
+ if lang != "":
|
|
200
|
+ if p.get("description_" + lang, "") != "":
|
|
201
|
+ description = p.get("description_" + lang, "")
|
|
202
|
+ print("<br><span class=\"listdesc\">" + description + "</span>")
|
157
|
203
|
|
158
|
204
|
if showLastCommit:
|
159
|
205
|
link = githubCommitBadge(p)
|
|
@@ -165,10 +211,13 @@ def printMenuItem(p, yearsAsHeading = False, showDateSpan = False, showOnlyStart
|
165
|
211
|
def printRecentMenu(count = 5):
|
166
|
212
|
posts = [p for p in pages if "date" in p and p.lang == "en"]
|
167
|
213
|
posts.sort(key=lambda p: p.get("update", p.get("date")), reverse=True)
|
|
214
|
+
|
168
|
215
|
if count > 0:
|
169
|
216
|
posts = posts[0:count]
|
|
217
|
+
|
|
218
|
+ lastyear = "0"
|
170
|
219
|
for p in posts:
|
171
|
|
- printMenuItem(p, False, False, False, True, "0", "", False)
|
|
220
|
+ lastyear = printMenuItem(p, count == 0, False, False, True, lastyear, "", False, False, 0, True)
|
172
|
221
|
|
173
|
222
|
def printBlogMenu(year_min=None, year_max=None):
|
174
|
223
|
posts = [p for p in pages if "post" in p and p.lang == "en"]
|
|
@@ -186,23 +235,44 @@ def printBlogMenu(year_min=None, year_max=None):
|
186
|
235
|
def printProjectsMenu():
|
187
|
236
|
# prints all pages with parent 'projects' or 'stuff'.
|
188
|
237
|
# first the ones without date, sorted by position.
|
|
238
|
+ # this first section includes sub-headings for children
|
189
|
239
|
# then afterwards those with date, split by year.
|
190
|
240
|
# also supports blog posts with parent.
|
191
|
241
|
enpages = [p for p in pages if p.lang == "en"]
|
192
|
242
|
|
|
243
|
+ # select pages without date
|
193
|
244
|
dpages = [p for p in enpages if p.get("date", "") == ""]
|
|
245
|
+ # only those that have a parent in ['projects', 'stuff']
|
194
|
246
|
mpages = [p for p in dpages if any(x in p.get("parent", "") for x in [ 'projects', 'stuff' ])]
|
|
247
|
+ # sort by position
|
195
|
248
|
mpages.sort(key=lambda p: [int(p.get("position", "999"))])
|
|
249
|
+ # print all pages
|
196
|
250
|
for p in mpages:
|
197
|
251
|
printMenuItem(p)
|
198
|
252
|
|
|
253
|
+ # print subpages for these top-level items
|
|
254
|
+ subpages = [sub for sub in enpages if sub.get("parent", "none") == p.get("child-id", "unknown")]
|
|
255
|
+ for sp in subpages:
|
|
256
|
+ printMenuItem(sp, False, True, True, False, "0", "", False, True, 1)
|
|
257
|
+
|
|
258
|
+ # slect pages with a date
|
199
|
259
|
dpages = [p for p in enpages if p.get("date", "") != ""]
|
|
260
|
+ # only those that have a parent in ['projects', 'stuff']
|
200
|
261
|
mpages = [p for p in dpages if any(x in p.get("parent", "") for x in [ 'projects', 'stuff' ])]
|
|
262
|
+ # sort by date
|
201
|
263
|
mpages.sort(key=lambda p: [p.get("date", "9999-01-01")], reverse = True)
|
|
264
|
+
|
|
265
|
+ # print all pages
|
202
|
266
|
lastyear = "0"
|
203
|
267
|
for p in mpages:
|
204
|
268
|
lastyear = printMenuItem(p, True, True, False, False, lastyear)
|
205
|
269
|
|
|
270
|
+ # print subpages for these top-level items
|
|
271
|
+ subpages = [sub for sub in enpages if sub.get("parent", "none") == p.get("child-id", "unknown")]
|
|
272
|
+ subpages.sort(key=lambda p: [p.get("date", "9999-01-01")], reverse = True)
|
|
273
|
+ for sp in subpages:
|
|
274
|
+ printMenuItem(sp, False, True, True, False, "0", "", False, True, 1)
|
|
275
|
+
|
206
|
276
|
def print3DPrintingMenu():
|
207
|
277
|
mpages = [p for p in pages if p.get("parent", "") == "3d-printing" and p.lang == "en"]
|
208
|
278
|
mpages.sort(key=lambda p: int(p["position"]))
|
|
@@ -487,9 +557,9 @@ def hook_preconvert_anotherlang():
|
487
|
557
|
langs.append(lang)
|
488
|
558
|
|
489
|
559
|
if lang == "en":
|
490
|
|
- filename = re.sub(MKD_PATT, "%s\g<0>" % "", p.fname).split(os.path.sep)[-1]
|
|
560
|
+ filename = re.sub(MKD_PATT, r"%s\g<0>" % "", p.fname).split(os.path.sep)[-1]
|
491
|
561
|
else:
|
492
|
|
- filename = re.sub(MKD_PATT, ".%s\g<0>" % lang, p.fname).split(os.path.sep)[-1]
|
|
562
|
+ filename = re.sub(MKD_PATT, r".%s\g<0>" % lang, p.fname).split(os.path.sep)[-1]
|
493
|
563
|
|
494
|
564
|
vp = Page(filename, virtual=text)
|
495
|
565
|
# Copy real page attributes to the virtual page
|
|
@@ -746,6 +816,6 @@ def hook_postconvert_size():
|
746
|
816
|
except:
|
747
|
817
|
print("Unable to estimate file size for %s" % matchobj.group(1))
|
748
|
818
|
return '<a href=\"%s\">%s</a>' % (matchobj.group(1), matchobj.group(3))
|
749
|
|
- _re_url = '<a href=\"([^\"]*?\.(%s))\">(.*?)<\/a>' % file_ext
|
|
819
|
+ _re_url = r'<a href=\"([^\"]*?\.(%s))\">(.*?)<\/a>' % file_ext
|
750
|
820
|
for p in pages:
|
751
|
821
|
p.html = re.sub(_re_url, matched_link, p.html)
|