#!/usr/bin/python
import sys, os, cgi, re, ConfigParser
import cgitb; cgitb.enable()
from time import localtime, strftime
"""
blarg.py
Simple weblog script
Joe Topjian - joe@terrarum.net
Created 01/20/05
Modified 04/26/05
Instructions:
Create a file called config.txt in the same directory as this file. Inside, fill out as follows:
--begin--
[general]
datadir=
templatedir=
ext=.txt
dateformat=
title=
numentries=
url=
description=
--end--
Datadir is a directory that will include your entries. These are simple blosxom-style entries so the first line
is the title of the entry and the rest is the body. You may also make any type of directory tree you want as well such as:
/cooking/recipies/cookies.txt
ext is the extention of your entries.
Templatedir is a directory containing the following files:
header.html, entry.html footer.html contenttype.html
Variables in the templates are such as:
%url = url value in config file
%description = description in config file
etc
%title, %body = title and body of entry
dateformat is a strftime formatted date: http://docs.python.org/lib/module-time.html
%date ends up being dateformat parsed
contenttype.html includes "Content-Type: text/html\n\n". If you are using any other file formats (like rss or txt), create respective contenttype.ext files to print out the Content-Type line.
You may also create a format.ext file in your template directory with special formatting instructions. Example:
#link
text = '%s' % (text, text)
Then in your entry:
"http://joe.terrarum.net"[link] will be come http://joe.terrarum.net
You may also chain your formats like so: [bold,italic]
Pagination works by just adding %prev and %next wherever
"""
form = cgi.FieldStorage()
files = { }
formats = { }
code = [ ]
nosearch = 0
# function of os.path.walk
def walker(arg, dirname, fname):
for i in fname:
(root, ext) = os.path.splitext(i)
if ext == config.get('general','ext'):
filename = os.path.join(dirname,i).replace(config.get('general','datadir'),'')
files[filename] = int(os.path.getmtime(os.path.join(dirname,i)))
# interop function
def interop(text):
for keyword in re.compile(r'\%\w+').findall(text):
# loops through all the sections to see if the keyword exists
for section in config.sections():
if config.has_option(section, keyword[1:]):
text = text.replace(keyword, config.get(section, keyword[1:]))
break;
return text
# formatting function
def replace(text, format):
if ',' in format:
for f in format.split(','):
if formats.has_key(f): exec(formats[f])
else:
if formats.has_key(format): exec(formats[format])
return text
# Create a config object to parse the config.txt file
config = ConfigParser.ConfigParser()
config.readfp(open('config.txt'))
# figure out the format and if a subdirectory was specified
curl = os.environ['REQUEST_URI'].replace('?'+os.environ['QUERY_STRING'], '')
(root, ext) = os.path.splitext(curl)
subdir = config.get('general','datadir') + curl
if ext: subdir = subdir.replace(ext, config.get('general','ext'))
if not os.path.isdir(subdir):
if not os.path.isfile(subdir):
subdir = ''
else:
filename = subdir.replace(config.get('general','datadir'),'')
files[filename] = int(os.path.getmtime(subdir))
nosearch = 1
if ext and os.path.isfile(config.get('general','templatedir') + '/header.' + ext[1:]):
contenttype = ext[1:]
else:
contenttype = 'html'
# formatting re
formatre = re.compile(r'"([\w\s\-\.\+\:\/\;\~ ]+)"\[([\,\w]+)\]')
# read in formats
file = open(config.get('general','templatedir') + '/format.' + contenttype)
for line in file:
if line[0] == '#':
if code:
formats[curr] = "\n".join(code)
code = []
curr = line.replace('#','').rstrip()
else:
code.append(line)
formats[curr] = "\n".join(code)
# look for all the file
if not nosearch:
if subdir:
os.path.walk(subdir, walker, None)
else:
os.path.walk(config.get('general','datadir'), walker, None)
# reverse sort by timestamp on the entries
items = [ (v, k) for k, v in files.items() ]
items.sort()
items.reverse()
files = [ (v, k) for k, v in items ]
print open(os.path.join(config.get('general','templatedir'),'contenttype.'+contenttype)).read()
# page information
if form.has_key('p'):
offset = int(form['p'].value)
if offset + int(config.get('general','numentries')) < len(files):
config.set('general','next','Next' % (config.get('general','url'), curl, str(offset + int(config.get('general','numentries')))))
else:
config.set('general','next','')
prev = offset - int(config.get('general','numentries'))
if prev >= 0:
config.set('general','prev','Prev' % (curl, str(prev)))
else:
config.set('general','prev','')
else:
if len(files) < int(config.get('general','numentries')):
config.set('general','next','')
else:
config.set('general','next','Next' % (config.get('general','url'), curl, config.get('general','numentries')))
config.set('general','prev','')
offset = 0
print interop(open(config.get('general','templatedir') + '/header.' + contenttype).read())
for (file, timestamp) in files[offset:int(config.get('general','numentries'))+offset]:
entrytpl = open(config.get('general','templatedir') + '/entry.' + contenttype).read()
entry = open(config.get('general','datadir') + '/' + file)
config.set('general','entrytitle', entry.readline().rstrip())
config.set('general','perm', file.replace('.txt','.html'))
if contenttype != 'rss':
config.set('general','body',re.compile(r'(
)?\n').sub("
\n", entry.read()))
else:
config.set('general','body', entry.read()[:150] + '...')
entry.close()
config.set('general', 'date', strftime(config.get('general','dateformat'), localtime(int(timestamp))))
entrytpl = interop(entrytpl)
m = formatre.search(entrytpl)
while m:
text = replace(m.group(1), m.group(2))
entrytpl = formatre.sub(text, entrytpl, count=1)
m = formatre.search(entrytpl)
print entrytpl
print interop(open(config.get('general','templatedir') + '/footer.'+contenttype).read())