Mercurial > p > roundup > code
comparison roundup/cgi/form_parser.py @ 6939:38dc223d90cc
flake8 fixes - also change signature of parse()
removed num_re from parse. Variable is not used in method. Nothing
seems to call parse with the num_re. Also remove flake8 warning about
running compile when defining argument to method.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Thu, 08 Sep 2022 14:38:59 -0400 |
| parents | 408fd477761f |
| children |
comparison
equal
deleted
inserted
replaced
| 6938:075d8c6626b0 | 6939:38dc223d90cc |
|---|---|
| 1 import re, mimetypes | 1 import mimetypes |
| 2 import re | |
| 2 | 3 |
| 3 from roundup import hyperdb, date, password | 4 from roundup import hyperdb, date, password |
| 4 from roundup.cgi import templating, TranslationService | 5 from roundup.cgi import TranslationService |
| 5 from roundup.cgi.exceptions import FormError | 6 from roundup.cgi.exceptions import FormError |
| 6 | 7 |
| 7 | 8 |
| 8 class FormParser: | 9 class FormParser: |
| 9 # edit form variable handling (see unit tests) | 10 # edit form variable handling (see unit tests) |
| 40 except AttributeError: | 41 except AttributeError: |
| 41 _translator = TranslationService.get_translation() | 42 _translator = TranslationService.get_translation() |
| 42 self._ = self.gettext = _translator.gettext | 43 self._ = self.gettext = _translator.gettext |
| 43 self.ngettext = _translator.ngettext | 44 self.ngettext = _translator.ngettext |
| 44 | 45 |
| 45 def parse(self, create=0, num_re=re.compile(r'^\d+$')): | 46 def parse(self, create=0): |
| 46 """ Item properties and their values are edited with html FORM | 47 """ Item properties and their values are edited with html FORM |
| 47 variables and their values. You can: | 48 variables and their values. You can: |
| 48 | 49 |
| 49 - Change the value of some property of the current item. | 50 - Change the value of some property of the current item. |
| 50 - Create a new item of any class, and edit the new item's | 51 - Create a new item of any class, and edit the new item's |
| 285 if d['link']: | 286 if d['link']: |
| 286 value = [] | 287 value = [] |
| 287 for entry in self.extractFormList(form[key]): | 288 for entry in self.extractFormList(form[key]): |
| 288 m = self.FV_DESIGNATOR.match(entry) | 289 m = self.FV_DESIGNATOR.match(entry) |
| 289 if not m: | 290 if not m: |
| 290 raise FormError(self._('link "%(key)s" ' | 291 raise FormError(self._( |
| 292 'link "%(key)s" ' | |
| 291 'value "%(entry)s" not a designator') % locals()) | 293 'value "%(entry)s" not a designator') % locals()) |
| 292 value.append((m.group(1), m.group(2))) | 294 value.append((m.group(1), m.group(2))) |
| 293 | 295 |
| 294 # get details of linked class | 296 # get details of linked class |
| 295 lcn = m.group(1) | 297 lcn = m.group(1) |
| 303 got_props[(lcn, lnodeid)] = {} | 305 got_props[(lcn, lnodeid)] = {} |
| 304 | 306 |
| 305 # make sure the link property is valid | 307 # make sure the link property is valid |
| 306 if (not isinstance(propdef[propname], hyperdb.Multilink) and | 308 if (not isinstance(propdef[propname], hyperdb.Multilink) and |
| 307 not isinstance(propdef[propname], hyperdb.Link)): | 309 not isinstance(propdef[propname], hyperdb.Link)): |
| 308 raise FormError(self._('%(class)s %(property)s ' | 310 raise FormError(self._( |
| 309 'is not a link or multilink property') % { | 311 '%(class)s %(property)s ' |
| 310 'class':cn, 'property':propname}) | 312 'is not a link or multilink property') % { |
| 313 'class': cn, 'property': propname}) | |
| 311 | 314 |
| 312 all_links.append((cn, nodeid, propname, value)) | 315 all_links.append((cn, nodeid, propname, value)) |
| 313 continue | 316 continue |
| 314 | 317 |
| 315 # detect the special ":required" variable | 318 # detect the special ":required" variable |
| 316 if d['required']: | 319 if d['required']: |
| 317 for entry in self.extractFormList(form[key]): | 320 for entry in self.extractFormList(form[key]): |
| 318 m = self.FV_SPECIAL.match(entry) | 321 m = self.FV_SPECIAL.match(entry) |
| 319 if not m: | 322 if not m: |
| 320 raise FormError(self._('The form action claims to ' | 323 raise FormError(self._( |
| 324 'The form action claims to ' | |
| 321 'require property "%(property)s" ' | 325 'require property "%(property)s" ' |
| 322 'which doesn\'t exist') % { | 326 'which doesn\'t exist') % { |
| 323 'property':propname}) | 327 'property': propname}) |
| 324 if m.group('classname'): | 328 if m.group('classname'): |
| 325 this = (m.group('classname'), m.group('id')) | 329 this = (m.group('classname'), m.group('id')) |
| 326 entry = m.group('propname') | 330 entry = m.group('propname') |
| 327 if this not in all_required: | 331 if this not in all_required: |
| 328 all_required[this] = [] | 332 all_required[this] = [] |
| 337 mlaction = 'add' | 341 mlaction = 'add' |
| 338 | 342 |
| 339 # does the property exist? | 343 # does the property exist? |
| 340 if propname not in propdef: | 344 if propname not in propdef: |
| 341 if mlaction != 'set': | 345 if mlaction != 'set': |
| 342 raise FormError(self._('You have submitted a %(action)s ' | 346 raise FormError(self._( |
| 347 'You have submitted a %(action)s ' | |
| 343 'action for the property "%(property)s" ' | 348 'action for the property "%(property)s" ' |
| 344 'which doesn\'t exist') % { | 349 'which doesn\'t exist') % { |
| 345 'action': mlaction, 'property': propname}) | 350 'action': mlaction, 'property': propname}) |
| 346 # the form element is probably just something we don't care | 351 # the form element is probably just something we don't care |
| 347 # about - ignore it | 352 # about - ignore it |
| 348 continue | 353 continue |
| 349 proptype = propdef[propname] | 354 proptype = propdef[propname] |
| 350 | 355 |
| 362 elif isinstance(proptype, hyperdb.Multilink): | 367 elif isinstance(proptype, hyperdb.Multilink): |
| 363 value = self.extractFormList(value) | 368 value = self.extractFormList(value) |
| 364 else: | 369 else: |
| 365 # multiple values are not OK | 370 # multiple values are not OK |
| 366 if isinstance(value, type([])): | 371 if isinstance(value, type([])): |
| 367 raise FormError(self._('You have submitted more than one ' | 372 raise FormError(self._( |
| 373 'You have submitted more than one ' | |
| 368 'value for the %s property') % propname) | 374 'value for the %s property') % propname) |
| 369 # value might be a single file upload | 375 # value might be a single file upload |
| 370 if not getattr(value, 'filename', None): | 376 if not getattr(value, 'filename', None): |
| 371 value = value.value.strip() | 377 value = value.value.strip() |
| 372 | 378 |
| 390 break | 396 break |
| 391 else: | 397 else: |
| 392 raise FormError(self._('Password and confirmation text ' | 398 raise FormError(self._('Password and confirmation text ' |
| 393 'do not match')) | 399 'do not match')) |
| 394 if isinstance(confirm, type([])): | 400 if isinstance(confirm, type([])): |
| 395 raise FormError(self._('You have submitted more than one ' | 401 raise FormError(self._( |
| 402 'You have submitted more than one ' | |
| 396 'value for the %s property') % propname) | 403 'value for the %s property') % propname) |
| 397 if value != confirm.value: | 404 if value != confirm.value: |
| 398 raise FormError(self._('Password and confirmation text ' | 405 raise FormError(self._('Password and confirmation text ' |
| 399 'do not match')) | 406 'do not match')) |
| 400 try: | 407 try: |
| 430 value = None | 437 value = None |
| 431 nodeid = None | 438 nodeid = None |
| 432 elif isinstance(proptype, hyperdb.Multilink): | 439 elif isinstance(proptype, hyperdb.Multilink): |
| 433 # convert input to list of ids | 440 # convert input to list of ids |
| 434 try: | 441 try: |
| 435 l = hyperdb.rawToHyperdb(self.db, cl, nodeid, | 442 id_list = hyperdb.rawToHyperdb(self.db, cl, nodeid, |
| 436 propname, value) | 443 propname, value) |
| 437 except hyperdb.HyperdbValueError as msg: | 444 except hyperdb.HyperdbValueError as msg: |
| 438 raise FormError(msg) | 445 raise FormError(msg) |
| 439 | 446 |
| 440 # now use that list of ids to modify the multilink | 447 # now use that list of ids to modify the multilink |
| 441 if mlaction == 'set': | 448 if mlaction == 'set': |
| 442 value = l | 449 value = id_list |
| 443 else: | 450 else: |
| 444 # we're modifying the list - get the current list of ids | 451 # we're modifying the list - get the current list of ids |
| 445 if propname in props: | 452 if propname in props: |
| 446 existing = props[propname] | 453 existing = props[propname] |
| 447 elif nodeid and not nodeid.startswith('-'): | 454 elif nodeid and not nodeid.startswith('-'): |
| 451 | 458 |
| 452 # now either remove or add | 459 # now either remove or add |
| 453 if mlaction == 'remove': | 460 if mlaction == 'remove': |
| 454 # remove - handle situation where the id isn't in | 461 # remove - handle situation where the id isn't in |
| 455 # the list | 462 # the list |
| 456 for entry in l: | 463 for entry in id_list: |
| 457 try: | 464 try: |
| 458 existing.remove(entry) | 465 existing.remove(entry) |
| 459 except ValueError: | 466 except ValueError: |
| 460 raise FormError(self._('property ' | 467 raise FormError(self._( |
| 468 'property ' | |
| 461 '"%(propname)s": "%(value)s" ' | 469 '"%(propname)s": "%(value)s" ' |
| 462 'not currently in list') % { | 470 'not currently in list') % { |
| 463 'propname': propname, 'value': entry}) | 471 'propname': propname, 'value': entry}) |
| 464 else: | 472 else: |
| 465 # add - easy, just don't dupe | 473 # add - easy, just don't dupe |
| 466 for entry in l: | 474 for entry in id_list: |
| 467 if entry not in existing: | 475 if entry not in existing: |
| 468 existing.append(entry) | 476 existing.append(entry) |
| 469 value = existing | 477 value = existing |
| 470 # Sort the value in the same order used by | 478 # Sort the value in the same order used by |
| 471 # Multilink.from_raw. | 479 # Multilink.from_raw. |
| 477 else: | 485 else: |
| 478 # handle all other types | 486 # handle all other types |
| 479 try: | 487 try: |
| 480 # Try handling file upload | 488 # Try handling file upload |
| 481 if (isinstance(proptype, hyperdb.String) and | 489 if (isinstance(proptype, hyperdb.String) and |
| 482 hasattr(value, 'filename') and | 490 hasattr(value, 'filename') and |
| 483 value.filename is not None): | 491 value.filename is not None): |
| 484 value = self.parse_file(propdef, props, value) | 492 value = self.parse_file(propdef, props, value) |
| 485 else: | 493 else: |
| 486 value = hyperdb.rawToHyperdb(self.db, cl, nodeid, | 494 value = hyperdb.rawToHyperdb(self.db, cl, nodeid, |
| 487 propname, value) | 495 propname, value) |
| 488 except hyperdb.HyperdbValueError as msg: | 496 except hyperdb.HyperdbValueError as msg: |
| 520 if isinstance(proptype, hyperdb.String): | 528 if isinstance(proptype, hyperdb.String): |
| 521 # some backends store "missing" Strings as | 529 # some backends store "missing" Strings as |
| 522 # empty strings | 530 # empty strings |
| 523 if existing == self.db.BACKEND_MISSING_STRING: | 531 if existing == self.db.BACKEND_MISSING_STRING: |
| 524 existing = None | 532 existing = None |
| 525 elif isinstance(proptype, hyperdb.Number) or \ | 533 elif (isinstance(proptype, hyperdb.Number) or |
| 526 isinstance(proptype, hyperdb.Integer): | 534 isinstance(proptype, hyperdb.Integer)): |
| 527 # some backends store "missing" Numbers as 0 :( | 535 # some backends store "missing" Numbers as 0 :( |
| 528 if existing == self.db.BACKEND_MISSING_NUMBER: | 536 if existing == self.db.BACKEND_MISSING_NUMBER: |
| 529 existing = None | 537 existing = None |
| 530 elif isinstance(proptype, hyperdb.Boolean): | 538 elif isinstance(proptype, hyperdb.Boolean): |
| 531 # likewise Booleans | 539 # likewise Booleans |
