#!/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__)