#!/usr/bin/python

# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.

# Author: Stefan Ritter <xeno@thehappy.de>
# Description: A simple blogging software

import cgi, os, time, glob, re, md5, sys, random
import ConfigParser

def generate_uuid(string):
	string_md5sum = md5.new(string).hexdigest()
	string_md5sum_1 = string_md5sum[0:8]
	string_md5sum_2 = string_md5sum[8:12]
	string_md5sum_3 = string_md5sum[12:16]
	string_md5sum_4 = string_md5sum[16:20]
	string_md5sum_5 = string_md5sum[20:32]
	string = string_md5sum_1 + '-' + string_md5sum_2 + '-' + string_md5sum_3 + '-' + string_md5sum_4 + '-' + string_md5sum_5
	return string

def errorpage(string):
	print 'Content-type: text/html\n'
	print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
	print ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
	print '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">'
	print '<head>'
	print '    <title>Error!</title>'
	print '</head>'
	print '<body>'
	print '    <b>' + string + '</b> is not set in configuration, please check your installation!'
	print '</body>'
	print '</html>'
	sys.exit()

def document_header(string):
	if string == "xhtml-transitional":
		print 'Content-type: text/html\n'
		print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
		print ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
		print '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">'
	if string == "xhtml-strict":
		print 'Content-type: text/html\n'
		print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'
		print ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
		print '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">'
	if string == "atom":
		print 'Content-type: application/atom+xml\n'
		print '<?xml version="1.0" encoding="utf-8"?>'
		print '<feed xmlns="http://www.w3.org/2005/Atom">'

configuration = ConfigParser.ConfigParser()
configuration.read('configuration')

try: blog_title = configuration.get('personal', 'blog_title')
except: errorpage("blog_title")
try: blog_url = configuration.get('personal', 'blog_url')
except: errorpage("blog_url")
try: keywords = configuration.get('personal', 'keywords')
except: errorpage("keywords")
try: entries_dir = configuration.get('personal', 'entries_dir')
except: errorpage("entries_dir")
try: entries_suffix = configuration.get('personal', 'entries_suffix')
except: errorpage("entries_suffix")
try: staticpages_dir = configuration.get('personal', 'staticpages_dir')
except: errorpage("staticpages_dir")
try: style = configuration.get('look', 'style')
except: errorpage("style")
try: entries_per_page = configuration.getint('look', 'entries_per_page')
except: errorpage("entries_per_page")
try: monthlist = configuration.get('look', 'monthlist')
except: errorpage("monthlist")
try: staticpages = configuration.get('look', 'staticpages')
except: errorpage("staticpages")
try: linklist = configuration.get('look', 'linklist')
except: errorpage("linklist")
try: permalinks = configuration.get('look', 'permalinks')
except: errorpage("permalinks")
try: comments = configuration.get('look', 'comments')
except: errorpage("comments")
try: newest_first = configuration.get('look', 'newest_first')
except: errorpage("newest_first")

# Read POST Variables
action = cgi.FieldStorage()
month_display = action.getvalue('m')
post_display = action.getvalue('p')
static_display = action.getvalue('s')
allentries_display = action.getvalue('a')
feed_display = action.getvalue('feed')
if not month_display: month_display = ""
if not post_display: post_display = ""
if not static_display: static_display = ""
if not allentries_display: allentries_display = ""
if not feed_display: feed_display = ""

# Commentstuff
ctitle = action.getvalue('ctitle')
cname = action.getvalue('cname')
ctext = action.getvalue('ctext')
cquiz = action.getvalue('cquiz')
cquizv = action.getvalue('cquizv')
if not ctitle: ctitle = ""
if not cname: cname = ""
if not ctext: ctext = ""
if not cquiz: cquiz = ""
if not cquizv: cquizv = ""

# Comment to commit?
if cname and ctext and ctitle:
	# Prevent XSS hacks
	cname = cname.replace("<", "&lt;") \
				 .replace(">", "&gt;") \
				 .replace("\"", "&quot;")
	ctext = ctext.replace("<", "&lt;") \
				 .replace(">", "&gt;") \
				 .replace("\"", "&quot;")
	
	# Add comment
	if not cquiz == cquizv:
		errorpage("Brainmode")
	else:
		comments_file = glob.glob(entries_dir + ctitle + '.comments')
		if not comments_file:
			content = open(entries_dir + ctitle + '.comments', "w")
			content.close()
			comments_file = glob.glob(entries_dir + ctitle + '.comments')
		content = open(comments_file[0], "a+")
		content.write("-." + cname + "\n")
		content.write("+." + time.asctime() + "\n")
		ctext = ctext.split("\n")
		for line in ctext:
			content.write("." + line + "\n")
		content.close()

# Read entries and store their title and timestamp
entries      = []
entries_list  = glob.glob(entries_dir + '*.' + entries_suffix)

for entry in entries_list:
	timestamp = os.stat(entry)
	timestamp = time.localtime(timestamp[8])
	entry = timestamp, entry
	entries.append(entry)

if newest_first:
	entries.sort(reverse=True)
else:
	entries.sort()

# Generate atom feed
if feed_display == "atom":
	title = str(entries[0][1]).replace('entries/', '', 1).replace('.' + entries_suffix, '')
	date = entries[0][0]
	blog_title_md5sum = generate_uuid(blog_title)
	title_md5sum = generate_uuid(title)

	document_header("atom")	
	print '<link href="' + blog_url + '/?feed=atom" rel="self" type="application/atom+xml"/>'
	print '    <author>'
	print '        <name>' + blog_title + '</name>'
	print '    </author>'
	print '    <title>' + blog_title + '</title>'
	print '    <id>urn:uuid:' + blog_title_md5sum + '</id>'
	print '    <updated>' + str(date[0]) + '-0' + str(date[1]) + '-' + str(date[2]) + 'T' + str(date[3]) + ':' + str(date[4]) + ':' + str(date[5]) + 'Z</updated>'
	print ''
	print '    <entry>'
	print '        <title>' + title + '</title>'
	print '        <link href="' + blog_url + '"/>'
	print '        <id>urn:uuid:' + title_md5sum + '</id>'
	print '        <updated>' + str(date[0]) + '-0' + str(date[1]) + '-' + str(date[2]) + 'T' + str(date[3]) + ':' + str(date[4]) + ':' + str(date[5]) + 'Z</updated>'
	print '    </entry>'
	print '</feed>'

# Generate regular page
else:
	document_header("xhtml-transitional")
	print '    <head>'
	print '        <title>' + blog_title + '</title>'
	print '        <meta http-equiv="content-type" content="text/html; charset=utf-8" />'
	print '        <meta name="keywords" content="' + keywords + '" />'
	print '        <meta name="description" content="' + blog_title + '" />'
	print '        <link rel="stylesheet" type="text/css" href="styles/' + style + '" />'
	print '    </head>'
	print '    <body>'
	print '        <div class="title"><a href="?" class="title">' + blog_title + '</a></div>'
	print '        <div class="feeds">'
	print '            <a href="?feed=rss"><img src="styles/images/rss.png" alt="rss" /></a>'
	print '            <a href="?feed=atom"><img src="styles/images/atom.png" alt="atom" /></a>'
	print '        </div>'

	print '        <div class="screen"><div class="sidebar">'

	# Sidebar: Staticpages
	if staticpages == "True":
		staticpages = []
		staticpages_list  = glob.glob(staticpages_dir + '*')
		staticpages_list.sort()
		print '            <div class="sidebarentry">'
		print '                <small>pages</small><br />'
		for staticpage in staticpages_list:
			title = re.sub('\w+?\/\d+?-', '', staticpage)
			link = re.sub('\w+?\/', '', staticpage)
			# The ultimative lookshe-hack *g*
			if title == "lookshe":
				print '                &nbsp;<a href="?s=' + link + '">/me</a>&nbsp;<br />'
			else:
				print '                &nbsp;<a href="?s=' + link + '">' + title + '</a>&nbsp;<br />'

		if monthlist == "True": print '                <br />'
		print '            </div>'

	# Sidebar: Monthlist
	if monthlist == "True":
		olddate = ""
		print '            <div class="sidebarentry">'
		print '                <small>months</small><br />'
		for entry in entries:
			date        = time.strftime("%m%Y", entry[0])
			date_display = time.strftime("%h %Y", entry[0])
			if not olddate == date:
				print '                &nbsp;<a href="?m=' + date + '">' + date_display + '</a>&nbsp;<br />'
			olddate = date
		if linklist == "True": print '                <br />'
		print '            </div>'

	# Sidebar: Linklist
	if linklist == "True":
		print '            <div class="sidebarentry">'
		print '                <small>links</small><br />'
		content = open("linklist", "r")
		for line in content:
			if line.strip() is "":
				print '                <br />'
			else:
				print '                &nbsp;<a href="' + line.split(" ")[0] + '" target="_blank">' + line.split(" ", 1)[1].strip() + '</a>&nbsp;<br />'
		content.close()
		print '            </div>'

	print '        </div>'
	print '        <div class="content">'

	if static_display != "": # Show Staticpage
		content = open(staticpages_dir + static_display, "r")
		print '            <div class="entrytitle">' + re.sub('\d+?-', '', static_display) + '</div>'
		print '            <div class="entry"><p>'
		for line in content:
			print '                ' + line.strip() + '<br />'
		print '            </p></div>'
		content.close()
	else: # Show regular entry
		entry_counter = 0
		for entry in entries:
			date            = time.strftime("%c", entry[0])
			date_to_compare = time.strftime("%m%Y", entry[0]) # Needed for permalinks
			entry           = entry[1]
			title           = entry.replace('entries/', '', 1)
			title           = title.replace('.' + entries_suffix, '')

			if month_display == date_to_compare or not month_display:
				if post_display == title or not post_display:
					if allentries_display == "1" or entry_counter < entries_per_page:
						content = open(entry, "r")
						if permalinks:
							print '            <div class="entrytitle"><a href="?p=' + title + '" class="entrytitle">' + title + ' <small>(' + date + ')</small></a></div>'
						else:
							print '            <div class="entrytitle">' + title + ' <small>(' + date + ')</small></div>'
						print '            <div class="entry">'
						for line in content:
							print '                ' + line.strip() + '<br />'
						
						# Comments are shown when post_display and comments_file
						comments_file = glob.glob(entries_dir + title + '.comments')
						if post_display:
							if comments_file:
								print '                <br /><hr />'
								comments_file = glob.glob(entries_dir + title + '.comments')
								comments_content = open(comments_file[0], "r")
								for line in comments_content:
									if line.split(".", 1)[0] == "-":
										print '                <br />'
										print '                <b><i>' + line.split(".", 1)[1].strip() + '</i><small> wrote at '
									elif line.split(".", 1)[0] == "+":
										print '                ' + line.split(".", 1)[1].strip() + ':</small></b><br />'
									else:
										line = line.split(".", 1)[1]
										print '                &nbsp;&nbsp;' + line.strip() + '<br />'
								comments_content.close()

							# Form for adding comments
							random_int_a = random.randint(1,9)
							random_int_b = random.randint(1,9)
							cquizv = random_int_a + random_int_b

							print '                <br /><br /><br />'
							print '                <form action="" method="post">'
							print '                    <input type="hidden" name="ctitle" value="' + title + '" />'
							print '                    <input type="hidden" name="cquizv" value="' + str(cquizv) + '" />'
							print '                    <label for="cname">name:</label><input type="text" id="cname" name="cname" />'
							print '                    <br /><label for="ctext">text:</label><textarea rows="5" cols="80" id="ctext" name="ctext"></textarea>'
							print '                    <br /><label for="cquiz">' + str(random_int_a) + '+' + str(random_int_b) + '=</label><input type="text" id="cquiz" name="cquiz" />'
							print '                    <br /><input type="submit" id="submit" value="post comment" />'
							print '                </form>'

						if comments == "True":
							comments_file = glob.glob(entries_dir + title + '.comments')
							if not comments_file and not post_display:
								print '                <div class="comment">'
								print '                    <ul><li><a href="?p=' + title + '" class="comment">no comments</a></li></ul>'
								print '                </div>'
							elif comments_file and not post_display:
								comments_content = open(comments_file[0], "r")
								comments_counter = 0
								for line in comments_content:
									if line.split(".", 1)[0] == "-": comments_counter += 1
								print '                <div class="comment">'
								print '                    <ul><li><a href="?p=' + title + '" class="comment">comments (' + str(comments_counter) + ')</a></li></ul>'
								print '                </div>'
								comments_content.close()
								
						print '            </div>'
						print '            <br /><br />'
						content.close()
						entry_counter += 1

		if not month_display and not post_display and not allentries_display and entry_counter == entries_per_page: # Display pagelist
			print '            <div class="entry"><a href=?a=1>View all entries...</a></div>'

	print '        </div></div>'
	print '    </body>'
	print '</html>'

# vim: set tw=0 ts=4: