diff --git a/wortschlucker/src/wortschlucker.py b/wortschlucker/src/wortschlucker.py index 824905a..69a95d6 100755 --- a/wortschlucker/src/wortschlucker.py +++ b/wortschlucker/src/wortschlucker.py @@ -1,4 +1,5 @@ #!/usr/bin/env python2.6 +# -*- coding: utf-8 -*- import os # the basedir is the parent dir of the location of this script @@ -94,6 +95,12 @@ class Poll(sqlobject.SQLObject): description = sqlobject.UnicodeCol() timestamp_creation = sqlobject.DateTimeCol() + def get_related_polls(self): + related = [] + related.extend([poll.second for poll in PollRelation.selectBy(first=self.id)]) + related.extend([poll.first for poll in PollRelation.selectBy(second=self.id)]) + return related + def get_settings(self): current_dict = {} for setting in PollSetting.selectBy(poll_id=self.id): @@ -202,6 +209,11 @@ def render(filename, input_data=None, **values): return stream.render("html", doctype="html") def get_poll_id(hash_key): + if isinstance(hash_key, unicode): + try: + hash_key = str(hash_key) + except UnicodeEncodeError: + return None polls = Poll.selectBy(hash_key=hash_key) if polls.count() == 1: return polls[0].id @@ -209,12 +221,32 @@ def get_poll_id(hash_key): return None def get_poll_admin_id(hash_key): + if isinstance(hash_key, unicode): + try: + hash_key = str(hash_key) + except UnicodeEncodeError: + return None polls = Poll.selectBy(admin_hash_key=hash_key) if polls.count() == 1: return polls[0].id else: return None +def extract_poll_admin_id(text): + """ The text may be an admin hash or a the admin link of a poll """ + result = get_poll_admin_id(text) + if result is None: + extracted_text = re.findall(r"[a-z0-9]+", text) + # we assume that the hash is at the end of the string + extracted_text.reverse() + for found in extracted_text: + guess = get_poll_admin_id(found) + if not guess is None: + return guess + return None + else: + return result + def get_new_hash_key(length=16, charset=None): """ returns a quite random hash key with the specified length """ if charset is None: @@ -390,8 +422,39 @@ def show_frontpage(): value_dict["polls"] = Poll.select() return render("frontpage.html", **value_dict) +def render_poll_admin(poll, add_related, del_related): + value_dict = get_default_values() + errors = {} + if not add_related is None: + other_poll_id = extract_poll_admin_id(add_related) + if other_poll_id == poll.id: + errors["related"] = u"Wortschlucker kann nicht mit sich selbst verknüpft werden" + elif other_poll_id is None: + errors["related"] = u"Wortschlucker nicht gefunden" + else: + related_polls = poll.get_related_polls() + if other_poll_id in [one_poll.id for one_poll in related_polls]: + errors["related"] = u"Dieser Wortschlucker wurde bereits verknüpft" + else: + PollRelation(first=poll.id, second=other_poll_id) + if not del_related is None: + other_poll_id = extract_poll_admin_id(del_related) + if other_poll_id is None: + errors["related"] = u"Wortschlucker nicht gefunden" + else: + related_polls = poll.get_related_polls() + if not other_poll_id in [one_poll.id for one_poll in related_polls]: + errors["related"] = u"Dieser Wortschlucker war nicht verknüpft" + else: + # delete all relations between these two polls + PollRelation.deleteBy(first=poll.id, second=other_poll_id) + PollRelation.deleteBy(first=other_poll_id, second=poll.id) + value_dict["poll"] = poll + value_dict["errors"] = errors + return render("poll_admin_details.html", **value_dict) + @bobo.query('/:poll_hash') -def show_one_poll(poll_hash=None): +def show_one_poll(poll_hash=None, add_related=None, del_related=None): value_dict = get_default_values() poll_id = get_poll_id(poll_hash) if not poll_id is None: @@ -400,8 +463,7 @@ def show_one_poll(poll_hash=None): else: admin_poll_id = get_poll_admin_id(poll_hash) if not admin_poll_id is None: - value_dict["poll"] = Poll.get(admin_poll_id) - return render("poll_admin_details.html", **value_dict) + return render_poll_admin(Poll.get(admin_poll_id), add_related, del_related) else: return bobo.redirect(BASE_DICT["base_url"])