solves Issue #328, multiple name must be unique with all names, added a function to validatename which takes care of the issue
authorAshutosh Singla <ashu1461@gmail.com>
Tue, 09 Apr 2013 22:33:42 +0530
changeset 20857f4520c9b5f1
parent 2084 d366d1af5e1e
child 2086 a5b0f7551a56
solves Issue #328, multiple name must be unique with all names, added a function to validatename which takes care of the issue
MoinMoin/forms.py
MoinMoin/items/__init__.py
     1.1 --- a/MoinMoin/forms.py	Tue Apr 09 15:14:08 2013 +0530
     1.2 +++ b/MoinMoin/forms.py	Tue Apr 09 22:33:42 2013 +0530
     1.3 @@ -20,10 +20,12 @@
     1.4  from flatland.validation import Validator, Present, IsEmail, ValueBetween, URLValidator, Converted, ValueAtLeast
     1.5  from flatland.exc import AdaptationError
     1.6  
     1.7 +from whoosh.query import Term, Or, Not, And
     1.8 +
     1.9  from flask import g as flaskg
    1.10  
    1.11  from MoinMoin.constants.forms import *
    1.12 -from MoinMoin.constants.keys import ITEMID, NAME
    1.13 +from MoinMoin.constants.keys import ITEMID, NAME, LATEST_REVS
    1.14  from MoinMoin.i18n import _, L_, N_
    1.15  from MoinMoin.util.forms import FileStorage
    1.16  
    1.17 @@ -71,12 +73,36 @@
    1.18      """Validator for JSON
    1.19      """
    1.20      invalid_json_msg = L_('Invalid JSON.')
    1.21 +    invalid_name_msg = ""
    1.22 +
    1.23 +    def validname(self, meta, name, itemid):
    1.24 +        names = meta.get(NAME)
    1.25 +        if names is None:
    1.26 +            self.invalid_name_msg = L_("No name field in the JSON meta.")
    1.27 +            return False
    1.28 +        if len(names) != len(set(names)):
    1.29 +            self.invalid_name_msg = L_("The names in the JSON name list must be unique.")
    1.30 +            return False
    1.31 +        query = Or([Term(NAME, x) for x in names])
    1.32 +        if itemid is not None:
    1.33 +            query = And([query, Not(Term(ITEMID, itemid))])
    1.34 +        duplicate_names = set()
    1.35 +        with flaskg.storage.indexer.ix[LATEST_REVS].searcher() as searcher:
    1.36 +            results = searcher.search(query)
    1.37 +            for result in results:
    1.38 +                duplicate_names |= set([x for x in result[NAME] if x in names])
    1.39 +        if duplicate_names:
    1.40 +            self.invalid_name_msg = L_("Item(s) named %(duplicate_names)s already exist.", duplicate_names=", ".join(duplicate_names))
    1.41 +            return False
    1.42 +        return True
    1.43  
    1.44      def validate(self, element, state):
    1.45          try:
    1.46 -            json.loads(element.value)
    1.47 +            meta = json.loads(element.value)
    1.48          except:  # catch ANY exception that happens due to unserializing
    1.49              return self.note_error(element, state, 'invalid_json_msg')
    1.50 +        if not self.validname(meta, state[NAME], state[ITEMID]):
    1.51 +            return self.note_error(element, state, 'invalid_name_msg')
    1.52          return True
    1.53  
    1.54  JSON = OptionalMultilineText.with_properties(lang='en', dir='ltr').validated_by(ValidJSON())
     2.1 --- a/MoinMoin/items/__init__.py	Tue Apr 09 15:14:08 2013 +0530
     2.2 +++ b/MoinMoin/items/__init__.py	Tue Apr 09 22:33:42 2013 +0530
     2.3 @@ -727,7 +727,8 @@
     2.4                      # break them
     2.5                      return "OK"
     2.6              form = self.ModifyForm.from_request(request)
     2.7 -            if form.validate():
     2.8 +            state = dict(name=self.name, itemid=self.meta.get(ITEMID))
     2.9 +            if form.validate(state):
    2.10                  meta, data, contenttype_guessed, comment = form._dump(self)
    2.11                  contenttype_qs = request.values.get('contenttype')
    2.12                  try: