kopia lustrzana https://github.com/collective/icalendar
				
				
				
			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
							rodzic
							
								
									4551ea8180
								
							
						
					
					
						commit
						82acd96524
					
				|  | @ -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] | ||||
| 
 | ||||
|  |  | |||
|  | @ -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)) | ||||
| 
 | ||||
|     ######################### | ||||
|  |  | |||
|  | @ -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' | ||||
|         ) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Johannes Raggam
						Johannes Raggam