erster Entwurf fuer simples Umfrage-Web-Interface
This commit is contained in:
parent
b4c3a84104
commit
59ccb5a87c
11 changed files with 465 additions and 0 deletions
44
umfrage_kirchenplatz2012/src/dataset.py
Normal file
44
umfrage_kirchenplatz2012/src/dataset.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
DEFINITION_OPTIONS = (
|
||||
(u"Grüner Platz", "http://stadtgestalten.org/umfrage/kirchenplatz2012/media/option1.png",
|
||||
(u"verbreiterte Gehwege", u"Wochenmarkt auf Ostseite", u"Grüne Platzfläche im Westen (keine Nutzung der Freiflächen für Stände, Außengastronomie, etc. möglich)", u"Grünes Kirchenumfeld", u"51 PKW-Stellplätze auf dem Platz (Ostseite) und an der Südseite", u"Bushaltestelle im Bestand", u"Taxistand vor Kirchenplatz Nr. 13", u"Baumpflanzungen auf dem Platz und straßenbegleitend an den Gehwegen")),
|
||||
(u"Karo", "http://stadtgestalten.org/umfrage/kirchenplatz2012/media/option2.png",
|
||||
(u"verbreiterte Gehwege", u"Wochenmarkt auf Ostseite", u"gepflasterte Platzfläche im Westen (Nutzung der Freiflächen für Stände, Außengastronomie, etc. möglich)", u"Kirchenumfeld als befestigte Fläche und Grün", u"30 PKW-Stellplätze auf dem Platz (Ostseite)", u"Bushaltestelle auf der Westseite (gegenüber Mühlenstraße)", u"Taxistand vor Kirchenplatz Nr. 1-2", u"Baumpflanzungen auf dem Platz und straßenbegleitend an den Gehwegen")),
|
||||
(u"Marktplatz mit Baumhain", "http://stadtgestalten.org/umfrage/kirchenplatz2012/media/option3.png",
|
||||
(u"verbreiterte Gehwege", u"Wochenmarkt auf Ostseite (ingeschränkte Fläche wg. Baumpflanzungen)", u"teilweise gepflasterte Platzfläche im Westen (Nutzung der Freiflächen (nicht unter den Bäumen) für Stände, Außengastronomie, etc. möglich) sowie starke Baumpflanzungen", u"Kirchenumfeld als befestigte Fläche", u"44 PKW-Stellplätze straßenbegleitend auf der Nord- und Südseite", u"Bushaltestelle auf der Westseite (gegenüber Mühlenstraße)", u"Taxistand vor Kirchenplatz Nr. 13", u"Baumpflanzungen auf dem Platz und straßenbegleitend an den Gehwegen")),
|
||||
(u"Befestigter Platz", "http://stadtgestalten.org/umfrage/kirchenplatz2012/media/option4.png",
|
||||
(u"verbreiterte Gehwege", u"Wochenmarkt auf Ostseite (ingeschränkte Fläche wg. Baumpflanzungen)", u"teilweise gepflasterte Platzfläche im Westen (Nutzung der Freiflächen für Stände, Außengastronomie, etc. möglich) sowie starke Baumpflanzungen", u"Kirchenumfeld als befestigte Fläche", u"39 PKW-Stellplätze straßenbegleitend auf der Nord- und Südseite", u"Bushaltestelle im Bestand", u"Taxistand vor Kirchenplatz Nr. 13", u"Baumpflanzungen auf dem Platz und auf der West- und Ostseite straßenbegleitend an den Gehwegen")))
|
||||
|
||||
|
||||
DEFINITION_QUALITY_RANGES = {
|
||||
"mehr_weniger": (
|
||||
(u"++", u"++ Ja, trifft voll zu"),
|
||||
(u"+", u"+ Ja, mit Abstrichen"),
|
||||
(u"-", u"- Kaum bis wenig"),
|
||||
(u"--", u"-- Überhaupt nicht")),
|
||||
"baeume": (
|
||||
(u"++", u"++ Lineare Anordnung (Baumreihen)"),
|
||||
(u"--", u"-- Beliebige Anordnung in Einzelbäume, Baumgruppen, Baumhainen")),
|
||||
"gesamt": (
|
||||
(u"++", u"++ Sehr gute Variante, berücksichtigt so gut wie alle Anforderungen"),
|
||||
(u"+", u"+ In Teilen gut gelungene Variante"),
|
||||
(u"-", u"- Wenig attraktiv, berücksichtigt zu wenige Anforderungen"),
|
||||
(u"--", u"-- Unattraktiv, unpassende Variante")),
|
||||
}
|
||||
|
||||
|
||||
DEFINITION_QUESTIONS = (
|
||||
(u"Frage 1: Lädt der Platz durch seine geplante Neugestaltung insgesamt zum Flanieren/Verweilen/Aufenthalt ein?", "mehr_weniger"),
|
||||
(u"Frage 2: Wird die Funktion des Platzes als Orts- und Versorgungsmittelpunkt durch den Entwurf gestärkt?", "mehr_weniger"),
|
||||
(u"Frage 3: Wird die Kirche als Bauwerk mit Portal und grünem Umfeld durch den Entwurf entsprechend betont?", "mehr_weniger"),
|
||||
(u"Frage 4: Berücksichtigt die Variante ausreichend Fläche/ Teilbereiche für temporäre Nutzungen (Markt, Festivitäten)?", "mehr_weniger"),
|
||||
(u"Frage 5: Sind die Hauptwege für Fußgänger über den Platz erkennbar und nutzbar (u.a. Verbindung Mühlenstraße-Kirchenstraße)?", "mehr_weniger"),
|
||||
(u"Frage 6: Steht die Anordnung der Stellplätze im Einklang mit der Neugestaltung des Platzes und wird die Anzahl als ausreichend eingeschätzt?", "mehr_weniger"),
|
||||
(u"Frage 7: Sind Bushaltestelle und Taxistand für die Benutzer gut und aus Sicht der Platzgestaltung attraktiv angeordnet?", "mehr_weniger"),
|
||||
(u"Frage 8: Ist das zugrunde gelegte Begrünungskonzept gestalterisch attraktiv (Straßenraum, Kirchenumfeld)?", "mehr_weniger"),
|
||||
(u"Frage 9: Sind ausreichend Baumanpflanzungen an der Straße sowie im Kirchenumfeld berücksichtigt worden?", "mehr_weniger"),
|
||||
(u"Frage 10: Ist eine lineare Anordnung der Bäume (Baumreihen) im Kirchenumfeld oder eine beliebige Anordnung von Einzelbäumen neben Baumgruppen, Baumhainen gestalterisch und funktional besser?", "baeume"),
|
||||
(u"Abschließende Gesamtbewertung der Planungsvarianten", "gesamt"),
|
||||
)
|
||||
|
183
umfrage_kirchenplatz2012/src/umfrage.py
Normal file
183
umfrage_kirchenplatz2012/src/umfrage.py
Normal file
|
@ -0,0 +1,183 @@
|
|||
#!/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__)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue