changeset 1671:c4b58c65830f

merged
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Mon, 13 Aug 2012 10:23:43 +0200
parents fa66e4447d63 (current diff) d3a1a3e7075f (diff)
children dcea928c99bf b0ba46ffe914
files
diffstat 2 files changed, 57 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/forms.py	Mon Aug 13 00:34:15 2012 +0200
+++ b/MoinMoin/forms.py	Mon Aug 13 10:23:43 2012 +0200
@@ -13,10 +13,14 @@
 import json
 
 from flatland import Element, Form, String, Integer, Boolean, Enum, Dict, DateTime as _DateTime, JoinedString
+from flatland.util import class_cloner, Unspecified
 from flatland.validation import Validator, Present, IsEmail, ValueBetween, URLValidator, Converted, ValueAtLeast
 from flatland.exc import AdaptationError
 
+from flask import g as flaskg
+
 from MoinMoin.constants.forms import *
+from MoinMoin.constants.keys import ITEMID, NAME
 from MoinMoin.i18n import _, L_, N_
 from MoinMoin.security.textcha import TextCha, TextChaizedForm, TextChaValid
 from MoinMoin.util.forms import FileStorage
@@ -140,3 +144,45 @@
 Submit = String.using(default=L_('OK'), optional=True).with_properties(widget=WIDGET_SUBMIT, class_=CLASS_BUTTON)
 
 Hidden = String.using(optional=True).with_properties(widget=WIDGET_HIDDEN)
+
+
+# XXX When some user chooses a Reference candidate that is removed before the
+# user POSTs, the validator fails. This can be confusing.
+class ValidReference(Validator):
+    """
+    Validator for Reference
+    """
+    invalid_reference_msg = L_('Invalid Reference.')
+
+    def validate(self, element, state):
+        if element.value not in element.valid_values:
+            return self.note_error(element, state, 'invalid_reference_msg')
+        return True
+
+class Reference(Select.with_properties(empty_label=L_(u'(None)')).validated_by(ValidReference())):
+    """
+    A metadata property that points to another item selected out of the
+    Results of a search query.
+    """
+    @class_cloner
+    def to(cls, query, query_args={}):
+        cls._query = query
+        cls._query_args = query_args
+        return cls
+
+    @classmethod
+    def _get_choices(cls):
+        revs = flaskg.storage.search(cls._query, **cls._query_args)
+        choices = [(rev.meta[ITEMID], rev.meta[NAME]) for rev in revs]
+        if cls.optional:
+            choices.append((u'', cls.properties['empty_label']))
+        return choices
+
+    def __init__(self, value=Unspecified, **kw):
+        super(Reference, self).__init__(value, **kw)
+        # NOTE There is a slight chance of two instances of the same Reference
+        # subclass having different set of choices when the storage changes
+        # between their initialization.
+        choices = self._get_choices()
+        self.properties['labels'] = dict(choices)
+        self.valid_values = [id_ for id_, name in choices]
--- a/MoinMoin/items/__init__.py	Mon Aug 13 00:34:15 2012 +0200
+++ b/MoinMoin/items/__init__.py	Mon Aug 13 10:23:43 2012 +0200
@@ -629,14 +629,6 @@
 
 
 @register
-class Ticket(Contentful):
-    """
-    Stub for ticket item class.
-    """
-    itemtype = u'ticket'
-
-
-@register
 class Userprofile(Item):
     """
     Currently userprofile is implemented as a contenttype. This is a stub of an
@@ -658,11 +650,13 @@
 
     def do_show(self, revid):
         # First, check if the current user has the required privileges
-        if not flaskg.user.may.create(self.name):
-            return render_template('show_nonexistent.html',
-                                   item_name=self.name,
-                                  )
-        return Response(self._select_itemtype(), 404)
+        if flaskg.user.may.create(self.name):
+            content = self._select_itemtype()
+        else:
+            content = render_template('show_nonexistent.html',
+                                      item_name=self.name,
+                                     )
+        return Response(content, 404)
 
     def do_modify(self):
         # First, check if the current user has the required privileges
@@ -713,3 +707,7 @@
     class _ModifyForm(Default._ModifyForm):
         meta_form = BlogEntryMetaForm
         meta_template = 'modify_blog_entry_meta.html'
+
+
+from ..util.pysupport import load_package_modules
+load_package_modules(__name__, __path__)