codekasten/tycker/tycker.py

145 lines
4.3 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2012 Lars Kruse <devel@sumpfralle.de>
#
# tycker is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# tycker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with tycker. If not, see <http://www.gnu.org/licenses/>.
#
import os
# the basedir is the parent dir of the location of this script
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# Somehow "/usr/lib/python2.X/dist-packages" is missing from sys.path - thus bobo is not found.
# This applies to libapache2-mod-wsgi (3.3-2).
import sys
for path in list(sys.path):
options = []
parent_dir, last_dir = os.path.split(path)
options.append(os.path.join(path, "dist-packages"))
options.append(os.path.join(parent_dir, "pymodules", last_dir))
for option in options:
if os.path.isdir(option):
sys.path.append(option)
import datetime
import bobo
import sqlobject
import genshi.template
from settings import *
db_uri = "sqlite://%s" % DB_FILE
sqlobject.sqlhub.processConnection = sqlobject.connectionForURI(db_uri)
loader = genshi.template.TemplateLoader(os.path.join(BASE_DIR, 'templates'), auto_reload=True)
class Entry(sqlobject.SQLObject):
timestamp = sqlobject.DateTimeCol()
title = sqlobject.UnicodeCol()
content = sqlobject.UnicodeCol()
def render(filename, **values):
stream = loader.load(filename).generate(**values)
return stream.render("html", doctype="html")
def get_filename(index):
return os.path.join(OUTPUT_DIR, FILENAME_TEMPLATE % index)
def get_link(index):
return FILENAME_TEMPLATE % index
def update_static_html():
entries = list(Entry.select().orderBy("-timestamp"))
file_index = 1
while entries:
current = entries[:PAGE_SIZE]
entries = entries[PAGE_SIZE:]
current_filename = get_filename(file_index)
if file_index > 1:
previous_link = get_link(file_index - 1)
else:
previous_link = None
if entries:
next_link = get_link(file_index + 1)
else:
next_link = None
values = { "entries": current,
"prev_link": previous_link,
"next_link": next_link,
}
rendered = render("display.html", **values)
open(current_filename, "w").write(rendered)
file_index += 1
@bobo.query('/submit')
def submit_entry(entry_id=None, title=None, content=None, date=None):
title = title.strip()
content = content.strip()
if not all((title, content, date)):
return bobo.redirect(BASE_URL)
try:
date = datetime.datetime.strptime(date, DATE_FORMAT_FULL)
except ValueError:
bobo.redirect(BASE_URL)
if entry_id is None:
Entry(title=title, content=content, timestamp=date)
else:
try:
entry = Entry.get(entry_id)
except sqlobject.SQLObjectNotFound:
bobo.redirect(BASE_URL)
entry.title = title
entry.content = content
entry.date = date
update_static_html()
return bobo.redirect(BASE_URL)
@bobo.query('/delete')
def delete_entry(entry_id):
try:
Entry.delete(entry_id)
except sqlobject.SQLObjectNotFound:
bobo.redirect(BASE_URL)
update_static_html()
return bobo.redirect(BASE_URL)
@bobo.query('/generate')
def generate_static():
update_static_html()
return bobo.redirect(BASE_URL)
@bobo.query('/')
def show_entries():
values = {}
values["entries"] = Entry.select().orderBy("-timestamp")
values["date_format"] = DATE_FORMAT_FULL
values["static_url"] = get_link(1)
return render("admin_show_entries.html", **values)
@bobo.query('')
def redirect_base():
return bobo.redirect(os.path.split(__file__)[1] + "/")
for table in (Entry, ):
#table.dropTable()
if not table.tableExists():
table.createTable()
application = bobo.Application(bobo_resources=__name__)