184 lines
5.9 KiB
Python
184 lines
5.9 KiB
Python
|
#!/usr/bin/env python2.6
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import os
|
||
|
# the basedir is the parent dir of the location of this script
|
||
|
BASE_DIR = os.path.dirname(os.path.abspath(os.path.join(__file__, os.path.pardir)))
|
||
|
# add the project directory to the python search path
|
||
|
import sys
|
||
|
sys.path.insert(0, os.path.join(BASE_DIR, "src"))
|
||
|
|
||
|
|
||
|
from dataset import DEFINITION_OPTIONS, DEFINITION_QUALITY_RANGES, \
|
||
|
DEFINITION_QUESTIONS
|
||
|
|
||
|
import ConfigParser
|
||
|
import datetime
|
||
|
import uuid
|
||
|
import sqlobject
|
||
|
import bobo
|
||
|
import genshi
|
||
|
import genshi.template
|
||
|
import genshi.filters
|
||
|
|
||
|
|
||
|
CONFIG_FILE = os.path.join(BASE_DIR, "umfrage.conf")
|
||
|
|
||
|
config = ConfigParser.SafeConfigParser()
|
||
|
config.read(CONFIG_FILE)
|
||
|
db_uri = config.get("database", "uri")
|
||
|
sqlobject.sqlhub.processConnection = sqlobject.connectionForURI(db_uri)
|
||
|
loader = genshi.template.TemplateLoader(os.path.join(BASE_DIR, 'templates'), auto_reload=False)
|
||
|
|
||
|
|
||
|
BASE_DICT = {
|
||
|
"base_url": "/umfrage/kirchenplatz2012/", # the trailing slash is necessary
|
||
|
"errors": {},
|
||
|
}
|
||
|
|
||
|
class Session(sqlobject.SQLObject):
|
||
|
created = sqlobject.DateTimeCol(default=sqlobject.DateTimeCol.now)
|
||
|
name = sqlobject.UnicodeCol(default=lambda: uuid.uuid4().hex)
|
||
|
|
||
|
|
||
|
class Question(sqlobject.SQLObject):
|
||
|
text = sqlobject.UnicodeCol()
|
||
|
weight = sqlobject.IntCol()
|
||
|
quality_levels = sqlobject.PickleCol()
|
||
|
|
||
|
|
||
|
class Option(sqlobject.SQLObject):
|
||
|
title = sqlobject.UnicodeCol()
|
||
|
text = sqlobject.UnicodeCol()
|
||
|
image = sqlobject.UnicodeCol()
|
||
|
weight = sqlobject.IntCol()
|
||
|
|
||
|
|
||
|
class Answer(sqlobject.SQLObject):
|
||
|
text = sqlobject.UnicodeCol(default="")
|
||
|
quality = sqlobject.UnicodeCol(default="")
|
||
|
question = sqlobject.ForeignKey("Question")
|
||
|
option = sqlobject.ForeignKey("Option")
|
||
|
session = sqlobject.ForeignKey("Session")
|
||
|
|
||
|
|
||
|
def get_default_values(**kwargs):
|
||
|
value_dict = dict(BASE_DICT)
|
||
|
# we always need "options" (e.g. on frontpage)
|
||
|
value_dict["options"] = list(Option.select())
|
||
|
value_dict["options"].sort(key=lambda item: item.weight)
|
||
|
for key, value in kwargs.items():
|
||
|
value_dict[key] = value
|
||
|
return value_dict
|
||
|
|
||
|
def render(filename, input_data=None, **values):
|
||
|
stream = loader.load(filename).generate(**values)
|
||
|
if not input_data is None:
|
||
|
stream |= genshi.filters.HTMLFormFiller(data=input_data)
|
||
|
return stream.render("html", doctype="html")
|
||
|
|
||
|
|
||
|
def get_previous_question(question):
|
||
|
questions = Question.select().orderBy("-weight")
|
||
|
for one_q in questions:
|
||
|
if one_q.weight < question.weight:
|
||
|
return one_q
|
||
|
return None
|
||
|
|
||
|
def get_next_question(question):
|
||
|
questions = Question.select().orderBy("weight")
|
||
|
for one_q in questions:
|
||
|
if one_q.weight > question.weight:
|
||
|
return one_q
|
||
|
return None
|
||
|
|
||
|
@bobo.query('/')
|
||
|
def show_question(session_id=None, question_id=None, go_backward=False,
|
||
|
**kwargs):
|
||
|
params = get_default_values()
|
||
|
session = None
|
||
|
if session_id:
|
||
|
session = list(Session.selectBy(name=session_id))
|
||
|
if session:
|
||
|
session = session[0]
|
||
|
if not session:
|
||
|
session = Session()
|
||
|
params["session"] = session
|
||
|
return render("start.html", **params)
|
||
|
question = None
|
||
|
if question_id:
|
||
|
try:
|
||
|
question = Question.get(int(question_id))
|
||
|
except ValueError:
|
||
|
pass
|
||
|
# any new input values? (update "Answer" objects)
|
||
|
target_question = None
|
||
|
if question:
|
||
|
for option in Option.select():
|
||
|
opt_params = {}
|
||
|
for key in ("text", "quality"):
|
||
|
dict_key = "option_%s_%s" % (option.id, key)
|
||
|
if dict_key in kwargs:
|
||
|
opt_params[key] = kwargs[dict_key]
|
||
|
# at least one item was found
|
||
|
if opt_params:
|
||
|
answer = Answer.selectBy(session=session, question=question,
|
||
|
option=option)
|
||
|
if not answer:
|
||
|
# create new one
|
||
|
answer = Answer(session=session, question=question,
|
||
|
option=option)
|
||
|
else:
|
||
|
answer = answer[0]
|
||
|
# update one value
|
||
|
for key in opt_params:
|
||
|
setattr(answer, key, opt_params[key])
|
||
|
if go_backward:
|
||
|
target_question = get_previous_question(question)
|
||
|
else:
|
||
|
target_question = get_next_question(question)
|
||
|
if not target_question:
|
||
|
# special case: we are finished
|
||
|
return render("summary.html", session=session)
|
||
|
if not target_question:
|
||
|
target_question = Question.select().orderBy("weight")[0]
|
||
|
# populate the next question
|
||
|
input_data = {}
|
||
|
for answer in Answer.selectBy(session=session, question=target_question):
|
||
|
for key in ("text", "quality"):
|
||
|
input_data["option_%s_%s" % (answer.option.id, key)] = \
|
||
|
getattr(answer, key)
|
||
|
params.update({"session": session,
|
||
|
"question": target_question,
|
||
|
"next_question": get_next_question(target_question),
|
||
|
"previous_question": get_previous_question(target_question),
|
||
|
})
|
||
|
return render("question.html", input_data=input_data, **params)
|
||
|
|
||
|
|
||
|
@bobo.query('')
|
||
|
def redirect_startpage():
|
||
|
return bobo.redirect(BASE_DICT["base_url"])
|
||
|
|
||
|
|
||
|
# initialize the tables (do it only once!)
|
||
|
if True:
|
||
|
tables = (Session, Question, Option, Answer)
|
||
|
# drop all
|
||
|
drop_tables = list(tables)
|
||
|
drop_tables.reverse()
|
||
|
for table in drop_tables:
|
||
|
if table.tableExists():
|
||
|
table.dropTable()
|
||
|
for table in tables:
|
||
|
table.createTable()
|
||
|
for index, (title, image_url, lines) in enumerate(DEFINITION_OPTIONS):
|
||
|
Option(title=title, image=image_url,
|
||
|
text=os.linesep.join(lines), weight=index)
|
||
|
for index, (text, quality_levels) in enumerate(DEFINITION_QUESTIONS):
|
||
|
Question(text=text, weight=index, quality_levels=DEFINITION_QUALITY_RANGES[quality_levels])
|
||
|
|
||
|
# this application should be usable with mod_wsgi
|
||
|
application = bobo.Application(bobo_resources=__name__)
|
||
|
|