Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions vobject/behavior.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from . import base

properties_allow_localization = ['NAME','SUMMARY','DESCRIPTION','LOCATION']
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PROPERTIES_ALLOW_LOCALIZATION = set('NAME','SUMMARY','DESCRIPTION','LOCATION')


#------------------------ Abstract class for behavior --------------------------
class Behavior(object):
Expand Down Expand Up @@ -81,22 +82,52 @@ def validate(cls, obj, raiseException=False, complainUnrecognized=False):
return cls.lineValidate(obj, raiseException, complainUnrecognized)
elif isinstance(obj, base.Component):
count = {}
language_count = {} #example: {'SUMMARY': {'en': 1, 'ja': 1} , 'DESCRIPTION': {None: 1}}
for child in obj.getChildren():
if not child.validate(raiseException, complainUnrecognized):
return False
name = child.name.upper()
count[name] = count.get(name, 0) + 1

if isinstance(child, base.ContentLine) and name in properties_allow_localization:
# for some properties, we count separately with respect to language
lang = child.params.get('LANGUAGE', [])
if len(lang) == 0:
lang = None
elif len(lang) == 1:
lang = lang[0].lower()
elif len(lang) > 1:
if raiseException:
m = "Multiple language parameters specified for property {1}"
raise base.ValidateError(m.format(name))
return False
if name in language_count:
language_count[name][lang] = language_count[name].get(lang, 0) + 1
else:
language_count[name] = {lang: 1}
Comment on lines +104 to +107
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either only line 105 and no if-statement at all, or change line 105 to

language_count[name][lang] += 1

since you ensured that it exists in line 104


for key, val in cls.knownChildren.items():
if count.get(key, 0) < val[0]:
minimum_count = val[0]
if count.get(key, 0) < minimum_count:
if raiseException:
m = "{0} components must contain at least {1} {2}"
raise base.ValidateError(m .format(cls.name, val[0], key))
raise base.ValidateError(m .format(cls.name, minimum_count, key))
return False
if val[1] and count.get(key, 0) > val[1]:
if raiseException:
maximum_count = val[1]
if maximum_count and count.get(key, 0) > maximum_count:
if key in properties_allow_localization:
# check if the maximum is exceeded for any language
for lang, count_for_lang in language_count.get(key, {}).items():
if count_for_lang > maximum_count:
if raiseException:
m = "{0} components cannot contain more than {1} {2} with the same language"
raise base.ValidateError(m.format(cls.name, maximum_count, key))
return False
elif raiseException:
m = "{0} components cannot contain more than {1} {2}"
raise base.ValidateError(m.format(cls.name, val[1], key))
return False
raise base.ValidateError(m.format(cls.name, maximum_count, key))
else:
return False
return True
else:
err = "{0} is not a Component or Contentline".format(obj)
Expand Down