My static website generator using poole https://www.xythobuz.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import re
  2. import itertools
  3. import email.utils
  4. import os.path
  5. import time
  6. from datetime import datetime
  7. DEFAULT_LANG = "en"
  8. BASE_URL = "http://www.xythobuz.de"
  9. # -----------------------------------------------------------------------------
  10. # preconvert hooks
  11. # -----------------------------------------------------------------------------
  12. def hook_preconvert_anotherlang():
  13. MKD_PATT = r'\.(?:md|mkd|mdown|markdown)$'
  14. _re_lang = re.compile(r'^[\s+]?lang[\s+]?[:=]((?:.|\n )*)', re.MULTILINE)
  15. vpages = [] # Set of all virtual pages
  16. for p in pages:
  17. current_lang = DEFAULT_LANG # Default language
  18. langs = [] # List of languages for the current page
  19. page_vpages = {} # Set of virtual pages for the current page
  20. text_lang = re.split(_re_lang, p.source)
  21. text_grouped = dict(zip([current_lang,] + \
  22. [lang.strip() for lang in text_lang[1::2]], \
  23. text_lang[::2]))
  24. for lang, text in text_grouped.iteritems():
  25. spath = p.fname.split(os.path.sep)
  26. langs.append(lang)
  27. if lang == "en":
  28. filename = re.sub(MKD_PATT, "%s\g<0>" % "", p.fname).split(os.path.sep)[-1]
  29. else:
  30. filename = re.sub(MKD_PATT, ".%s\g<0>" % lang, p.fname).split(os.path.sep)[-1]
  31. vp = Page(filename, virtual=text)
  32. # Copy real page attributes to the virtual page
  33. for attr in p:
  34. if not vp.has_key(attr):
  35. vp[attr] = p[attr]
  36. # Define a title in the proper language
  37. vp["title"] = p["title_%s" % lang] \
  38. if p.has_key("title_%s" % lang) \
  39. else p["title"]
  40. # Keep track of the current lang of the virtual page
  41. vp["lang"] = lang
  42. # Fix post name if exists
  43. if vp.has_key("post"):
  44. if lang == "en":
  45. vp["post"] = vp["post"][:]
  46. else:
  47. vp["post"] = vp["post"][:-len(lang) - 1]
  48. page_vpages[lang] = vp
  49. # Each virtual page has to know about its sister vpages
  50. for lang, vpage in page_vpages.iteritems():
  51. vpage["lang_links"] = dict([(l, v["url"]) for l, v in page_vpages.iteritems()])
  52. vpage["other_lang"] = langs # set other langs and link
  53. vpages += page_vpages.values()
  54. pages[:] = vpages
  55. _COMPAT = """ case "%s":
  56. $loc = "%s/%s";
  57. break;
  58. """
  59. _COMPAT_404 = """ default:
  60. $loc = "%s";
  61. break;
  62. """
  63. def hook_preconvert_compat():
  64. fp = open(os.path.join(options.project, "output", "index.php"), 'w')
  65. fp.write("<?\n")
  66. fp.write("// Auto generated xyCMS compatibility index.php\n")
  67. fp.write("$loc = 'index.de.html';\n")
  68. fp.write("if (isset($_GET['p'])) {\n")
  69. fp.write(" if (isset($_GET['lang'])) {\n")
  70. fp.write(" $_GET['p'] .= EN;\n")
  71. fp.write(" }\n")
  72. fp.write(" switch($_GET['p']) {\n")
  73. for p in pages:
  74. if p.get("compat", "") != "":
  75. tmp = p["compat"]
  76. if p.get("lang", DEFAULT_LANG) == DEFAULT_LANG:
  77. tmp = tmp + "EN"
  78. fp.write(_COMPAT % (tmp, options.base_url.rstrip('/'), p.url))
  79. fp.write("\n")
  80. fp.write(_COMPAT_404 % "/404.html")
  81. fp.write(" }\n")
  82. fp.write("}\n")
  83. fp.write("if ($_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.1') {\n")
  84. fp.write(" if (php_sapi_name() == 'cgi') {\n")
  85. fp.write(" header('Status: 301 Moved Permanently');\n")
  86. fp.write(" } else {\n")
  87. fp.write(" header('HTTP/1.1 301 Moved Permanently');\n")
  88. fp.write(" }\n")
  89. fp.write("}\n");
  90. fp.write("header('Location: '.$loc);\n")
  91. fp.write("?>")
  92. _SITEMAP = """<?xml version="1.0" encoding="UTF-8"?>
  93. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  94. %s
  95. </urlset>
  96. """
  97. _SITEMAP_URL = """
  98. <url>
  99. <loc>%s/%s</loc>
  100. <lastmod>%s</lastmod>
  101. <changefreq>%s</changefreq>
  102. <priority>%s</priority>
  103. </url>
  104. """
  105. def hook_preconvert_sitemap():
  106. date = datetime.strftime(datetime.now(), "%Y-%m-%d")
  107. urls = []
  108. for p in pages:
  109. urls.append(_SITEMAP_URL % (options.base_url.rstrip('/'), p.url, date, p.get("changefreq", "monthly"), p.get("priority", "0.5")))
  110. fname = os.path.join(options.project, "output", "sitemap.xml")
  111. fp = open(fname, 'w')
  112. fp.write(_SITEMAP % "".join(urls))
  113. fp.close()
  114. # -----------------------------------------------------------------------------
  115. # postconvert hooks
  116. # -----------------------------------------------------------------------------
  117. _RSS = """<?xml version="1.0"?>
  118. <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  119. <channel>
  120. <title>%s</title>
  121. <link>%s</link>
  122. <atom:link href="%s" rel="self" type="application/rss+xml" />
  123. <description>%s</description>
  124. <language>en-us</language>
  125. <pubDate>%s</pubDate>
  126. <lastBuildDate>%s</lastBuildDate>
  127. <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  128. <generator>Poole</generator>
  129. %s
  130. </channel>
  131. </rss>
  132. """
  133. _RSS_ITEM = """
  134. <item>
  135. <title>%s</title>
  136. <link>%s</link>
  137. <description>%s</description>
  138. <pubDate>%s</pubDate>
  139. <guid>%s</guid>
  140. </item>
  141. """
  142. def hook_postconvert_rss():
  143. items = []
  144. posts = [p for p in pages if "post" in p] # get all blog post pages
  145. posts.sort(key=lambda p: p.date, reverse=True)
  146. for p in posts:
  147. title = p.post
  148. link = "%s/%s" % (BASE_URL, p.url)
  149. desc = htmlspecialchars(p.get("description", "Electronics & Software Projects"))
  150. date = time.mktime(time.strptime("%s 12" % p.date, "%Y-%m-%d %H"))
  151. date = email.utils.formatdate(date)
  152. items.append(_RSS_ITEM % (title, link, desc, date, link))
  153. items = "".join(items)
  154. title = "xythobuz.de Blog"
  155. link = "%s/blog.html" % BASE_URL
  156. feed = "%s/rss.xml" % BASE_URL
  157. desc = htmlspecialchars("xythobuz Electronics & Software Projects")
  158. date = email.utils.formatdate()
  159. rss = _RSS % (title, link, feed, desc, date, date, items)
  160. fp = open(os.path.join(output, "rss.xml"), 'w')
  161. fp.write(rss)
  162. fp.close()