Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def get_vcard_property_param_values(values_string):
"""
Get the parameter values. RFC 2426 page 29.
@param values_string: Comma separated values
@return: Set of values. Assumes that sequence doesn't matter and that
duplicate values can be discarded, even though RFC 2426 doesn't explicitly
say this. I.e., assumes that TYPE=WORK,VOICE,WORK === TYPE=VOICE,WORK.
"""
values = set(vcard_utils.split_unescaped(values_string, ','))
# Validate
for value in values:
if not re.match(u'^[{0}]+$|^"[{1}]+"$'.format(
re.escape(SAFE_CHARACTERS), re.escape(QUOTE_SAFE_CHARACTERS)), value):
raise VCardValueError('{0}: {1}'.format(NOTE_INVALID_VALUE, value), {})
return values
def get_vcard_property_parameter(param_string):
"""
Get the parameter name and value(s). RFC 2426 page 29.
@param param_string: Single parameter and values
@return: Dictionary with a parameter name and values
"""
try:
param_name, values_string = vcard_utils.split_unescaped(param_string, '=')
except ValueError as error:
raise VCardItemCountError('{0}: {1}'.format(NOTE_MISSING_PARAM_VALUE, str(error)), {})
values = get_vcard_property_param_values(values_string)
# Validate
if not re.match('^[{0}]+$'.format(re.escape(ID_CHARACTERS)), param_name):
raise VCardNameError('{0}: {1}'.format(NOTE_INVALID_PARAMETER_NAME, param_name), {})
return {'name': param_name, 'values': values}
def get_vcard_property_sub_values(value_string):
"""
Get the parts of the value.
@param value_string: Single value string
@return: List of values (RFC 2426 page 9)
"""
sub_values = vcard_utils.split_unescaped(value_string, ',')
# Validate string
for sub_value in sub_values:
if not re.match(u'^[{0}]*$'.format(re.escape(VALUE_CHARACTERS)), sub_value):
raise VCardValueError('{0}: {1}'.format(NOTE_INVALID_SUB_VALUE, sub_value), {})
return sub_values
Get a single property.
@param property_line: Single unfolded vCard line
@return: Dictionary with name, parameters and values
"""
property_parts = vcard_utils.split_unescaped(property_line, ':')
if len(property_parts) < 2:
raise VCardItemCountError('{0}: {1}'.format(NOTE_MISSING_VALUE_STRING, property_line), {})
elif len(property_parts) > 2:
# Merge - Colon doesn't have to be escaped in values
property_parts[1] = ':'.join(property_parts[1:])
property_parts = property_parts[:2]
property_string, values_string = property_parts
# Split property name and property parameters
property_name_and_params = vcard_utils.split_unescaped(property_string, ';')
property_ = VcardProperty(property_name_and_params.pop(0))
# String validation
if not property_.name.upper() in ALL_PROPERTIES and not re.match(
'^X-[{0}]+$'.format(re.escape(ID_CHARACTERS)), property_.name, re.IGNORECASE):
raise VCardNameError('{0}: {1}'.format(NOTE_INVALID_PROPERTY_NAME, property_.name), {})
try:
if len(property_name_and_params) != 0:
property_.parameters = get_vcard_property_params(';'.join(property_name_and_params))
property_.values = get_vcard_property_values(values_string)
# Validate
vcard_validators.validate_vcard_property(property_)
except VCardError as error:
def get_vcard_property_values(values_string):
"""
Get the property values.
@param values_string: Multiple value string
@return: List of values (RFC 2426 page 12)
"""
values = []
# Strip line ending
values_string = values_string[:-len(NEWLINE_CHARACTERS)]
sub_value_strings = vcard_utils.split_unescaped(values_string, ';')
for sub in sub_value_strings:
values.append(get_vcard_property_sub_values(sub))
return values
def get_vcard_property_params(params_string):
"""
Get the parameters and their values. RFC 2426 page 28.
@param params_string: Part of a vCard line between the first semicolon
and the first colon.
@return: Dictionary of parameters. Assumes that
TYPE=WORK;TYPE=WORK,VOICE === TYPE=VOICE,WORK === TYPE=VOICE;TYPE=WORK.
"""
params = {}
if not params_string:
return params
for parameter_string in vcard_utils.split_unescaped(params_string, ';'):
parameter = get_vcard_property_parameter(parameter_string)
param_name = parameter['name'].upper() # To be able to merge TYPE & type
if param_name not in params:
params[param_name] = parameter['values']
else:
# Merge
params[param_name] = params[param_name].union(parameter['values'])
return params