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 0000000..384bdb4 Binary files /dev/null and b/wortschlucker/database.sqlite differ diff --git a/wortschlucker/forms.py b/wortschlucker/forms.py new file mode 100644 index 0000000..5ea06ca --- /dev/null +++ b/wortschlucker/forms.py @@ -0,0 +1,7 @@ +import formencode + +class PollForm(formencode.Schema): + author = formencode.validators.UnicodeString(strip=True, not_empty=True) + title = formencode.validators.UnicodeString(strip=True, not_empty=True) + description = formencode.validators.UnicodeString(strip=True, not_empty=True) + diff --git a/wortschlucker/templates/layout.html b/wortschlucker/templates/layout.html new file mode 100644 index 0000000..4aaa229 --- /dev/null +++ b/wortschlucker/templates/layout.html @@ -0,0 +1,31 @@ + + + + + + + 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}

+ + + + + 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 +