def cnode2ical(cnode): """Convert a tree of cnodes to an ical calendar cnode: typically from Erebus2ICSVisitor return: icalendar.Calendar """ comp = Component() comp.name = cnode.name.upper() for k,v in cnode.attr.iteritems(): # If an attribute is a CNode, say n, we must add all the # attributes of n as parameters to the iCalendar element. We # first encode the value to the corresponding iCalendar value # (with types_factory, like icalendar.Component does # internally), and then add the parameters. if v.__class__ == CNode: target_class = types_factory.for_property(k) val = target_class(v.content) val.params = Parameters() for p,pv in v.attr.iteritems(): val.params[p] = pv comp.add(k, val, encode=0) else: comp.add(k, v, encode=1) for c in cnode.children: comp.add_component(cnode2ical(c)) return comp
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_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_format_event_blanks(self): component = Component() component.add('dtstart', datetime.datetime(2018, 2, 3, 13, 3, 4, tzinfo=pytz.UTC)) event = Event.from_vevent(component, pytz.UTC) user_config = UserConfig.new(Config('calbot.cfg.sample'), 'TEST') user_config.language = 'ru_RU.UTF-8' result = format_event(user_config, event) self.assertEqual( 'None\nСуббота, 03 февраля 2018, 13:03 UTC\nNone\nNone', result)
def test_format_event_real_html(self): component = Component() component.add('summary', 'Встреча ML-клуба') component.add('location', 'ул. Таубе, 5, Омск, Омская обл., Россия, 644037') component.add( 'description', '10 февраля в 11:00 пройдет 5-я встреча <a href="https://vk.com/mlomsk">ML клуба</a> в офисе <a href="https://vk.com/7bits">7bits</a>, Таубе 5. Регистрация на встречу: <a href="https://vk.com/away.php?to=http%3A%2F%2Fmlomsk.1der.link%2Fmeetup%2Fsignup&post=-141957789_74&cc_key=" target="_blank">mlomsk.1der.link/meetup/signup</a>.<br><br>В этот раз у нас будет 2 доклада:' ) timezone = pytz.timezone('Asia/Omsk') component.add( 'dtstart', datetime.datetime(2018, 2, 10, 11, 0, 0, tzinfo=timezone)) event = Event.from_vevent(component, timezone) user_config = UserConfig.new(Config('calbot.cfg.sample'), 'TEST') user_config.language = 'ru_RU.UTF-8' result = format_event(user_config, event) self.assertEqual( 'Встреча ML-клуба\nСуббота, 10 февраля 2018, 11:00 Asia/Omsk\nул. Таубе, 5, Омск, Омская обл., Россия, 644037\n10 февраля в 11:00 пройдет 5-я встреча ML клуба (https://vk.com/mlomsk) в офисе 7bits (https://vk.com/7bits), Таубе 5. Регистрация на встречу: mlomsk.1der.link/meetup/signup.\n\nВ этот раз у нас будет 2 доклада:', result)
def test_cal_Component_add(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( 'dtstart', datetime(2010, 10, 10, 10, 0, 0, tzinfo=pytz.timezone("Europe/Vienna"))) comp.add('created', datetime(2010, 10, 10, 12, 0, 0)) comp.add( 'dtstamp', datetime(2010, 10, 10, 14, 0, 0, tzinfo=pytz.timezone("Europe/Vienna"))) comp.add('last-modified', datetime(2010, 10, 10, 16, 0, 0, tzinfo=pytz.utc)) lines = comp.to_ical().splitlines() self.assertTrue( "DTSTART;TZID=Europe/Vienna;VALUE=DATE-TIME:20101010T100000" in lines) self.assertTrue("CREATED;VALUE=DATE-TIME:20101010T120000Z" in lines) self.assertTrue("DTSTAMP;VALUE=DATE-TIME:20101010T130000Z" in lines) self.assertTrue( "LAST-MODIFIED;VALUE=DATE-TIME:20101010T160000Z" in lines)
def test_cal_Component_add(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("dtstart", datetime(2010, 10, 10, 10, 0, 0, tzinfo=pytz.timezone("Europe/Vienna"))) comp.add("created", datetime(2010, 10, 10, 12, 0, 0)) comp.add("dtstamp", datetime(2010, 10, 10, 14, 0, 0, tzinfo=pytz.timezone("Europe/Vienna"))) comp.add("last-modified", datetime(2010, 10, 10, 16, 0, 0, tzinfo=pytz.utc)) lines = comp.to_ical().splitlines() self.assertTrue("DTSTART;TZID=Europe/Vienna;VALUE=DATE-TIME:20101010T100000" in lines) self.assertTrue("CREATED;VALUE=DATE-TIME:20101010T120000Z" in lines) self.assertTrue("DTSTAMP;VALUE=DATE-TIME:20101010T130000Z" in lines) self.assertTrue("LAST-MODIFIED;VALUE=DATE-TIME:20101010T160000Z" in lines)
def test_format_event_html(self): component = Component() component.add('summary', '<b>summary</b>') component.add('location', '<i>location</i>') component.add( 'description', '<b>description</b><br><br> <a href="link.html">link</a>') component.add('dtstart', datetime.datetime(2018, 2, 3, 13, 3, 4, tzinfo=pytz.UTC)) event = Event.from_vevent(component, pytz.UTC) user_config = UserConfig.new(Config('calbot.cfg.sample'), 'TEST') user_config.language = 'ru_RU.UTF-8' result = format_event(user_config, event) self.assertEqual( 'summary\nСуббота, 03 февраля 2018, 13:03 UTC\nlocation\ndescription\n\n link (link.html)', result)
def test_cal_Component(self): from icalendar.cal import Component, Calendar, Event from icalendar import prop # A component is like a dictionary with extra methods and attributes. c = Component() c.name = 'VCALENDAR' # Every key defines a property.A property can consist of either a # single item. This can be set with a single value... c['prodid'] = '-//max m//icalendar.mxm.dk/' self.assertEqual( c, Calendar({'PRODID': '-//max m//icalendar.mxm.dk/'}) ) # or with a list c['ATTENDEE'] = ['Max M', 'Rasmussen'] self.assertEqual( c, Calendar({'ATTENDEE': ['Max M', 'Rasmussen'], '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', ['*****@*****.**', '*****@*****.**']) # or add one per line c.add('attendee', '*****@*****.**') c.add('attendee', '*****@*****.**') # add again multiple values at once to very concatenaton of lists c.add('attendee', ['*****@*****.**', '*****@*****.**']) self.assertEqual( c, Event({'ATTENDEE': [ prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**') ]}) ) ### # You can get the values back directly ... c.add('prodid', '-//my product//') self.assertEqual(c['prodid'], prop.vText(u'-//my product//')) # ... or decoded to a python type self.assertEqual(c.decoded('prodid'), b'-//my product//') # With default values for non existing properties self.assertEqual(c.decoded('version', 'No Version'), 'No Version') c.add('rdate', [datetime(2013, 3, 28), datetime(2013, 3, 27)]) self.assertTrue(isinstance(c.decoded('rdate'), prop.vDDDLists)) # The component can render itself in the RFC 2445 format. c = Component() c.name = 'VCALENDAR' c.add('attendee', 'Max M') self.assertEqual( c.to_ical(), b'BEGIN:VCALENDAR\r\nATTENDEE:Max M\r\nEND:VCALENDAR\r\n' ) # Components can be nested, so You can add a subcompont. Eg a calendar # holds events. e = Component(summary='A brief history of time') e.name = 'VEVENT' e.add('dtend', '20000102T000000', encode=0) e.add('dtstart', '20000101T000000', encode=0) self.assertEqual( e.to_ical(), b'BEGIN:VEVENT\r\nDTEND:20000102T000000\r\n' + b'DTSTART:20000101T000000\r\nSUMMARY:A brief history of time\r' + b'\nEND:VEVENT\r\n' ) c.add_component(e) self.assertEqual( c.subcomponents, [Event({'DTEND': '20000102T000000', 'DTSTART': '20000101T000000', 'SUMMARY': 'A brief history of time'})] ) # We can walk over nested componentes with the walk method. self.assertEqual([i.name for i in c.walk()], ['VCALENDAR', 'VEVENT']) # We can also just walk over specific component types, by filtering # them on their name. self.assertEqual([i.name for i in c.walk('VEVENT')], ['VEVENT']) self.assertEqual( [i['dtstart'] for i in c.walk('VEVENT')], ['20000101T000000'] ) # We can enumerate property items recursively with the property_items # method. self.assertEqual( c.property_items(), [('BEGIN', b'VCALENDAR'), ('ATTENDEE', prop.vCalAddress('Max M')), ('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'), ('DTSTART', '20000101T000000'), ('SUMMARY', 'A brief history of time'), ('END', b'VEVENT'), ('END', b'VCALENDAR')] ) # We can also enumerate property items just under the component. self.assertEqual( c.property_items(recursive=False), [('BEGIN', b'VCALENDAR'), ('ATTENDEE', prop.vCalAddress('Max M')), ('END', b'VCALENDAR')] ) sc = c.subcomponents[0] self.assertEqual( sc.property_items(recursive=False), [('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'), ('DTSTART', '20000101T000000'), ('SUMMARY', 'A brief history of time'), ('END', b'VEVENT')] ) # Text fields which span multiple mulitple lines require proper # indenting c = Calendar() c['description'] = u'Paragraph one\n\nParagraph two' self.assertEqual( c.to_ical(), b'BEGIN:VCALENDAR\r\nDESCRIPTION:Paragraph one\\n\\nParagraph two' + b'\r\nEND:VCALENDAR\r\n' ) # INLINE properties have their values on one property line. Note the # double quoting of the value with a colon in it. c = Calendar() c['resources'] = 'Chair, Table, "Room: 42"' self.assertEqual( c, Calendar({'RESOURCES': 'Chair, Table, "Room: 42"'}) ) self.assertEqual( c.to_ical(), b'BEGIN:VCALENDAR\r\nRESOURCES:Chair\\, Table\\, "Room: 42"\r\n' + b'END:VCALENDAR\r\n' ) # The inline values must be handled by the get_inline() and # set_inline() methods. self.assertEqual( c.get_inline('resources', decode=0), [u'Chair', u'Table', u'Room: 42'] ) # These can also be decoded self.assertEqual( c.get_inline('resources', decode=1), [b'Chair', b'Table', b'Room: 42'] ) # You can set them directly ... c.set_inline('resources', ['A', 'List', 'of', 'some, recources'], encode=1) self.assertEqual(c['resources'], 'A,List,of,"some, recources"') # ... and back again self.assertEqual( c.get_inline('resources', decode=0), ['A', 'List', 'of', 'some, recources'] ) c['freebusy'] = '19970308T160000Z/PT3H,19970308T200000Z/PT1H,'\ + '19970308T230000Z/19970309T000000Z' self.assertEqual( c.get_inline('freebusy', decode=0), ['19970308T160000Z/PT3H', '19970308T200000Z/PT1H', '19970308T230000Z/19970309T000000Z'] ) freebusy = c.get_inline('freebusy', decode=1) self.assertTrue(isinstance(freebusy[0][0], datetime)) self.assertTrue(isinstance(freebusy[0][1], timedelta))
def test_cal_Component(self): from icalendar.cal import Component, Calendar, Event from icalendar import prop # A component is like a dictionary with extra methods and attributes. c = Component() c.name = 'VCALENDAR' # Every key defines a property.A property can consist of either a # single item. This can be set with a single value... c['prodid'] = '-//max m//icalendar.mxm.dk/' self.assertEqual(c, Calendar({'PRODID': '-//max m//icalendar.mxm.dk/'})) # or with a list c['ATTENDEE'] = ['Max M', 'Rasmussen'] self.assertEqual( c, Calendar({ 'ATTENDEE': ['Max M', 'Rasmussen'], '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', ['*****@*****.**', '*****@*****.**']) # or add one per line c.add('attendee', '*****@*****.**') c.add('attendee', '*****@*****.**') # add again multiple values at once to very concatenaton of lists c.add('attendee', ['*****@*****.**', '*****@*****.**']) self.assertEqual( c, Event({ 'ATTENDEE': [ prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**'), prop.vCalAddress('*****@*****.**') ] })) ### # You can get the values back directly ... c.add('prodid', '-//my product//') self.assertEqual(c['prodid'], prop.vText(u'-//my product//')) # ... or decoded to a python type self.assertEqual(c.decoded('prodid'), b'-//my product//') # With default values for non existing properties self.assertEqual(c.decoded('version', 'No Version'), 'No Version') c.add('rdate', [datetime(2013, 3, 28), datetime(2013, 3, 27)]) self.assertTrue(isinstance(c.decoded('rdate'), prop.vDDDLists)) # The component can render itself in the RFC 2445 format. c = Component() c.name = 'VCALENDAR' c.add('attendee', 'Max M') self.assertEqual( c.to_ical(), b'BEGIN:VCALENDAR\r\nATTENDEE:Max M\r\nEND:VCALENDAR\r\n') # Components can be nested, so You can add a subcompont. Eg a calendar # holds events. e = Component(summary='A brief history of time') e.name = 'VEVENT' e.add('dtend', '20000102T000000', encode=0) e.add('dtstart', '20000101T000000', encode=0) self.assertEqual( e.to_ical(), b'BEGIN:VEVENT\r\nDTEND:20000102T000000\r\n' + b'DTSTART:20000101T000000\r\nSUMMARY:A brief history of time\r' + b'\nEND:VEVENT\r\n') c.add_component(e) self.assertEqual(c.subcomponents, [ Event({ 'DTEND': '20000102T000000', 'DTSTART': '20000101T000000', 'SUMMARY': 'A brief history of time' }) ]) # We can walk over nested componentes with the walk method. self.assertEqual([i.name for i in c.walk()], ['VCALENDAR', 'VEVENT']) # We can also just walk over specific component types, by filtering # them on their name. self.assertEqual([i.name for i in c.walk('VEVENT')], ['VEVENT']) self.assertEqual([i['dtstart'] for i in c.walk('VEVENT')], ['20000101T000000']) # We can enumerate property items recursively with the property_items # method. self.assertEqual(c.property_items(), [('BEGIN', b'VCALENDAR'), ('ATTENDEE', prop.vCalAddress('Max M')), ('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'), ('DTSTART', '20000101T000000'), ('SUMMARY', 'A brief history of time'), ('END', b'VEVENT'), ('END', b'VCALENDAR')]) # We can also enumerate property items just under the component. self.assertEqual(c.property_items(recursive=False), [('BEGIN', b'VCALENDAR'), ('ATTENDEE', prop.vCalAddress('Max M')), ('END', b'VCALENDAR')]) sc = c.subcomponents[0] self.assertEqual(sc.property_items(recursive=False), [('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'), ('DTSTART', '20000101T000000'), ('SUMMARY', 'A brief history of time'), ('END', b'VEVENT')]) # Text fields which span multiple mulitple lines require proper # indenting c = Calendar() c['description'] = u'Paragraph one\n\nParagraph two' self.assertEqual( c.to_ical(), b'BEGIN:VCALENDAR\r\nDESCRIPTION:Paragraph one\\n\\nParagraph two' + b'\r\nEND:VCALENDAR\r\n') # INLINE properties have their values on one property line. Note the # double quoting of the value with a colon in it. c = Calendar() c['resources'] = 'Chair, Table, "Room: 42"' self.assertEqual(c, Calendar({'RESOURCES': 'Chair, Table, "Room: 42"'})) self.assertEqual( c.to_ical(), b'BEGIN:VCALENDAR\r\nRESOURCES:Chair\\, Table\\, "Room: 42"\r\n' + b'END:VCALENDAR\r\n') # The inline values must be handled by the get_inline() and # set_inline() methods. self.assertEqual(c.get_inline('resources', decode=0), [u'Chair', u'Table', u'Room: 42']) # These can also be decoded self.assertEqual(c.get_inline('resources', decode=1), [b'Chair', b'Table', b'Room: 42']) # You can set them directly ... c.set_inline('resources', ['A', 'List', 'of', 'some, recources'], encode=1) self.assertEqual(c['resources'], 'A,List,of,"some, recources"') # ... and back again self.assertEqual(c.get_inline('resources', decode=0), ['A', 'List', 'of', 'some, recources']) c['freebusy'] = '19970308T160000Z/PT3H,19970308T200000Z/PT1H,'\ + '19970308T230000Z/19970309T000000Z' self.assertEqual(c.get_inline('freebusy', decode=0), [ '19970308T160000Z/PT3H', '19970308T200000Z/PT1H', '19970308T230000Z/19970309T000000Z' ]) freebusy = c.get_inline('freebusy', decode=1) self.assertTrue(isinstance(freebusy[0][0], datetime)) self.assertTrue(isinstance(freebusy[0][1], timedelta))
def _get_component(): component = Component() component.add('summary', 'summary') component.add('location', 'location') component.add('description', 'description') return component
def test_cal_Component(self): from icalendar.cal import Component, Calendar, Event from icalendar import prop # A component is like a dictionary with extra methods and attributes. c = Component() c.name = "VCALENDAR" # Every key defines a property.A property can consist of either a # single item. This can be set with a single value... c["prodid"] = "-//max m//icalendar.mxm.dk/" self.assertEqual(c, Calendar({"PRODID": "-//max m//icalendar.mxm.dk/"})) # or with a list c["ATTENDEE"] = ["Max M", "Rasmussen"] self.assertEqual(c, Calendar({"ATTENDEE": ["Max M", "Rasmussen"], "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", ["*****@*****.**", "*****@*****.**"]) # or add one per line c.add("attendee", "*****@*****.**") c.add("attendee", "*****@*****.**") # add again multiple values at once to very concatenaton of lists c.add("attendee", ["*****@*****.**", "*****@*****.**"]) self.assertEqual( c, Event( { "ATTENDEE": [ prop.vCalAddress("*****@*****.**"), prop.vCalAddress("*****@*****.**"), prop.vCalAddress("*****@*****.**"), prop.vCalAddress("*****@*****.**"), prop.vCalAddress("*****@*****.**"), prop.vCalAddress("*****@*****.**"), ] } ), ) ### # You can get the values back directly ... c.add("prodid", "-//my product//") self.assertEqual(c["prodid"], prop.vText(u"-//my product//")) # ... or decoded to a python type self.assertEqual(c.decoded("prodid"), b"-//my product//") # With default values for non existing properties self.assertEqual(c.decoded("version", "No Version"), "No Version") c.add("rdate", [datetime(2013, 3, 28), datetime(2013, 3, 27)]) self.assertTrue(isinstance(c.decoded("rdate"), prop.vDDDLists)) # The component can render itself in the RFC 2445 format. c = Component() c.name = "VCALENDAR" c.add("attendee", "Max M") self.assertEqual(c.to_ical(), b"BEGIN:VCALENDAR\r\nATTENDEE:Max M\r\nEND:VCALENDAR\r\n") # Components can be nested, so You can add a subcompont. Eg a calendar # holds events. e = Component(summary="A brief history of time") e.name = "VEVENT" e.add("dtend", "20000102T000000", encode=0) e.add("dtstart", "20000101T000000", encode=0) self.assertEqual( e.to_ical(), b"BEGIN:VEVENT\r\nDTEND:20000102T000000\r\n" + b"DTSTART:20000101T000000\r\nSUMMARY:A brief history of time\r" + b"\nEND:VEVENT\r\n", ) c.add_component(e) self.assertEqual( c.subcomponents, [Event({"DTEND": "20000102T000000", "DTSTART": "20000101T000000", "SUMMARY": "A brief history of time"})], ) # We can walk over nested componentes with the walk method. self.assertEqual([i.name for i in c.walk()], ["VCALENDAR", "VEVENT"]) # We can also just walk over specific component types, by filtering # them on their name. self.assertEqual([i.name for i in c.walk("VEVENT")], ["VEVENT"]) self.assertEqual([i["dtstart"] for i in c.walk("VEVENT")], ["20000101T000000"]) # We can enumerate property items recursively with the property_items # method. self.assertEqual( c.property_items(), [ ("BEGIN", b"VCALENDAR"), ("ATTENDEE", prop.vCalAddress("Max M")), ("BEGIN", b"VEVENT"), ("DTEND", "20000102T000000"), ("DTSTART", "20000101T000000"), ("SUMMARY", "A brief history of time"), ("END", b"VEVENT"), ("END", b"VCALENDAR"), ], ) # We can also enumerate property items just under the component. self.assertEqual( c.property_items(recursive=False), [("BEGIN", b"VCALENDAR"), ("ATTENDEE", prop.vCalAddress("Max M")), ("END", b"VCALENDAR")], ) sc = c.subcomponents[0] self.assertEqual( sc.property_items(recursive=False), [ ("BEGIN", b"VEVENT"), ("DTEND", "20000102T000000"), ("DTSTART", "20000101T000000"), ("SUMMARY", "A brief history of time"), ("END", b"VEVENT"), ], ) # Text fields which span multiple mulitple lines require proper # indenting c = Calendar() c["description"] = u"Paragraph one\n\nParagraph two" self.assertEqual( c.to_ical(), b"BEGIN:VCALENDAR\r\nDESCRIPTION:Paragraph one\\n\\nParagraph two" + b"\r\nEND:VCALENDAR\r\n" ) # INLINE properties have their values on one property line. Note the # double quoting of the value with a colon in it. c = Calendar() c["resources"] = 'Chair, Table, "Room: 42"' self.assertEqual(c, Calendar({"RESOURCES": 'Chair, Table, "Room: 42"'})) self.assertEqual( c.to_ical(), b'BEGIN:VCALENDAR\r\nRESOURCES:Chair\\, Table\\, "Room: 42"\r\n' + b"END:VCALENDAR\r\n" ) # The inline values must be handled by the get_inline() and # set_inline() methods. self.assertEqual(c.get_inline("resources", decode=0), [u"Chair", u"Table", u"Room: 42"]) # These can also be decoded self.assertEqual(c.get_inline("resources", decode=1), [b"Chair", b"Table", b"Room: 42"]) # You can set them directly ... c.set_inline("resources", ["A", "List", "of", "some, recources"], encode=1) self.assertEqual(c["resources"], 'A,List,of,"some, recources"') # ... and back again self.assertEqual(c.get_inline("resources", decode=0), ["A", "List", "of", "some, recources"]) c["freebusy"] = "19970308T160000Z/PT3H,19970308T200000Z/PT1H," + "19970308T230000Z/19970309T000000Z" self.assertEqual( c.get_inline("freebusy", decode=0), ["19970308T160000Z/PT3H", "19970308T200000Z/PT1H", "19970308T230000Z/19970309T000000Z"], ) freebusy = c.get_inline("freebusy", decode=1) self.assertTrue(isinstance(freebusy[0][0], datetime)) self.assertTrue(isinstance(freebusy[0][1], timedelta))