From f2ef35b429ccf5d5205e393165e5eece91125968 Mon Sep 17 00:00:00 2001 From: lars Date: Wed, 14 Apr 2010 18:03:44 +0000 Subject: [PATCH] first draft of the poll website --- wortschlucker/README | 5 + wortschlucker/database.sqlite | Bin 0 -> 3072 bytes wortschlucker/forms.py | 7 ++ wortschlucker/templates/layout.html | 31 +++++ wortschlucker/templates/poll_details.html | 21 ++++ wortschlucker/templates/poll_new.html | 36 ++++++ wortschlucker/templates/polls.html | 27 +++++ wortschlucker/wortschlucker.py | 132 ++++++++++++++++++++++ 8 files changed, 259 insertions(+) create mode 100644 wortschlucker/README create mode 100644 wortschlucker/database.sqlite create mode 100644 wortschlucker/forms.py create mode 100644 wortschlucker/templates/layout.html create mode 100644 wortschlucker/templates/poll_details.html create mode 100644 wortschlucker/templates/poll_new.html create mode 100644 wortschlucker/templates/polls.html create mode 100755 wortschlucker/wortschlucker.py diff --git a/wortschlucker/README b/wortschlucker/README new file mode 100644 index 0000000..5f0d057 --- /dev/null +++ b/wortschlucker/README @@ -0,0 +1,5 @@ +Requirements: + apt-get install python-bobo python-genshi python-sqlobject + +Start the server: + bobo2.6 wortschlucker.py diff --git a/wortschlucker/database.sqlite b/wortschlucker/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..384bdb4b8d21f2819472fc882767a03214091112 GIT binary patch literal 3072 zcmeHIL2KJE6qcPpAkfnYVYhc|=n9doIB`z%g1UtzY3KN`vV&1c8({>NnZFs+5s%X*m~mU!>`@MpbGNM3(f2*n{Q$~{xyqBgQD^cnym)X~F?wk|9K zFmnTbn4Yw9WLv+G{XKvoq`VQ@!RdMVZF(xY-LSwamS;^;akN$R{*a z3oFIVzLFwWJXgkoD~Do{>Zh^?W|ymV6b4oLhl%-DA(e!XUeJ)PW^`SXry?Cdcc8ca z`}1%ABVTNvXwuf_v-ML?O*9TP4*Ww0F6<8KE&DIr1uNxnOcFeH9O9%IaWg#0ILU~Q zH;(IPWXzSm9i5yXogp5c56L+ufc>dEnv%&otJ3MctaUu>J9y)by_6+n#8UmTKjIln k60JI7UZs;COOS=BG?_Zyl(^OT*FXIx8V4E&{zC_T1Bz* + + + + + + WortSchlucker<py:if test="title">: ${title}</py:if> + + + + ${select('*[local-name()!="title"]')} + + + + + + +
+ ${select('*|text()')} +
+ + +
+ + + diff --git a/wortschlucker/templates/poll_details.html b/wortschlucker/templates/poll_details.html new file mode 100644 index 0000000..73cacca --- /dev/null +++ b/wortschlucker/templates/poll_details.html @@ -0,0 +1,21 @@ + + + + + + Poll details + + +

Poll: ${poll.title}

+
    +
  • Author: ${poll.author}
  • +
  • Created: ${poll.get_creation_time_string()}
  • +
  • Description: ${poll.description}
  • +
  • URL: ${poll.get_url()}
  • +
+ + + + diff --git a/wortschlucker/templates/poll_new.html b/wortschlucker/templates/poll_new.html new file mode 100644 index 0000000..c096f7f --- /dev/null +++ b/wortschlucker/templates/poll_new.html @@ -0,0 +1,36 @@ + + + + + + Create a poll + + +

New poll

+
+

+ + + ${errors.author} +

+

+ + + ${errors.title} +

+

+ + + ${errors.description} +

+

+ + +

+
+ + + + diff --git a/wortschlucker/templates/polls.html b/wortschlucker/templates/polls.html new file mode 100644 index 0000000..a808421 --- /dev/null +++ b/wortschlucker/templates/polls.html @@ -0,0 +1,27 @@ + + + + + + Poll list + + +

All polls

+

Error: +

    +
  • ${message}
  • +
+

+

Create a new poll

+ + + + diff --git a/wortschlucker/wortschlucker.py b/wortschlucker/wortschlucker.py new file mode 100755 index 0000000..2fd5ad3 --- /dev/null +++ b/wortschlucker/wortschlucker.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python2.6 + +# add the current directory to the python search path +import sys +sys.path.insert(0, "./") + +import forms +import sqlobject +import bobo +from genshi.template import TemplateLoader +import genshi +import formencode +import uuid +import datetime +import os + +db_filename = "database.sqlite" +db_filename = os.path.abspath(db_filename) +database = sqlobject.connectionForURI("sqlite://" + db_filename) +sqlobject.sqlhub.processConnection = database +loader = TemplateLoader(os.path.join(os.path.dirname(__file__), 'templates'), auto_reload=True) + +BASE_DICT = { + "base_url": "/", # the trailing slash is necessary + "errors": {}, +} + +class WordSubmission(sqlobject.SQLObject): + submitter = sqlobject.StringCol() + content = sqlobject.StringCol() + poll_id = sqlobject.ForeignKey("Poll") + + +class Poll(sqlobject.SQLObject): + author = sqlobject.StringCol() + hash_key = sqlobject.StringCol() + title = sqlobject.StringCol() + description = sqlobject.StringCol() + timestamp_creation = sqlobject.DateTimeCol() + + def get_num_of_submitters(self): + all_submitters = [submission.submitter for submission in WordSubmission.selectBy(poll_id=self.id)] + unique_submitters = [] + for submitter in all_submitters: + if not submitter in unique_submitters: + unique_submitters.append(submitter) + return len(unique_submitters) + + def get_num_of_submissions(self): + return WordSubmission.selectBy(poll_id=self.id).count() + + def get_url(self): + return "%spolls/%s" % (BASE_DICT["base_url"], self.hash_key) + + def get_creation_time_string(self): + return str(self.timestamp_creation) + +def get_default_values(**kwargs): + value_dict = dict(BASE_DICT) + for key, value in kwargs.items(): + value_dict[key] = value + return value_dict + +def render(filename, **values): + return loader.load(filename).generate(**values).render("html", doctype="html") + +def get_poll_id(hash_key): + polls = Poll.selectBy(hash_key=hash_key) + if polls.count() == 1: + return polls[0].id + else: + return None + +def get_new_hash_key(): + hash_key = uuid.uuid4().get_hex() + while not get_poll_id(hash_key) is None: + hash_key = uuid.uuid4().get_hex() + return hash_key + +@bobo.query('/polls/new') +@bobo.query('/polls/new/:author/:title/:description') +def create_poll(cancel=False, author=None, title=None, description=None): + data = {"author": author, "title": title, "description": description} + value_dict = get_default_values() + if cancel: + return bobo.redirect(BASE_DICT["base_url"]) + elif (author is None) and (title is None) and (description is None): + return render("poll_new.html", **value_dict) + else: + errors = {} + try: + data = forms.PollForm.to_python(data) + except formencode.Invalid, errors_packed: + errors = errors_packed.unpack_errors() + if errors: + value_dict["errors"] = errors + return render("poll_new.html", **value_dict) + else: + # create the new poll + hash_key = get_new_hash_key() + now = datetime.datetime.now() + new_poll = Poll(hash_key=hash_key, timestamp_creation=now, **data) + return bobo.redirect(new_poll.get_url()) + +@bobo.query('') +@bobo.query('/') +@bobo.query('/polls') +@bobo.query('/polls/') +def show_polls(): + value_dict = get_default_values() + value_dict["polls"] = Poll.select() + return render("polls.html", **value_dict) + +@bobo.query('/polls/:poll_hash') +def show_one_poll(poll_hash=None): + poll_id = get_poll_id(poll_hash) + if not poll_id is None: + value_dict = get_default_values() + value_dict["poll"] = Poll.get(poll_id) + return render("poll_details.html", **value_dict) + else: + return bobo.redirect(BASE_DICT["base_url"]) + + +if not Poll.tableExists(): + #Poll.dropTable() + Poll.createTable() +if not WordSubmission.tableExists(): + WordSubmission.createTable() +for poll in Poll.select(): + print poll +