A lightweight FCGI blog written in python
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.
 
 
 
pylog/pylog.py

283 lines
8.7 KiB

#!/usr/bin/python
import os,os.path, sys
import urllib, cgi,time
import cgitb
cgitb.enable()
form = cgi.FieldStorage()
from datetime import datetime
from pylog_action import *
import pylog_config as cfg
import comment_section
__version = "v0.1-(2012-03-15)"
def dir_entry(f,path,depth,hidden):
if '_' in os.path.basename(f):
typ = f[f.rindex('_')+1:]
name = os.path.basename(f)[:-(len(typ)+1)]
else:
typ = ''
name = os.path.basename(f)
if typ in dir_actions:
dir_actions[typ](name,f,depth,hidden)
def file_entry(f,path,depth,hidden):
if '.' in os.path.basename(f):
typ = f[f.rindex('.')+1:]
name = os.path.basename(f)[:-(len(typ)+1)]
else:
typ = ''
name = os.path.basename(f)
if typ in disp_actions:
file_link(name,f,depth,hidden)
def process_dirs(path='.',disppath='.',depth=0,hidden=False):
dirlist = os.listdir(path)
if len(dirlist)!=0:
dir_begin(disppath,hidden,depth)
dirs = []
files = []
for f in dirlist:
f = os.path.normpath(os.path.join(path,f))
if os.path.isdir(f):
dirs.append(f)
else:
files.append(f)
dirs.sort()
files.sort()
for f in dirs+files:
if os.path.isdir(f):
dir_entry(f,disppath,depth,hidden)
if disppath[:len(f)]==f:
process_dirs(f,disppath,depth+1,False)
else:
process_dirs(f,disppath,depth+1,True)
else:
file_entry(f,disppath,depth,hidden)
dir_end(disppath,hidden,depth)
def disp_list(path):
if path==cfg.contentdir:
files,keys=get_newest(cfg.numofposts)
disp_file_dict(files,keys)
return
files = {}
for f in os.listdir(path):
f = os.path.normpath(os.path.join(path,f))
if get_valid_path(f)==cfg.contentdir:
continue
if not os.path.isdir(f):
if not os.path.getmtime(f) in files:
files[os.path.getmtime(f)]=[f]
else:
files[os.path.getmtime(f)].append(f)
keys = files.keys()
keys.sort()
keys.reverse()
disp_file_dict(files,keys)
def disp_file_dict(d,keys):
script = sys.argv[0][sys.argv[0].rindex('/')+1:]
for k in keys:
for f in d[k]:
if '.' in os.path.basename(f):
typ = f[f.rindex('.')+1:]
name = os.path.basename(f)[:-(len(typ)+1)]
else:
typ = ''
name = os.path.basename(f)
if typ in prev_actions and not os.path.isdir(f):
sys.stdout.write('<h1><a class="entryheader" href="'+script+'?')
sys.stdout.write(urllib.urlencode({'path': os.path.normpath(os.path.dirname(f)), \
'disp':os.path.normpath(f)}).replace('&','&amp;')+'">')
print name+'</a> - <span class="entrydate">',
print datetime.fromtimestamp(int(k)).strftime(cfg.datefmt),
print '</span>&nbsp;'
comment_section.disp_num_of_comments(f)
print '</h1>'
prev_actions[typ](f)
def get_all(path=cfg.contentdir):
dicts = []
files = []
for f in os.listdir(path):
f = os.path.normpath(os.path.join(path,f))
if not os.path.isdir(f):
if '.' in os.path.basename(f):
typ = f[f.rindex('.')+1:]
name = os.path.basename(f)[:-(len(typ)+1)]
else:
typ = ''
name = os.path.basename(f)
if typ in prev_actions:
files.append(f)
else:
if '_' in os.path.basename(f):
typ = f[f.rindex('_')+1:]
name = os.path.basename(f)[:-(len(typ)+1)]
else:
typ = ''
name = os.path.basename(f)
if typ in dir_actions:
dicts.append(f)
for d in dicts:
files+=get_all(d)
return files
def get_newest(n):
allfiles=get_all()
files = {}
for f in allfiles:
if not os.path.getmtime(f) in files:
files[os.path.getmtime(f)]=[f]
else:
files[os.path.getmtime(f)].append(f)
keys = files.keys()
keys.sort()
keys.reverse()
return files,keys[0:n]
def get_valid_path(path):
if '..' in path or os.path.normpath(path)=='.':
return cfg.contentdir
valid_chars='. abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/_-0123456789'
for c in path:
if not c in valid_chars:
return cfg.contentdir
return os.path.normpath(path)
if not 'rss' in form:
sys.stdout.write('Content-type: text/html; charset=utf-8\n\n')
else:
import xml.etree.ElementTree as ET
sys.stdout.write('Content-type: text/xml\n\n')
script = sys.argv[0][sys.argv[0].rindex('/')+1:]
files,keys=get_newest(cfg.numofposts)
tz = time.timezone
tzHHMM = "%0+3d%02d" % (tz/-3600,abs((tz%3600)/60))
print '''<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="'''+cfg.topurl+script+'?rss=1'+'" rel="self" type="application/rss+xml" />'
print (" <title>"+cfg.blogtitle+"</title>").encode(cfg.encoding)
print (" <description>"+cfg.subtitle+"</description>").encode(cfg.encoding)
print " <link>"+cfg.topurl+script+"</link>"
print " <generator>Pylog "+__version+"</generator>"
if len(keys)>0:
date=datetime.fromtimestamp(int(keys[0])).strftime("%a, %d %b %Y %H:%M:%S ")
print " <lastBuildDate>"+date+tzHHMM+"</lastBuildDate>"
for k in keys:
date=datetime.fromtimestamp(int(k)).strftime("%a, %d %b %Y %H:%M:%S ")
for f in files[k]:
if '.' in os.path.basename(f):
typ = f[f.rindex('.')+1:]
name = os.path.basename(f)[:-(len(typ)+1)]
else:
typ = ''
name = os.path.basename(f)
print " <item>"
print " <title>"+name+"</title>"
link = ET.Element("link")
link.text = cfg.topurl+script+'?'+urllib.urlencode({'path': os.path.normpath(os.path.dirname(f)),'disp':os.path.normpath(f)})
print " ",
ET.dump(link)
link.tag="guid"
print " ",
ET.dump(link)
print " <pubDate>"+date+tzHHMM+"</pubDate>"
print " </item>"
print "</channel>"
print "</rss>"
sys.exit(0)
script = sys.argv[0][sys.argv[0].rindex('/')+1:]
path = cfg.contentdir
if 'path' in form:
path=form['path'].value
path=get_valid_path(path)
print '<!DOCTYPE html>'
print '<html>'
print '<head>'
print '<meta charset="UTF-8">'
print ('<title>'+cfg.title+'</title>').encode(cfg.encoding)
print '<link rel="alternate" type="application/rss+xml" title="RSS" href="'+cfg.topurl+script+'"?rss=1 />'
print cfg.header.encode(cfg.encoding)
comment_section.comments_init()
print '</head>'
print '<body>'
print ('<h1 id="blogtitle"><a href="'+script+'">'+cfg.blogtitle+'</a></h1>').encode(cfg.encoding)
print ('<h2 id="subtitle">'+cfg.subtitle+'</h2>').encode(cfg.encoding)
print '<div id="menu">'
process_dirs(cfg.contentdir,path)
print '</div>'
print '<div id="content">'
try:
if 'disp' in form:
validdisp = get_valid_path(form['disp'].value)
disp=os.path.basename(validdisp)
if not os.path.isdir(disp):
if '.' in disp:
typ = disp[disp.rindex('.')+1:]
name = disp[:-(len(typ)+1)]
else:
typ = ''
name = disp
if typ in disp_actions:
sys.stdout.write('<h1><span class="entryheader">')
print name+'</span> - <span class="entrydate">',
print datetime.fromtimestamp( \
int(os.path.getmtime(validdisp)) \
).strftime(cfg.datefmt),
print '</span></h1>'
disp_actions[typ](validdisp)
print '<hr>'
print '<div id="footer">'
print cfg.footer
comment_section.disp_comments(validdisp)
print '</div>'
else:
disp_list(path)
except OSError as ose:
# This is here for various errors that
# may occur when accessing files
print '<span style="color:#f00>-- [!]&nbsp;Error&nbsp;[!] --<br>'
print ose.strerror + '</span>'
print '</body>'
print '</html>'