From b0f109f3b95c414fa9eda4e5516430d8511d328c Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Thu, 26 Dec 2013 18:42:13 +0100 Subject: [PATCH] Support adding lists to a component property, which value already was a list and remove the Component.set method, which was only be used by add method. --- CHANGES.rst | 4 +++ src/icalendar/cal.py | 41 +++++++++++++++------------- src/icalendar/tests/test_unit_cal.py | 27 ++++++++++++++++-- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 95b73c1..cb0b171 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,10 @@ Changelog 4.0.dev (unreleased) -------------------- +- Support adding lists to a component property, which value already was a list + and remove the Component.set method, which was only be used by add method. + [thet] + - 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 diff --git a/src/icalendar/cal.py b/src/icalendar/cal.py index 12e6e74..e8edd16 100644 --- a/src/icalendar/cal.py +++ b/src/icalendar/cal.py @@ -112,16 +112,6 @@ class Component(CaselessDict): obj.params = parameters return obj - 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, parameters, encode) - for v in value] - else: - self[name] = self._encode(name, value, parameters, encode) - def add(self, name, value, parameters=None, encode=1): """Add a property. @@ -152,16 +142,29 @@ class Component(CaselessDict): # assume UTC for naive datetime instances value = pytz.utc.localize(value) - # If property already exists, append it. Otherwise create and set it. - if name in self: - oldval = self[name] - value = self._encode(name, value, parameters, encode) - if isinstance(oldval, list): - oldval.append(value) - else: - self.set(name, [oldval, value], None, encode=0) + # encode value + 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. + value = [self._encode(name, v, parameters, encode) for v in value] else: - self.set(name, value, parameters, encode) + value = self._encode(name, value, parameters, encode) + + # set value + if name in self: + # If property already exists, append it. + #if name == 'attendee': import pdb; pdb.set_trace() + oldval = self[name] + if isinstance(oldval, list): + if isinstance(value, list): + value = oldval + value + else: + oldval.append(value) + value = oldval + else: + value = [oldval, value] + self[name] = value def _decode(self, name, value): """Internal for decoding property values. diff --git a/src/icalendar/tests/test_unit_cal.py b/src/icalendar/tests/test_unit_cal.py index 4bdb371..4419f21 100644 --- a/src/icalendar/tests/test_unit_cal.py +++ b/src/icalendar/tests/test_unit_cal.py @@ -32,18 +32,39 @@ class TestCalComponent(unittest.TestCase): 'PRODID': '-//max m//icalendar.mxm.dk/'}) ) + ### ADD MULTIPLE VALUES TO A PROPERTY + # if you use the add method you don't have to considder if a value is # a list or not. c = Component() c.name = 'VEVENT' + + # add multiple values at once + c.add('attendee', + ['test@test.com', 'test2@test.com']) + + # or add one per line c.add('attendee', 'maxm@mxm.dk') c.add('attendee', 'test@example.dk') + + # add again multiple values at once to very concatenaton of lists + c.add('attendee', + ['test3@test.com', 'test4@test.com']) + self.assertEqual( c, - Event({'ATTENDEE': [prop.vCalAddress('maxm@mxm.dk'), - prop.vCalAddress('test@example.dk')]}) + Event({'ATTENDEE': [ + prop.vCalAddress('test@test.com'), + prop.vCalAddress('test2@test.com'), + prop.vCalAddress('maxm@mxm.dk'), + prop.vCalAddress('test@example.dk'), + prop.vCalAddress('test3@test.com'), + prop.vCalAddress('test4@test.com') + ]}) ) + ### + # You can get the values back directly ... c.add('prodid', '-//my product//') self.assertEqual(c['prodid'], prop.vText(u'-//my product//')) @@ -284,7 +305,7 @@ class TestCal(unittest.TestCase): event = icalendar.cal.Event() event['summary'] = 'Python meeting about calendaring' event['uid'] = '42' - event.set('dtstart', datetime(2005, 4, 4, 8, 0, 0)) + event.add('dtstart', datetime(2005, 4, 4, 8, 0, 0)) cal.add_component(event) self.assertEqual( cal.subcomponents[0].to_ical(),