Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Log invalid fields when disable-constraints is True #6

Merged
merged 5 commits into from

2 participants

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 22, 2013
  1. @ebrehault
  2. @ebrehault

    update history

    ebrehault authored
  3. @ebrehault

    fix error logging

    ebrehault authored
Commits on Nov 4, 2013
  1. @ebrehault

    merge with master

    ebrehault authored
Commits on Jan 22, 2014
  1. @ebrehault
This page is out of date. Refresh to see the latest.
View
3  docs/HISTORY.txt
@@ -5,7 +5,8 @@ Changelog
1.3 (unreleased)
----------------
-- Nothing changed yet.
+- Add 'logger' and 'loglevel' options so invalid fields are logged when
+ disable-constraints is True [ebrehault]
1.2 (2013-08-29)
View
1  setup.py
@@ -8,6 +8,7 @@
'plone.app.testing',
'plone.app.dexterity',
'plone.namedfile[blobs]',
+ 'plone.directives.form',
]
setup(name='transmogrify.dexterity',
version=version,
View
94 transmogrify/dexterity/converters.py
@@ -48,7 +48,7 @@ class NamedFileDeserializer(object):
def __init__(self, field):
self.field = field
- def __call__(self, value, filestore, item, disable_constraints=False):
+ def __call__(self, value, filestore, item, disable_constraints=False, logger=None):
if isinstance(value, dict):
filename = value.get('filename', None)
contenttype = str(value.get('contenttype', ''))
@@ -70,8 +70,19 @@ def __call__(self, value, filestore, item, disable_constraints=False):
filename=filename,
contentType=contenttype,
)
- if not disable_constraints:
+ try:
self.field.validate(instance)
+ except Exception, e:
+ if not disable_constraints:
+ raise e
+ else:
+ if logger:
+ logger(
+ "%s is invalid in %s: %s" % (
+ self.field.__name__,
+ item['_path'],
+ e)
+ )
return instance
@@ -109,7 +120,7 @@ def _convert_object(self,obj,encoding):
if isinstance(obj, unicode): return obj
raise ValueError('Unable to convert value to unicode string')
- def __call__(self, value, filestore, item, disable_constraints=False):
+ def __call__(self, value, filestore, item, disable_constraints=False, logger=None):
if isinstance(value, dict):
encoding = value.get('encoding', getSiteEncoding())
contenttype = value.get('contenttype', None)
@@ -132,14 +143,25 @@ def __call__(self, value, filestore, item, disable_constraints=False):
outputMimeType=self.field.output_mime_type,
encoding=encoding,
)
- if not disable_constraints:
+ try:
self.field.validate(instance)
+ except Exception, e:
+ if not disable_constraints:
+ raise e
+ else:
+ if logger:
+ logger(
+ "%s is invalid in %s: %s" % (
+ self.field.__name__,
+ item['_path'],
+ e)
+ )
return instance
class CollectionSerializer(object):
implements(ISerializer)
- adapts(ICollection)
+ adapts(ICollection)
def __init__(self, field):
self.field = field
@@ -160,7 +182,7 @@ class CollectionDeserializer(object):
def __init__(self, field):
self.field = field
- def __call__(self, value, filestore, item, disable_constraints=False):
+ def __call__(self, value, filestore, item, disable_constraints=False, logger=None):
field = self.field
if value in (None, ''):
return []
@@ -170,10 +192,21 @@ def __call__(self, value, filestore, item, disable_constraints=False):
deserializer = IDeserializer(self.field.value_type)
else:
deserializer = DefaultDeserializer()
- value = [deserializer(v, filestore, item, disable_constraints) for v in value]
+ value = [deserializer(v, filestore, item, disable_constraints, logger=logger) for v in value]
value = field._type(value)
- if not disable_constraints:
+ try:
self.field.validate(value)
+ except Exception, e:
+ if not disable_constraints:
+ raise e
+ else:
+ if logger:
+ logger(
+ "%s is invalid in %s: %s" % (
+ self.field.__name__,
+ item['_path'],
+ e)
+ )
return value
@@ -184,13 +217,24 @@ class DateDeserializer(object):
def __init__(self, field):
self.field = field
- def __call__(self, value, filestore, item, disable_constraints=False):
+ def __call__(self, value, filestore, item, disable_constraints=False, logger=None):
if isinstance(value, basestring):
value = datetime.strptime(value, '%Y-%m-%d')
if isinstance(value, datetime):
value = value.date()
- if not disable_constraints:
+ try:
self.field.validate(value)
+ except Exception, e:
+ if not disable_constraints:
+ raise e
+ else:
+ if logger:
+ logger(
+ "%s is invalid in %s: %s" % (
+ self.field.__name__,
+ item['_path'],
+ e)
+ )
return value
@@ -219,22 +263,24 @@ class DefaultDeserializer(object):
def __init__(self, field):
self.field = field
- def __call__(self, value, filestore, item, disable_constraints=False):
+ def __call__(self, value, filestore, item, disable_constraints=False, logger=None):
field = self.field
if field is not None:
- if isinstance(value, str):
- value = value.decode('utf-8')
- if isinstance(value, unicode):
- try:
+ try:
+ if isinstance(value, str):
+ value = value.decode('utf-8')
+ if isinstance(value, unicode):
value = IFromUnicode(field).fromUnicode(value)
- except ConstraintNotSatisfied:
- if not disable_constraints:
- raise ConstraintNotSatisfied(value)
- except TypeError, e:
- # TODO: This TypeError may happen because zope.schema._field.Choice._validate
- # tries to iterate over a vocabulary factory without calling it
- if not disable_constraints:
- raise e
- if not disable_constraints:
self.field.validate(value)
+ except Exception, e:
+ if not disable_constraints:
+ raise e
+ else:
+ if logger:
+ logger(
+ "%s is invalid in %s: %s" % (
+ self.field.__name__,
+ item['_path'],
+ e.__repr__())
+ )
return value
View
15 transmogrify/dexterity/schemaupdater.py
@@ -1,3 +1,5 @@
+import logging
+
from collective.transmogrifier.interfaces import ISectionBlueprint, ISection
from collective.transmogrifier.utils import defaultMatcher
from collective.transmogrifier.utils import Expression
@@ -36,6 +38,18 @@ def __init__(self, transmogrifier, name, options, previous):
options,
)
+ # create logger
+ if options.get('logger'):
+ self.logger = logging.getLogger(options['logger'])
+ self.loglevel = getattr(logging, options['loglevel'], None)
+ if self.loglevel is None:
+ # Assume it's an integer:
+ self.loglevel = int(options['loglevel'])
+ self.logger.setLevel(self.loglevel)
+ self.log = lambda s: self.logger.log(self.loglevel, s)
+ else:
+ self.log = None
+
def __iter__(self):
for item in self.previous:
pathkey = self.pathkey(*item.keys())[0]
@@ -80,6 +94,7 @@ def __iter__(self):
files,
item,
self.disable_constraints,
+ logger=self.log,
)
field.set(field.interface(obj), value)
continue
Something went wrong with that request. Please try again.