changeset 61:5b4ff5680037

Add a basic blog manager. rlgnotes is an experimental script for managing a static blog.
author John "Elwin" Edwards
date Fri, 30 Jan 2015 09:25:32 -0500
parents 876786c55450
children df7acc5653b3
files README.txt py/rlgnotes web/index.html web/notes/notes.css
diffstat 4 files changed, 173 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/README.txt	Wed Jan 21 10:45:00 2015 -0500
+++ b/README.txt	Fri Jan 30 09:25:32 2015 -0500
@@ -19,6 +19,9 @@
 py/rlgall.py is a module which recorder.py requires.  It should be installed
 in /lib/python<x.y>/site-packages or the equivalent location.
 
+py/rlgnotes is a basic blog creator.  It makes a blog (with RSS feed!) at
+the URL /notes using text files as the source.  Currently experimental.
+
 web/ contains the static parts of the rlgallery.org website.  Note that when 
 installed, scoring/ needs to be writable by whatever user is running the 
 recorder.py script.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/py/rlgnotes	Fri Jan 30 09:25:32 2015 -0500
@@ -0,0 +1,153 @@
+#!/usr/bin/python3
+
+import os
+import sys
+import datetime
+import rlgall
+import pytz
+
+navbar = '<div class="nav"><a href="/">rlgallery.org</a> -&gt; \
+<a href="/notes/">Notes</a> -&gt; {0}</div>'
+
+rsshead = """<?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0">
+<channel>
+<title>Roguelike Gallery</title>
+<description>News and notes from the Roguelike Gallery.</description>
+<link>http://rlgallery.org/notes/</link>
+"""
+
+indexintro = """<p>The Gallery's blog, with news and thoughts on roguelike 
+games. A comment system is planned but does not exist yet. There is an 
+<a href="feed.rss">RSS feed</a> for the benefit of robots.</p>
+"""
+
+phead = rlgall.phead.replace("/scoring/scores.css", "notes.css")
+
+ptitle = '<h2 class="pagetitle">{0}</h2>\n'
+
+posthead = '<h3 class="posttitle">{0}</h2>\n'
+
+datediv = '<div class="datehead">{0}</div>\n'
+
+def noteurl(tag):
+  return "http://rlgallery.org/notes/" + tag + ".html"
+
+def itementry(tagname, value):
+  return "  <{0}>{1}</{0}>\n".format(tagname, value)
+
+def fmtdate(dt):
+  if dt == None:
+    dt = datetime.datetime.now(pytz.utc)
+  return dt.strftime("%a, %d %b %Y %H:%M:%S %z")
+
+def qdetag(istr):
+  nstart = istr.find('>')
+  if nstart < 0:
+    return istr
+  mstr = istr[nstart + 1:]
+  nend = mstr.find('<')
+  if nend < 0:
+    return mstr
+  return mstr[:nend]
+
+def mkindexfile(postdata, notedir):
+  indexfile = open(notedir + "/index.html", "w")
+  postdata.sort(key=lambda m: m[2], reverse=True)
+  indexfile.write(phead.format("Roguelike Gallery Notes"))
+  indexfile.write('<body>\n<h1>Roguelike Gallery Notes</h1>\n')
+  indexfile.write(rlgall.navtop.format("Notes"))
+  indexfile.write(indexintro)
+  for note in postdata:
+    indexfile.write(posthead.format(note[1]))
+    datestr = note[2].strftime("%B %e, %Y")
+    indexfile.write(datediv.format(datestr))
+    if note[3][0] == '<':
+      indexfile.write(note[3])
+    else:
+      indexfile.write('<p>' + note[3] + '</p>')
+    indexfile.write('<p><a href="{0}.html">More</a></p>\n'.format(note[0]))
+  indexfile.write(rlgall.pend)
+  indexfile.close()
+
+def mkrssfile(postdata, notedir):
+  rssfile = open(notedir + "/feed.rss", "w")
+  rssfile.write(rsshead)
+  nowstr = fmtdate(None)
+  rssfile.write("<lastBuildDate>" + nowstr + "</lastBuildDate>\n")
+  for post in postdata:
+    rssfile.write("<item>\n")
+    rssfile.write(itementry("title", post[1]))
+    rssfile.write(itementry("link", noteurl(post[0])))
+    rssfile.write(itementry("pubDate", fmtdate(post[2])))
+    rssfile.write(itementry("description", qdetag(post[3])))
+    rssfile.write("</item>\n")
+  rssfile.write('</channel>\n</rss>\n')
+
+webdir = "/var/www/lighttpd/notes/"
+if len(sys.argv) > 1:
+  srcdir = sys.argv[-1]
+else:
+  srcdir = "."
+
+if "-f" in sys.argv[1:]:
+  force = True
+else:
+  force = False
+
+metadata = []
+anynew = False
+
+notefiles = os.listdir(srcdir)
+for note in notefiles:
+  pagename = webdir + note + ".html"
+  try:
+    os.stat(pagename)
+  except FileNotFoundError:
+    anynew = True
+    createpage = True
+  else:
+    # It already exists, only create it if given -f option
+    createpage = force
+  notefi = open(srcdir + "/" + note)
+  if createpage:
+    pagefi = open(pagename, "w")
+  title = notefi.readline().rstrip()
+  pdate = notefi.readline().rstrip()
+  try:
+    ddate = datetime.datetime.strptime(pdate, "%Y-%m-%d.%H:%M").replace(tzinfo=pytz.utc)
+  except ValueError:
+    continue
+  firstline = notefi.readline().rstrip()
+  metadata.append((note, title, ddate, firstline))
+  if not createpage:
+    # Only the metadata is needed, for the index
+    notefi.close()
+    continue
+  pagefi.write(phead.format(title))
+  pagefi.write('<body>\n<h1>Roguelike Gallery Notes</h1>\n')
+  pagefi.write(navbar.format(title))
+  pagefi.write(ptitle.format(title))
+  pagefi.write(datediv.format(ddate.strftime("%B %e, %Y")))
+  pagefi.write('<div class="content">\n')
+  if firstline[0] == '<':
+    pagefi.write(firstline)
+  else:
+    pagefi.write('<p>' + firstline + '</p>')
+  for line in notefi:
+    if line == '\n':
+      continue
+    elif line[0] == '<':
+      pagefi.write(line)
+    elif line[0] == '\\':
+      pagefi.write(line[1:])
+    else:
+      pagefi.write('<p>' + line + '</p>')
+  pagefi.write('</div>\n')
+  pagefi.write(rlgall.pend)
+  pagefi.close()
+  notefi.close()
+
+if force or anynew:
+  mkindexfile(metadata, webdir)
+  mkrssfile(metadata, webdir)
--- a/web/index.html	Wed Jan 21 10:45:00 2015 -0500
+++ b/web/index.html	Fri Jan 30 09:25:32 2015 -0500
@@ -28,6 +28,7 @@
 <li><a href="/archive.cgi">ttyrec files</a></li>
 </ul>
 <h2>News</h2>
+<p>For more details, check <a href="/notes/">the blog</a>.</p>
 <p><strong>Jan. 12, 2015</strong>: Some bugs in the Web app have been fixed.</p>
 <p><strong>Mar. 31, 2014</strong>: A few bugs have been fixed. The length limit for player names has been increased from 10 characters to 20.</p>
 <p><strong>Jan. 10, 2014</strong>: Statistical charts have been added to the <a href="/scoring/">scores section</a>.</p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/notes/notes.css	Fri Jan 30 09:25:32 2015 -0500
@@ -0,0 +1,16 @@
+@import url("/main.css");
+
+h2.pagetitle {
+	text-align: center;
+}
+
+h3.posttitle {
+	background-color: #E0FFE0;
+	text-align: center;
+}
+
+div.datehead {
+	text-align: center;
+	font-size: 0.8em;
+	font-style: italic;
+}