diff --git a/wortschlucker/src/forms.py b/wortschlucker/src/forms.py index 65a064f..d26ccb4 100644 --- a/wortschlucker/src/forms.py +++ b/wortschlucker/src/forms.py @@ -6,6 +6,11 @@ class PollForm(formencode.Schema): description = formencode.validators.UnicodeString(strip=True, not_empty=True) template = formencode.validators.UnicodeString(strip=True) +class PollSettingsForm(PollForm): + settings = formencode.validators.Set() + setting_expose_date = formencode.validators.UnicodeString(strip=True, not_empty=True) + setting_close_date = formencode.validators.UnicodeString(strip=True, not_empty=True) + class SubmitForm(formencode.Schema): submitter = formencode.validators.UnicodeString(strip=True, not_empty=True) content = formencode.validators.UnicodeString(strip=True, not_empty=True) diff --git a/wortschlucker/src/wortschlucker.py b/wortschlucker/src/wortschlucker.py index 2ca8bbd..c0717ed 100755 --- a/wortschlucker/src/wortschlucker.py +++ b/wortschlucker/src/wortschlucker.py @@ -34,17 +34,22 @@ BASE_DICT = { "errors": {}, } +# used as the default setting for expose/close dates +DEFAULT_DAYS_AHEAD = 7 +DATE_FORMAT = "%d.%m.%Y" +DEFAULT_DATE = datetime.datetime.now() + datetime.timedelta(days=DEFAULT_DAYS_AHEAD) + POLL_SETTINGS = { "show_all_submissions": (bool, True), "show_statistics": (bool, True), "public": (bool, False), - "expose_date": (int, 0), - "close_date": (int, 0), + "expose_date": (datetime.datetime, DEFAULT_DATE), + "close_date": (datetime.datetime, DEFAULT_DATE), } POLL_SETTING_TEMPLATES = { - "brainstorm": {"expose_date": 20}, - "cards": {"show_all_submissions": False, "close_date": 30}, + "brainstorm": {}, + "cards": {"show_all_submissions": False}, "feedback": {"show_all_submissions": False}, "evaluation": {"show_all_submissions": False}, "notes": {"show_statistics": False}, @@ -118,14 +123,22 @@ class Poll(sqlobject.SQLObject): current_dict[key] = meta_info[1] return current_dict + def get_settings_strings(self): + settings = self.get_settings() + result = {} + for key, value in settings.items(): + result[key] = get_poll_setting_string(key, value) + return result + def change_setting(self, key, value): validated_value = validate_poll_setting(key, value) if not validated_value is None: + validated_value = get_poll_setting_string(key, validated_value) poll_setting = PollSetting.selectBy(poll_id=self.id, key=key) if poll_setting.count() == 1: - poll_setting[0].value = str(validated_value) + poll_setting[0].value = validated_value elif poll_setting.count() == 0: - PollSetting(poll_id=self.id, key=key, value=str(validated_value)) + PollSetting(poll_id=self.id, key=key, value=validated_value) def get_num_of_submitters(self): all_submitters = [submission.submitter for submission in ContentSubmission.selectBy(poll_id=self.id)] @@ -195,6 +208,23 @@ class PollMesh: return self.related +def get_poll_setting_string(key, value): + if not key in POLL_SETTINGS.keys(): + return "" + setting_type = POLL_SETTINGS[key][0] + if setting_type in (basestring, unicode, str): + return value + elif setting_type == bool: + return str(value) + elif setting_type == datetime.datetime: + # some old entries are invalid + if value is None: + return "" + else: + return value.strftime(DATE_FORMAT) + else: + return str(value) + def validate_poll_setting(key, value): if not key in POLL_SETTINGS.keys(): return None @@ -203,17 +233,29 @@ def validate_poll_setting(key, value): return value elif setting_type == bool: if value is None: - value = "false" - if isinstance(value, bool): + return False + elif isinstance(value, bool): return value else: text = value.lower() - if text in ("0", "false", "no", "off", "disabled", "", None): + if text in ("0", "false", "no", "off", "disabled", ""): return False elif text in ("1", "true", "yes", "on", "enabled"): return True else: return None + elif setting_type == datetime.datetime: + if value is None: + # default: one week later + value = datetime.date.today() + datetime.timedelta(days=DEFAULT_DAYS_AHEAD) + elif type(value) == datetime.datetime: + pass + else: + try: + value = datetime.datetime.strptime(value, DATE_FORMAT) + except ValueError: + value = None + return value elif setting_type == int: if value is None: value = 0 @@ -396,6 +438,10 @@ def admin_poll(cancel=False, submit=None, admin_hash_key=None, author=None, data["title"] = poll.title if description is None: data["description"] = poll.description + if setting_expose_date is None: + setting_expose_date = poll.get_settings_strings()["expose_date"] + if setting_close_date is None: + setting_close_date = poll.get_settings_strings()["close_date"] poll_settings = poll.get_settings() # update the settings only after a submit (otherwise we clear all current settings) if submit: @@ -409,22 +455,26 @@ def admin_poll(cancel=False, submit=None, admin_hash_key=None, author=None, pass for setting_key in poll_settings.keys(): poll_settings[setting_key] = setting_key in settings - # store the new settings or create the new poll + # collect all errors errors = {} + # add boolean "settings" after forms validation - since there is no destination type + data["settings"] = [key for key, value in poll_settings.items() if value is True] + for key, value in (("expose_date", setting_expose_date), ("close_date", setting_close_date)): + validated_value = validate_poll_setting(key, value) + if validated_value is None: + # keep the entered value and report an error + errors[key] = u"Ungültiges Datum" + data["setting_%s" % key] = value + else: + data["setting_%s" % key] = get_poll_setting_string(key, validated_value) + # use the validator to check for possible errors if submit: # check for errors only if the content is submitted (not just rendered) try: - data = forms.PollForm.to_python(data) + data = forms.PollSettingsForm.to_python(data) except formencode.Invalid, errors_packed: errors = errors_packed.unpack_errors() - # add boolean "settings" after forms validation - since there is no destination type - data["settings"] = [key for key, value in poll_settings.items() if value is True] - validated_expose_date = validate_poll_setting("expose_date", setting_expose_date) - if not validated_expose_date is None: - data["setting_expose_date"] = validated_expose_date - validated_close_date = validate_poll_setting("close_date", setting_close_date) - if not validated_close_date is None: - data["setting_close_date"] = validated_close_date + # store the new settings if errors: value_dict["errors"] = errors return render("poll_admin_edit.html", input_data=data, **value_dict) @@ -437,7 +487,7 @@ def admin_poll(cancel=False, submit=None, admin_hash_key=None, author=None, current_settings = poll.get_settings() # update settings for key, value in poll_settings.items(): - if current_settings[key] != value: + if (POLL_SETTINGS[key][0] == bool) and (current_settings[key] != value): poll.change_setting(key, value) poll.change_setting("expose_date", data["setting_expose_date"]) poll.change_setting("close_date", data["setting_close_date"]) @@ -484,7 +534,6 @@ def show_poll_list(render_file, page_size, page=None, filter_private=True): page = 1 end = start + page_size - 1 value_dict["polls"] = polls[start : end + 1] - print value_dict["polls"] # show a link for the next page, if more polls are available value_dict["show_next_link"] = (end + 1 < len(polls)) value_dict["show_previous_link"] = (start > 0)