#!/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=<num entries> url=<url of webpage> description=<description of site> --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 = '<a href="%s">%s</a>' % (text, text) Then in your entry: "http://joe.terrarum.net"[link] will be come <a href="http://joe.terrarum.net">http://joe.terrarum.net</a> 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','<a href="%s%s?p=%s">Next</a>' % (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','<a href="%s?p=%s">Prev</a>' % (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','<a href="%s%s?p=%s">Next</a>' % (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'(<br/>)?\n').sub("<br />\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())