Remove ability to add property parameters via a value's params attribute when

adding via cal.add (that was only possible for custom value objects and makes
  up a strange API), but support a parameter attribute on cal.add's method
  signature to pass a dictionary with property parameter key/value pairs.
  Fixes #116.
pull/120/merge
Johannes Raggam 2013-12-26 09:27:59 +01:00
rodzic 4551ea8180
commit 82acd96524
4 zmienionych plików z 76 dodań i 13 usunięć

Wyświetl plik

@ -5,6 +5,13 @@ Changelog
4.0.dev (unreleased)
--------------------
- Remove ability to add property parameters via a value's params attribute when
adding via cal.add (that was only possible for custom value objects and makes
up a strange API), but support a parameter attribute on cal.add's method
signature to pass a dictionary with property parameter key/value pairs.
Fixes #116.
[thet]
- Backport some of Regebro's changes from his regebro-refactor branch.
[thet]

Wyświetl plik

@ -92,32 +92,56 @@ class Component(CaselessDict):
#############################
# handling of property values
def _encode(self, name, value, cond=1):
def _encode(self, name, value, parameters=None, encode=1):
"""Conditional convertion of values.
"""
if not cond:
if not encode:
return value
if isinstance(value, types_factory.all_types):
# Don't encode already encoded values.
return value
klass = types_factory.for_property(name)
obj = klass(value)
if hasattr(value, 'params') and len(value.params.keys()) > 0:
# TODO: How can a python native value have params?
obj.params = value.params
if parameters:
if isinstance(parameters, dict):
params = Parameters()
for key, item in parameters.items():
params[key] = item
parameters = params
assert isinstance(parameters, Parameters)
obj.params = parameters
return obj
def set(self, name, value, encode=1):
def set(self, name, value, parameters=None, encode=1):
if encode and isinstance(value, list) \
and name.lower() not in ['rdate', 'exdate']:
# Individually convert each value to an ical type except rdate and
# exdate, where lists of dates might be passed to vDDDLists.
self[name] = [self._encode(name, v, encode) for v in value]
self[name] = [self._encode(name, v, parameters, encode)
for v in value]
else:
self[name] = self._encode(name, value, encode)
self[name] = self._encode(name, value, parameters, encode)
def add(self, name, value, encode=1):
def add(self, name, value, parameters=None, encode=1):
"""Add a property.
:param name: Key name of the property.
:type name: string
:param value: Value of the property. Either of a basic Python type of
any of the icalendar's own property types.
:type value: Python native type or icalendar property type.
:param parameters: Property parameter dictionary for the value. Only
available, if encode is set to True.
:type parameters: Dictionary
:param encode: True, if the value should be encoded to one of
icalendar's own property types (Fallback is "vText")
or False, if not.
:type encode: Boolean
:returns: None
"""
if isinstance(value, datetime) and\
name.lower() in ('dtstamp', 'created', 'last-modified'):
@ -131,13 +155,13 @@ class Component(CaselessDict):
# If property already exists, append it. Otherwise create and set it.
if name in self:
oldval = self[name]
value = self._encode(name, value, encode)
value = self._encode(name, value, parameters, encode)
if isinstance(oldval, list):
oldval.append(value)
else:
self.set(name, [oldval, value], encode=0)
self.set(name, [oldval, value], None, encode=0)
else:
self.set(name, value, encode)
self.set(name, value, parameters, encode)
def _decode(self, name, value):
"""Internal for decoding property values.
@ -191,7 +215,7 @@ class Component(CaselessDict):
to that.
"""
if encode:
values = [self._encode(name, value, 1) for value in values]
values = [self._encode(name, value, encode=1) for value in values]
self[name] = types_factory['inline'](q_join(values))
#########################

Wyświetl plik

@ -189,3 +189,25 @@ END:VCALENDAR"""
cal = icalendar.Calendar.from_ical(ics.read())
cal # pep 8
ics.close()
def test_issue_116(self):
"""Issue #116/#117 - How to add 'X-APPLE-STRUCTURED-LOCATION'
"""
event = icalendar.Event()
event.add(
"X-APPLE-STRUCTURED-LOCATION",
"geo:-33.868900,151.207000",
parameters={
"VALUE": "URI",
"X-ADDRESS": "367 George Street Sydney CBD NSW 2000",
"X-APPLE-RADIUS": "72",
"X-TITLE": "367 George Street"
}
)
self.assertEqual(
event.to_ical(),
b'BEGIN:VEVENT\r\nX-APPLE-STRUCTURED-LOCATION;VALUE=URI;'
b'X-ADDRESS="367 George Street Sydney \r\n CBD NSW 2000";'
b'X-APPLE-RADIUS=72;X-TITLE="367 George Street":'
b'geo:-33.868900\r\n \\,151.207000\r\nEND:VEVENT\r\n'
)

Wyświetl plik

@ -222,6 +222,16 @@ class TestCalComponent(unittest.TestCase):
self.assertEqual(comp['ATTACH'], [u'me', 'you', binary])
def test_cal_Component_add_property_parameter(self):
# Test the for timezone correctness: dtstart should preserve it's
# timezone, crated, dtstamp and last-modified must be in UTC.
Component = icalendar.cal.Component
comp = Component()
comp.add('X-TEST-PROP', 'tryout.',
parameters={'prop1': 'val1', 'prop2': 'val2'})
lines = comp.to_ical().splitlines()
self.assertTrue(b"X-TEST-PROP;PROP1=val1;PROP2=val2:tryout." in lines)
def test_cal_Component_from_ical(self):
# Check for proper handling of TZID parameter of datetime properties
Component = icalendar.cal.Component