Revert "vobject: add upstream tests"

This reverts commit dc7ce824da.
This commit is contained in:
Unrud 2018-08-14 18:44:51 +02:00
parent 18e4677cb7
commit e7e2c569b3
25 changed files with 2 additions and 1617 deletions

View File

@ -1,101 +0,0 @@
"""Translate an ics file's events to a different timezone."""
from optparse import OptionParser
from radicale_vobject import icalendar, base
try:
import PyICU
except:
PyICU = None
from datetime import datetime
def change_tz(cal, new_timezone, default, utc_only=False, utc_tz=icalendar.utc):
"""
Change the timezone of the specified component.
Args:
cal (Component): the component to change
new_timezone (tzinfo): the timezone to change to
default (tzinfo): a timezone to assume if the dtstart or dtend in cal
doesn't have an existing timezone
utc_only (bool): only convert dates that are in utc
utc_tz (tzinfo): the tzinfo to compare to for UTC when processing
utc_only=True
"""
for vevent in getattr(cal, 'vevent_list', []):
start = getattr(vevent, 'dtstart', None)
end = getattr(vevent, 'dtend', None)
for node in (start, end):
if node:
dt = node.value
if (isinstance(dt, datetime) and
(not utc_only or dt.tzinfo == utc_tz)):
if dt.tzinfo is None:
dt = dt.replace(tzinfo=default)
node.value = dt.astimezone(new_timezone)
def main():
options, args = get_options()
if PyICU is None:
print("Failure. change_tz requires PyICU, exiting")
elif options.list:
for tz_string in PyICU.TimeZone.createEnumeration():
print(tz_string)
elif args:
utc_only = options.utc
if utc_only:
which = "only UTC"
else:
which = "all"
print("Converting {0!s} events".format(which))
ics_file = args[0]
if len(args) > 1:
timezone = PyICU.ICUtzinfo.getInstance(args[1])
else:
timezone = PyICU.ICUtzinfo.default
print("... Reading {0!s}".format(ics_file))
cal = base.readOne(open(ics_file))
change_tz(cal, timezone, PyICU.ICUtzinfo.default, utc_only)
out_name = ics_file + '.converted'
print("... Writing {0!s}".format(out_name))
with open(out_name, 'wb') as out:
cal.serialize(out)
print("Done")
version = "0.1"
def get_options():
# Configuration options
usage = """usage: %prog [options] ics_file [timezone]"""
parser = OptionParser(usage=usage, version=version)
parser.set_description("change_tz will convert the timezones in an ics file. ")
parser.add_option("-u", "--only-utc", dest="utc", action="store_true",
default=False, help="Only change UTC events.")
parser.add_option("-l", "--list", dest="list", action="store_true",
default=False, help="List available timezones")
(cmdline_options, args) = parser.parse_args()
if not args and not cmdline_options.list:
print("error: too few arguments given")
print
print(parser.format_help())
return False, False
return cmdline_options, args
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("Aborted")

View File

@ -1,951 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
import datetime
import dateutil
import os
import re
import sys
import unittest
import json
from dateutil.tz import tzutc
from dateutil.rrule import rrule, rruleset, WEEKLY, MONTHLY
from radicale_vobject import base, iCalendar
from radicale_vobject import icalendar
from radicale_vobject.base import __behaviorRegistry as behavior_registry
from radicale_vobject.base import ContentLine, parseLine, ParseError
from radicale_vobject.base import readComponents, textLineToContentLine
from radicale_vobject.change_tz import change_tz
from radicale_vobject.icalendar import MultiDateBehavior, PeriodBehavior, \
RecurringComponent, utc
from radicale_vobject.icalendar import parseDtstart, stringToTextValues, \
stringToPeriod, timedeltaToString
two_hours = datetime.timedelta(hours=2)
def get_test_filepath(path):
"""
Helper function to get the filepath of test files.
"""
return os.path.join(os.path.dirname(__file__), "test_files", path)
def get_test_file(path):
"""
Helper function to open and read test files.
"""
filepath = get_test_filepath(path)
if sys.version_info[0] < 3:
# On python 2, this library operates on bytes.
f = open(filepath, 'r')
else:
# On python 3, it operates on unicode. We need to specify an encoding
# for systems for which the preferred encoding isn't utf-8 (e.g windows)
f = open(filepath, 'r', encoding='utf-8')
text = f.read()
f.close()
return text
class TestCalendarSerializing(unittest.TestCase):
"""
Test creating an iCalendar file
"""
max_diff = None
def test_scratchbuild(self):
"""
CreateCalendar 2.0 format from scratch
"""
test_cal = get_test_file("simple_2_0_test.ics")
cal = base.newFromBehavior('vcalendar', '2.0')
cal.add('vevent')
cal.vevent.add('dtstart').value = datetime.datetime(2006, 5, 9)
cal.vevent.add('description').value = "Test event"
cal.vevent.add('created').value = \
datetime.datetime(2006, 1, 1, 10,
tzinfo=dateutil.tz.tzical(
get_test_filepath("timezones.ics")).get('US/Pacific'))
cal.vevent.add('uid').value = "Not very random UID"
cal.vevent.add('dtstamp').value = datetime.datetime(2017, 6, 26, 0, tzinfo=tzutc())
# Note we're normalizing line endings, because no one got time for that.
self.assertEqual(
cal.serialize().replace('\r\n', '\n'),
test_cal.replace('\r\n', '\n')
)
def test_unicode(self):
"""
Test unicode characters
"""
test_cal = get_test_file("utf8_test.ics")
vevent = base.readOne(test_cal).vevent
vevent2 = base.readOne(vevent.serialize())
self.assertEqual(str(vevent), str(vevent2))
self.assertEqual(
vevent.summary.value,
'The title こんにちはキティ'
)
if sys.version_info[0] < 3:
test_cal = test_cal.decode('utf-8')
vevent = base.readOne(test_cal).vevent
vevent2 = base.readOne(vevent.serialize())
self.assertEqual(str(vevent), str(vevent2))
self.assertEqual(
vevent.summary.value,
u'The title こんにちはキティ'
)
def test_wrapping(self):
"""
Should support input file with a long text field covering multiple lines
"""
test_journal = get_test_file("journal.ics")
vobj = base.readOne(test_journal)
vjournal = base.readOne(vobj.serialize())
self.assertTrue('Joe, Lisa, and Bob' in vjournal.description.value)
self.assertTrue('Tuesday.\n2.' in vjournal.description.value)
def test_multiline(self):
"""
Multi-text serialization test
"""
category = base.newFromBehavior('categories')
category.value = ['Random category']
self.assertEqual(
category.serialize().strip(),
"CATEGORIES:Random category"
)
category.value.append('Other category')
self.assertEqual(
category.serialize().strip(),
"CATEGORIES:Random category,Other category"
)
def test_semicolon_separated(self):
"""
Semi-colon separated multi-text serialization test
"""
request_status = base.newFromBehavior('request-status')
request_status.value = ['5.1', 'Service unavailable']
self.assertEqual(
request_status.serialize().strip(),
"REQUEST-STATUS:5.1;Service unavailable"
)
@staticmethod
def test_unicode_multiline():
"""
Test multiline unicode characters
"""
cal = iCalendar()
cal.add('method').value = 'REQUEST'
cal.add('vevent')
cal.vevent.add('created').value = datetime.datetime.now()
cal.vevent.add('summary').value = 'Классное событие'
cal.vevent.add('description').value = ('Классное событие Классное событие Классное событие Классное событие '
'Классное событие Классsdssdное событие')
# json tries to encode as utf-8 and it would break if some chars could not be encoded
json.dumps(cal.serialize())
@staticmethod
def test_ical_to_hcal():
"""
Serializing iCalendar to hCalendar.
Since Hcalendar is experimental and the behavior doesn't seem to want to load,
This test will have to wait.
tzs = dateutil.tz.tzical(get_test_filepath("timezones.ics"))
cal = base.newFromBehavior('hcalendar')
self.assertEqual(
str(cal.behavior),
"<class 'radicale_vobject.hcalendar.HCalendar'>"
)
cal.add('vevent')
cal.vevent.add('summary').value = "this is a note"
cal.vevent.add('url').value = "http://microformats.org/code/hcalendar/creator"
cal.vevent.add('dtstart').value = datetime.date(2006,2,27)
cal.vevent.add('location').value = "a place"
cal.vevent.add('dtend').value = datetime.date(2006,2,27) + datetime.timedelta(days = 2)
event2 = cal.add('vevent')
event2.add('summary').value = "Another one"
event2.add('description').value = "The greatest thing ever!"
event2.add('dtstart').value = datetime.datetime(1998, 12, 17, 16, 42, tzinfo = tzs.get('US/Pacific'))
event2.add('location').value = "somewhere else"
event2.add('dtend').value = event2.dtstart.value + datetime.timedelta(days = 6)
hcal = cal.serialize()
"""
#self.assertEqual(
# str(hcal),
# """<span class="vevent">
# <a class="url" href="http://microformats.org/code/hcalendar/creator">
# <span class="summary">this is a note</span>:
# <abbr class="dtstart", title="20060227">Monday, February 27</abbr>
# - <abbr class="dtend", title="20060301">Tuesday, February 28</abbr>
# at <span class="location">a place</span>
# </a>
# </span>
# <span class="vevent">
# <span class="summary">Another one</span>:
# <abbr class="dtstart", title="19981217T164200-0800">Thursday, December 17, 16:42</abbr>
# - <abbr class="dtend", title="19981223T164200-0800">Wednesday, December 23, 16:42</abbr>
# at <span class="location">somewhere else</span>
# <div class="description">The greatest thing ever!</div>
# </span>
# """
#)
class TestBehaviors(unittest.TestCase):
"""
Test Behaviors
"""
def test_general_behavior(self):
"""
Tests for behavior registry, getting and creating a behavior.
"""
# Check expected behavior registry.
self.assertEqual(
sorted(behavior_registry.keys()),
['', 'ACTION', 'ADR', 'AVAILABLE', 'BUSYTYPE', 'CALSCALE',
'CATEGORIES', 'CLASS', 'COMMENT', 'COMPLETED', 'CONTACT',
'CREATED', 'DAYLIGHT', 'DESCRIPTION', 'DTEND', 'DTSTAMP',
'DTSTART', 'DUE', 'DURATION', 'EXDATE', 'EXRULE', 'FN', 'FREEBUSY',
'LABEL', 'LAST-MODIFIED', 'LOCATION', 'METHOD', 'N', 'ORG',
'PHOTO', 'PRODID', 'RDATE', 'RECURRENCE-ID', 'RELATED-TO',
'REQUEST-STATUS', 'RESOURCES', 'REV', 'RRULE', 'STANDARD', 'STATUS',
'SUMMARY', 'TRANSP', 'TRIGGER', 'UID', 'VALARM', 'VAVAILABILITY',
'VCALENDAR', 'VCARD', 'VEVENT', 'VFREEBUSY', 'VJOURNAL',
'VTIMEZONE', 'VTODO']
)
# test get_behavior
behavior = base.getBehavior('VCALENDAR')
self.assertEqual(
str(behavior),
"<class 'radicale_vobject.icalendar.VCalendar2_0'>"
)
self.assertTrue(behavior.isComponent)
self.assertEqual(
base.getBehavior("invalid_name"),
None
)
# test for ContentLine (not a component)
non_component_behavior = base.getBehavior('RDATE')
self.assertFalse(non_component_behavior.isComponent)
def test_MultiDateBehavior(self):
"""
Test MultiDateBehavior
"""
parseRDate = MultiDateBehavior.transformToNative
self.assertEqual(
str(parseRDate(textLineToContentLine("RDATE;VALUE=DATE:19970304,19970504,19970704,19970904"))),
"<RDATE{'VALUE': ['DATE']}[datetime.date(1997, 3, 4), datetime.date(1997, 5, 4), datetime.date(1997, 7, 4), datetime.date(1997, 9, 4)]>"
)
self.assertEqual(
str(parseRDate(textLineToContentLine("RDATE;VALUE=PERIOD:19960403T020000Z/19960403T040000Z,19960404T010000Z/PT3H"))),
"<RDATE{'VALUE': ['PERIOD']}[(datetime.datetime(1996, 4, 3, 2, 0, tzinfo=tzutc()), datetime.datetime(1996, 4, 3, 4, 0, tzinfo=tzutc())), (datetime.datetime(1996, 4, 4, 1, 0, tzinfo=tzutc()), datetime.timedelta(0, 10800))]>"
)
def test_periodBehavior(self):
"""
Test PeriodBehavior
"""
line = ContentLine('test', [], '', isNative=True)
line.behavior = PeriodBehavior
line.value = [(datetime.datetime(2006, 2, 16, 10), two_hours)]
self.assertEqual(
line.transformFromNative().value,
'20060216T100000/PT2H'
)
self.assertEqual(
line.transformToNative().value,
[(datetime.datetime(2006, 2, 16, 10, 0),
datetime.timedelta(0, 7200))]
)
line.value.append((datetime.datetime(2006, 5, 16, 10), two_hours))
self.assertEqual(
line.serialize().strip(),
'TEST:20060216T100000/PT2H,20060516T100000/PT2H'
)
class TestVTodo(unittest.TestCase):
"""
VTodo Tests
"""
def test_vtodo(self):
"""
Test VTodo
"""
vtodo = get_test_file("vtodo.ics")
obj = base.readOne(vtodo)
obj.vtodo.add('completed')
obj.vtodo.completed.value = datetime.datetime(2015,5,5,13,30)
self.assertEqual(obj.vtodo.completed.serialize()[0:23],
'COMPLETED:20150505T1330')
obj = base.readOne(obj.serialize())
self.assertEqual(obj.vtodo.completed.value,
datetime.datetime(2015,5,5,13,30))
class TestVobject(unittest.TestCase):
"""
VObject Tests
"""
max_diff = None
@classmethod
def setUpClass(cls):
"""
Method for setting up class fixture before running tests in the class.
Fetches test file.
"""
cls.simple_test_cal = get_test_file("simple_test.ics")
def test_readComponents(self):
"""
Test if reading components correctly
"""
cal = next(readComponents(self.simple_test_cal))
self.assertEqual(str(cal), "<VCALENDAR| [<VEVENT| [<SUMMARY{'BLAH': ['hi!']}Bastille Day Party>]>]>")
self.assertEqual(str(cal.vevent.summary), "<SUMMARY{'BLAH': ['hi!']}Bastille Day Party>")
def test_parseLine(self):
"""
Test line parsing
"""
self.assertEqual(parseLine("BLAH:"), ('BLAH', [], '', None))
self.assertEqual(
parseLine("RDATE:VALUE=DATE:19970304,19970504,19970704,19970904"),
('RDATE', [], 'VALUE=DATE:19970304,19970504,19970704,19970904', None)
)
self.assertEqual(
parseLine('DESCRIPTION;ALTREP="http://www.wiz.org":The Fall 98 Wild Wizards Conference - - Las Vegas, NV, USA'),
('DESCRIPTION', [['ALTREP', 'http://www.wiz.org']], 'The Fall 98 Wild Wizards Conference - - Las Vegas, NV, USA', None)
)
self.assertEqual(
parseLine("EMAIL;PREF;INTERNET:john@nowhere.com"),
('EMAIL', [['PREF'], ['INTERNET']], 'john@nowhere.com', None)
)
self.assertEqual(
parseLine('EMAIL;TYPE="blah",hah;INTERNET="DIGI",DERIDOO:john@nowhere.com'),
('EMAIL', [['TYPE', 'blah', 'hah'], ['INTERNET', 'DIGI', 'DERIDOO']], 'john@nowhere.com', None)
)
self.assertEqual(
parseLine('item1.ADR;type=HOME;type=pref:;;Reeperbahn 116;Hamburg;;20359;'),
('ADR', [['type', 'HOME'], ['type', 'pref']], ';;Reeperbahn 116;Hamburg;;20359;', 'item1')
)
self.assertRaises(ParseError, parseLine, ":")
class TestGeneralFileParsing(unittest.TestCase):
"""
General tests for parsing ics files.
"""
def test_readOne(self):
"""
Test reading first component of ics
"""
cal = get_test_file("silly_test.ics")
silly = base.readOne(cal)
self.assertEqual(
str(silly),
"<SILLYPROFILE| [<MORESTUFF{}this line is not folded, but in practice probably ought to be, as it is exceptionally long, and moreover demonstratively stupid>, <SILLYNAME{}name>, <STUFF{}foldedline>]>"
)
self.assertEqual(
str(silly.stuff),
"<STUFF{}foldedline>"
)
def test_importing(self):
"""
Test importing ics
"""
cal = get_test_file("standard_test.ics")
c = base.readOne(cal, validate=True)
self.assertEqual(
str(c.vevent.valarm.trigger),
"<TRIGGER{}-1 day, 0:00:00>"
)
self.assertEqual(
str(c.vevent.dtstart.value),
"2002-10-28 14:00:00-08:00"
)
self.assertTrue(
isinstance(c.vevent.dtstart.value, datetime.datetime)
)
self.assertEqual(
str(c.vevent.dtend.value),
"2002-10-28 15:00:00-08:00"
)
self.assertTrue(
isinstance(c.vevent.dtend.value, datetime.datetime)
)
self.assertEqual(
c.vevent.dtstamp.value,
datetime.datetime(2002, 10, 28, 1, 17, 6, tzinfo=tzutc())
)
vevent = c.vevent.transformFromNative()
self.assertEqual(
str(vevent.rrule),
"<RRULE{}FREQ=Weekly;COUNT=10>"
)
def test_bad_stream(self):
"""
Test bad ics stream
"""
cal = get_test_file("badstream.ics")
self.assertRaises(ParseError, base.readOne, cal)
def test_bad_line(self):
"""
Test bad line in ics file
"""
cal = get_test_file("badline.ics")
self.assertRaises(ParseError, base.readOne, cal)
newcal = base.readOne(cal, ignoreUnreadable=True)
self.assertEqual(
str(newcal.vevent.x_bad_underscore),
'<X-BAD-UNDERSCORE{}TRUE>'
)
def test_parseParams(self):
"""
Test parsing parameters
"""
self.assertEqual(
base.parseParams(';ALTREP="http://www.wiz.org"'),
[['ALTREP', 'http://www.wiz.org']]
)
self.assertEqual(
base.parseParams(';ALTREP="http://www.wiz.org;;",Blah,Foo;NEXT=Nope;BAR'),
[['ALTREP', 'http://www.wiz.org;;', 'Blah', 'Foo'],
['NEXT', 'Nope'], ['BAR']]
)
class TestVcards(unittest.TestCase):
"""
Test VCards
"""
@classmethod
def setUpClass(cls):
"""
Method for setting up class fixture before running tests in the class.
Fetches test file.
"""
cls.test_file = get_test_file("vcard_with_groups.ics")
cls.card = base.readOne(cls.test_file)
def test_vcard_creation(self):
"""
Test creating a vCard
"""
vcard = base.newFromBehavior('vcard', '3.0')
self.assertEqual(
str(vcard),
"<VCARD| []>"
)
def test_default_behavior(self):
"""
Default behavior test.
"""
card = self.card
self.assertEqual(
base.getBehavior('note'),
None
)
self.assertEqual(
str(card.note.value),
"The Mayor of the great city of Goerlitz in the great country of Germany.\nNext line."
)
def test_with_groups(self):
"""
vCard groups test
"""
card = self.card
self.assertEqual(
str(card.group),
'home'
)
self.assertEqual(
str(card.tel.group),
'home'
)
card.group = card.tel.group = 'new'
self.assertEqual(
str(card.tel.serialize().strip()),
'new.TEL;TYPE=fax,voice,msg:+49 3581 123456'
)
self.assertEqual(
str(card.serialize().splitlines()[0]),
'new.BEGIN:VCARD'
)
def test_vcard_3_parsing(self):
"""
VCARD 3.0 parse test
"""
test_file = get_test_file("simple_3_0_test.ics")
card = base.readOne(test_file)
# value not rendering correctly?
#self.assertEqual(
# card.adr.value,
# "<Address: Haight Street 512;\nEscape, Test\nNovosibirsk, 80214\nGnuland>"
#)
self.assertEqual(
card.org.value,
["University of Novosibirsk", "Department of Octopus Parthenogenesis"]
)
for _ in range(3):
new_card = base.readOne(card.serialize())
self.assertEqual(new_card.org.value, card.org.value)
card = new_card
class TestIcalendar(unittest.TestCase):
"""
Tests for icalendar.py
"""
max_diff = None
def test_parseDTStart(self):
"""
Should take a content line and return a datetime object.
"""
self.assertEqual(
parseDtstart(textLineToContentLine("DTSTART:20060509T000000")),
datetime.datetime(2006, 5, 9, 0, 0)
)
def test_regexes(self):
"""
Test regex patterns
"""
self.assertEqual(
re.findall(base.patterns['name'], '12foo-bar:yay'),
['12foo-bar', 'yay']
)
self.assertEqual(
re.findall(base.patterns['safe_char'], 'a;b"*,cd'),
['a', 'b', '*', 'c', 'd']
)
self.assertEqual(
re.findall(base.patterns['qsafe_char'], 'a;b"*,cd'),
['a', ';', 'b', '*', ',', 'c', 'd']
)
self.assertEqual(
re.findall(base.patterns['param_value'],
'"quoted";not-quoted;start"after-illegal-quote',
re.VERBOSE),
['"quoted"', '', 'not-quoted', '', 'start', '',
'after-illegal-quote', '']
)
match = base.line_re.match('TEST;ALTREP="http://www.wiz.org":value:;"')
self.assertEqual(
match.group('value'),
'value:;"'
)
self.assertEqual(
match.group('name'),
'TEST'
)
self.assertEqual(
match.group('params'),
';ALTREP="http://www.wiz.org"'
)
def test_stringToTextValues(self):
"""
Test string lists
"""
self.assertEqual(
stringToTextValues(''),
['']
)
self.assertEqual(
stringToTextValues('abcd,efgh'),
['abcd', 'efgh']
)
def test_stringToPeriod(self):
"""
Test datetime strings
"""
self.assertEqual(
stringToPeriod("19970101T180000Z/19970102T070000Z"),
(datetime.datetime(1997, 1, 1, 18, 0, tzinfo=tzutc()),
datetime.datetime(1997, 1, 2, 7, 0, tzinfo=tzutc()))
)
self.assertEqual(
stringToPeriod("19970101T180000Z/PT1H"),
(datetime.datetime(1997, 1, 1, 18, 0, tzinfo=tzutc()),
datetime.timedelta(0, 3600))
)
def test_timedeltaToString(self):
"""
Test timedelta strings
"""
self.assertEqual(
timedeltaToString(two_hours),
'PT2H'
)
self.assertEqual(
timedeltaToString(datetime.timedelta(minutes=20)),
'PT20M'
)
def test_vtimezone_creation(self):
"""
Test timezones
"""
tzs = dateutil.tz.tzical(get_test_filepath("timezones.ics"))
pacific = icalendar.TimezoneComponent(tzs.get('US/Pacific'))
self.assertEqual(
str(pacific),
"<VTIMEZONE | <TZID{}US/Pacific>>"
)
santiago = icalendar.TimezoneComponent(tzs.get('Santiago'))
self.assertEqual(
str(santiago),
"<VTIMEZONE | <TZID{}Santiago>>"
)
for year in range(2001, 2010):
for month in (2, 9):
dt = datetime.datetime(year, month, 15,
tzinfo=tzs.get('Santiago'))
self.assertTrue(dt.replace(tzinfo=tzs.get('Santiago')), dt)
@staticmethod
def test_timezone_serializing():
"""
Serializing with timezones test
"""
tzs = dateutil.tz.tzical(get_test_filepath("timezones.ics"))
pacific = tzs.get('US/Pacific')
cal = base.Component('VCALENDAR')
cal.setBehavior(icalendar.VCalendar2_0)
ev = cal.add('vevent')
ev.add('dtstart').value = datetime.datetime(2005, 10, 12, 9,
tzinfo=pacific)
evruleset = rruleset()
evruleset.rrule(rrule(WEEKLY, interval=2, byweekday=[2,4],
until=datetime.datetime(2005, 12, 15, 9)))
evruleset.rrule(rrule(MONTHLY, bymonthday=[-1,-5]))
evruleset.exdate(datetime.datetime(2005, 10, 14, 9, tzinfo=pacific))
ev.rruleset = evruleset
ev.add('duration').value = datetime.timedelta(hours=1)
apple = tzs.get('America/Montreal')
ev.dtstart.value = datetime.datetime(2005, 10, 12, 9, tzinfo=apple)
def test_pytz_timezone_serializing(self):
"""
Serializing with timezones from pytz test
"""
try:
import pytz
except ImportError:
return self.skipTest("pytz not installed") # NOQA
# Avoid conflicting cached tzinfo from other tests
def unregister_tzid(tzid):
"""Clear tzid from icalendar TZID registry"""
if icalendar.getTzid(tzid, False):
icalendar.registerTzid(tzid, None)
unregister_tzid('US/Eastern')
eastern = pytz.timezone('US/Eastern')
cal = base.Component('VCALENDAR')
cal.setBehavior(icalendar.VCalendar2_0)
ev = cal.add('vevent')
ev.add('dtstart').value = eastern.localize(
datetime.datetime(2008, 10, 12, 9))
serialized = cal.serialize()
expected_vtimezone = get_test_file("tz_us_eastern.ics")
self.assertIn(
expected_vtimezone.replace('\r\n', '\n'),
serialized.replace('\r\n', '\n')
)
# Exhaustively test all zones (just looking for no errors)
for tzname in pytz.all_timezones:
unregister_tzid(tzname)
tz = icalendar.TimezoneComponent(tzinfo=pytz.timezone(tzname))
tz.serialize()
def test_freeBusy(self):
"""
Test freebusy components
"""
test_cal = get_test_file("freebusy.ics")
vfb = base.newFromBehavior('VFREEBUSY')
vfb.add('uid').value = 'test'
vfb.add('dtstamp').value = datetime.datetime(2006, 2, 15, 0, tzinfo=utc)
vfb.add('dtstart').value = datetime.datetime(2006, 2, 16, 1, tzinfo=utc)
vfb.add('dtend').value = vfb.dtstart.value + two_hours
vfb.add('freebusy').value = [(vfb.dtstart.value, two_hours / 2)]
vfb.add('freebusy').value = [(vfb.dtstart.value, vfb.dtend.value)]
self.assertEqual(
vfb.serialize().replace('\r\n', '\n'),
test_cal.replace('\r\n', '\n')
)
def test_availablity(self):
"""
Test availability components
"""
test_cal = get_test_file("availablity.ics")
vcal = base.newFromBehavior('VAVAILABILITY')
vcal.add('uid').value = 'test'
vcal.add('dtstamp').value = datetime.datetime(2006, 2, 15, 0, tzinfo=utc)
vcal.add('dtstart').value = datetime.datetime(2006, 2, 16, 0, tzinfo=utc)
vcal.add('dtend').value = datetime.datetime(2006, 2, 17, 0, tzinfo=utc)
vcal.add('busytype').value = "BUSY"
av = base.newFromBehavior('AVAILABLE')
av.add('uid').value = 'test1'
av.add('dtstamp').value = datetime.datetime(2006, 2, 15, 0, tzinfo=utc)
av.add('dtstart').value = datetime.datetime(2006, 2, 16, 9, tzinfo=utc)
av.add('dtend').value = datetime.datetime(2006, 2, 16, 12, tzinfo=utc)
av.add('summary').value = "Available in the morning"
vcal.add(av)
self.assertEqual(
vcal.serialize().replace('\r\n', '\n'),
test_cal.replace('\r\n', '\n')
)
def test_recurrence(self):
"""
Ensure date valued UNTILs in rrules are in a reasonable timezone,
and include that day (12/28 in this test)
"""
test_file = get_test_file("recurrence.ics")
cal = base.readOne(test_file)
dates = list(cal.vevent.getrruleset())
self.assertEqual(
dates[0],
datetime.datetime(2006, 1, 26, 23, 0, tzinfo=tzutc())
)
self.assertEqual(
dates[1],
datetime.datetime(2006, 2, 23, 23, 0, tzinfo=tzutc())
)
self.assertEqual(
dates[-1],
datetime.datetime(2006, 12, 28, 23, 0, tzinfo=tzutc())
)
def test_recurring_component(self):
"""
Test recurring events
"""
vevent = RecurringComponent(name='VEVENT')
# init
self.assertTrue(vevent.isNative)
# rruleset should be None at this point.
# No rules have been passed or created.
self.assertEqual(vevent.rruleset, None)
# Now add start and rule for recurring event
vevent.add('dtstart').value = datetime.datetime(2005, 1, 19, 9)
vevent.add('rrule').value =u"FREQ=WEEKLY;COUNT=2;INTERVAL=2;BYDAY=TU,TH"
self.assertEqual(
list(vevent.rruleset),
[datetime.datetime(2005, 1, 20, 9, 0), datetime.datetime(2005, 2, 1, 9, 0)]
)
self.assertEqual(
list(vevent.getrruleset(addRDate=True)),
[datetime.datetime(2005, 1, 19, 9, 0), datetime.datetime(2005, 1, 20, 9, 0)]
)
# Also note that dateutil will expand all-day events (datetime.date values)
# to datetime.datetime value with time 0 and no timezone.
vevent.dtstart.value = datetime.date(2005,3,18)
self.assertEqual(
list(vevent.rruleset),
[datetime.datetime(2005, 3, 29, 0, 0), datetime.datetime(2005, 3, 31, 0, 0)]
)
self.assertEqual(
list(vevent.getrruleset(True)),
[datetime.datetime(2005, 3, 18, 0, 0), datetime.datetime(2005, 3, 29, 0, 0)]
)
def test_recurrence_without_tz(self):
"""
Test recurring vevent missing any time zone definitions.
"""
test_file = get_test_file("recurrence-without-tz.ics")
cal = base.readOne(test_file)
dates = list(cal.vevent.getrruleset())
self.assertEqual(dates[0], datetime.datetime(2013, 1, 17, 0, 0))
self.assertEqual(dates[1], datetime.datetime(2013, 1, 24, 0, 0))
self.assertEqual(dates[-1], datetime.datetime(2013, 3, 28, 0, 0))
def test_recurrence_offset_naive(self):
"""
Ensure recurring vevent missing some time zone definitions is
parsing. See isseu #75.
"""
test_file = get_test_file("recurrence-offset-naive.ics")
cal = base.readOne(test_file)
dates = list(cal.vevent.getrruleset())
self.assertEqual(dates[0], datetime.datetime(2013, 1, 17, 0, 0))
self.assertEqual(dates[1], datetime.datetime(2013, 1, 24, 0, 0))
self.assertEqual(dates[-1], datetime.datetime(2013, 3, 28, 0, 0))
class TestChangeTZ(unittest.TestCase):
"""
Tests for change_tz.change_tz
"""
class StubCal(object):
class StubEvent(object):
class Node(object):
def __init__(self, value):
self.value = value
def __init__(self, dtstart, dtend):
self.dtstart = self.Node(dtstart)
self.dtend = self.Node(dtend)
def __init__(self, dates):
"""
dates is a list of tuples (dtstart, dtend)
"""
self.vevent_list = [self.StubEvent(*d) for d in dates]
def test_change_tz(self):
"""
Change the timezones of events in a component to a different
timezone
"""
# Setup - create a stub vevent list
old_tz = dateutil.tz.gettz('UTC') # 0:00
new_tz = dateutil.tz.gettz('America/Chicago') # -5:00
dates = [
(datetime.datetime(1999, 12, 31, 23, 59, 59, 0, tzinfo=old_tz),
datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=old_tz)),
(datetime.datetime(2010, 12, 31, 23, 59, 59, 0, tzinfo=old_tz),
datetime.datetime(2011, 1, 2, 3, 0, 0, 0, tzinfo=old_tz))]
cal = self.StubCal(dates)
# Exercise - change the timezone
change_tz(cal, new_tz, dateutil.tz.gettz('UTC'))
# Test - that the tzs were converted correctly
expected_new_dates = [
(datetime.datetime(1999, 12, 31, 17, 59, 59, 0, tzinfo=new_tz),
datetime.datetime(1999, 12, 31, 18, 0, 0, 0, tzinfo=new_tz)),
(datetime.datetime(2010, 12, 31, 17, 59, 59, 0, tzinfo=new_tz),
datetime.datetime(2011, 1, 1, 21, 0, 0, 0, tzinfo=new_tz))]
for vevent, expected_datepair in zip(cal.vevent_list,
expected_new_dates):
self.assertEqual(vevent.dtstart.value, expected_datepair[0])
self.assertEqual(vevent.dtend.value, expected_datepair[1])
def test_change_tz_utc_only(self):
"""
Change any UTC timezones of events in a component to a different
timezone
"""
# Setup - create a stub vevent list
utc_tz = dateutil.tz.gettz('UTC') # 0:00
non_utc_tz = dateutil.tz.gettz('America/Santiago') # -4:00
new_tz = dateutil.tz.gettz('America/Chicago') # -5:00
dates = [
(datetime.datetime(1999, 12, 31, 23, 59, 59, 0, tzinfo=utc_tz),
datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=non_utc_tz))]
cal = self.StubCal(dates)
# Exercise - change the timezone passing utc_only=True
change_tz(cal, new_tz, dateutil.tz.gettz('UTC'), utc_only=True)
# Test - that only the utc item has changed
expected_new_dates = [
(datetime.datetime(1999, 12, 31, 17, 59, 59, 0, tzinfo=new_tz),
dates[0][1])]
for vevent, expected_datepair in zip(cal.vevent_list,
expected_new_dates):
self.assertEqual(vevent.dtstart.value, expected_datepair[0])
self.assertEqual(vevent.dtend.value, expected_datepair[1])
def test_change_tz_default(self):
"""
Change the timezones of events in a component to a different
timezone, passing a default timezone that is assumed when the events
don't have one
"""
# Setup - create a stub vevent list
new_tz = dateutil.tz.gettz('America/Chicago') # -5:00
dates = [
(datetime.datetime(1999, 12, 31, 23, 59, 59, 0, tzinfo=None),
datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=None))]
cal = self.StubCal(dates)
# Exercise - change the timezone
change_tz(cal, new_tz, dateutil.tz.gettz('UTC'))
# Test - that the tzs were converted correctly
expected_new_dates = [
(datetime.datetime(1999, 12, 31, 17, 59, 59, 0, tzinfo=new_tz),
datetime.datetime(1999, 12, 31, 18, 0, 0, 0, tzinfo=new_tz))]
for vevent, expected_datepair in zip(cal.vevent_list,
expected_new_dates):
self.assertEqual(vevent.dtstart.value, expected_datepair[0])
self.assertEqual(vevent.dtend.value, expected_datepair[1])
if __name__ == '__main__':
unittest.main()

View File

@ -1,14 +0,0 @@
BEGIN:VAVAILABILITY
UID:test
DTSTART:20060216T000000Z
DTEND:20060217T000000Z
BEGIN:AVAILABLE
UID:test1
DTSTART:20060216T090000Z
DTEND:20060216T120000Z
DTSTAMP:20060215T000000Z
SUMMARY:Available in the morning
END:AVAILABLE
BUSYTYPE:BUSY
DTSTAMP:20060215T000000Z
END:VAVAILABILITY

View File

@ -1,10 +0,0 @@
BEGIN:VCALENDAR
METHOD:PUBLISH
VERSION:2.0
BEGIN:VEVENT
DTSTART:19870405T020000
X-BAD/SLASH:TRUE
X-BAD_UNDERSCORE:TRUE
UID:EC9439B1-FF65-11D6-9973-003065F99D04
END:VEVENT
END:VCALENDAR

View File

@ -1,16 +0,0 @@
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
X-WR-TIMEZONE;VALUE=TEXT:US/Pacific
METHOD:PUBLISH
PRODID:-//Apple Computer\, Inc//iCal 1.0//EN
X-WR-CALNAME;VALUE=TEXT:Example
VERSION:2.0
BEGIN:VEVENT
DTSTART:20021028T140000Z
BEGIN:VALARM
TRIGGER:a20021028120000
ACTION:DISPLAY
DESCRIPTION:This trigger has a nonsensical value
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -1,8 +0,0 @@
BEGIN:VFREEBUSY
UID:test
DTSTART:20060216T010000Z
DTEND:20060216T030000Z
DTSTAMP:20060215T000000Z
FREEBUSY:20060216T010000Z/PT1H
FREEBUSY:20060216T010000Z/20060216T030000Z
END:VFREEBUSY

View File

@ -1,15 +0,0 @@
BEGIN:VJOURNAL
UID:19970901T130000Z-123405@example.com
DTSTAMP:19970901T130000Z
DTSTART;VALUE=DATE:19970317
SUMMARY:Staff meeting minutes
DESCRIPTION:1. Staff meeting: Participants include Joe\,
Lisa\, and Bob. Aurora project plans were reviewed.
There is currently no budget reserves for this project.
Lisa will escalate to management. Next meeting on Tuesday.\n
2. Telephone Conference: ABC Corp. sales representative
called to discuss new printer. Promised to get us a demo by
Friday.\n3. Henry Miller (Handsoff Insurance): Car was
totaled by tree. Is looking into a loaner car. 555-2323
(tel).
END:VJOURNAL

View File

@ -1,85 +0,0 @@
Unicode in vCards
.................
>>> import vobject
>>> card = vobject.vCard()
>>> card.add('fn').value = u'Hello\u1234 World!'
>>> card.add('n').value = vobject.vcard.Name('World', u'Hello\u1234')
>>> card.add('adr').value = vobject.vcard.Address(u'5\u1234 Nowhere, Apt 1', 'Berkeley', 'CA', '94704', 'USA')
>>> card
<VCARD| [<ADR{}5? Nowhere, Apt 1\nBerkeley, CA 94704\nUSA>, <FN{}Hello? World!>, <N{} Hello? World >]>
>>> card.serialize()
u'BEGIN:VCARD\r\nVERSION:3.0\r\nADR:;;5\u1234 Nowhere\\, Apt 1;Berkeley;CA;94704;USA\r\nFN:Hello\u1234 World!\r\nN:World;Hello\u1234;;;\r\nEND:VCARD\r\n'
>>> print(card.serialize())
BEGIN:VCARD
VERSION:3.0
ADR:;;5ሴ Nowhere\, Apt 1;Berkeley;CA;94704;USA
FN:Helloሴ World!
N:World;Helloሴ;;;
END:VCARD
Helper function
...............
>>> from pkg_resources import resource_stream
>>> def get_stream(path):
... try:
... return resource_stream(__name__, 'test_files/' + path)
... except: # different paths, depending on whether doctest is run directly
... return resource_stream(__name__, path)
Unicode in TZID
...............
>>> f = get_stream("tzid_8bit.ics")
>>> cal = vobject.readOne(f)
>>> print(cal.vevent.dtstart.value)
2008-05-30 15:00:00+06:00
>>> print(cal.vevent.dtstart.serialize())
DTSTART;TZID=Екатеринбург:20080530T150000
Commas in TZID
..............
>>> f = get_stream("ms_tzid.ics")
>>> cal = vobject.readOne(f)
>>> print(cal.vevent.dtstart.value)
2008-05-30 15:00:00+10:00
Equality in vCards
..................
>>> card.adr.value == vobject.vcard.Address('Just a street')
False
>>> card.adr.value == vobject.vcard.Address(u'5\u1234 Nowhere, Apt 1', 'Berkeley', 'CA', '94704', 'USA')
True
Organization (org)
..................
>>> card.add('org').value = ["Company, Inc.", "main unit", "sub-unit"]
>>> print(card.org.serialize())
ORG:Company\, Inc.;main unit;sub-unit
Ruby escapes semi-colons in rrules
..................................
>>> f = get_stream("ruby_rrule.ics")
>>> cal = vobject.readOne(f)
>>> iter(cal.vevent.rruleset).next()
datetime.datetime(2003, 1, 1, 7, 0)
quoted-printable
................
>>> vcf = 'BEGIN:VCARD\nVERSION:2.1\nN;ENCODING=QUOTED-PRINTABLE:;=E9\nFN;ENCODING=QUOTED-PRINTABLE:=E9\nTEL;HOME:0111111111\nEND:VCARD\n\n'
>>> vcf = vobject.readOne(vcf)
>>> vcf.n.value
<Name: ? >
>>> vcf.n.value.given
u'\xe9'
>>> vcf.serialize()
'BEGIN:VCARD\r\nVERSION:2.1\r\nFN:\xc3\xa9\r\nN:;\xc3\xa9;;;\r\nTEL:0111111111\r\nEND:VCARD\r\n'
>>> vcs = 'BEGIN:VCALENDAR\r\nPRODID:-//OpenSync//NONSGML OpenSync vformat 0.3//EN\r\nVERSION:1.0\r\nBEGIN:VEVENT\r\nDESCRIPTION;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:foo =C3=A5=0Abar =C3=A4=\r\n=0Abaz =C3=B6\r\nUID:20080406T152030Z-7822\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n'
>>> vcs = vobject.readOne(vcs, allowQP = True)
>>> vcs.serialize()
'BEGIN:VCALENDAR\r\nVERSION:1.0\r\nPRODID:-//OpenSync//NONSGML OpenSync vformat 0.3//EN\r\nBEGIN:VEVENT\r\nUID:20080406T152030Z-7822\r\nDESCRIPTION:foo \xc3\xa5\\nbar \xc3\xa4\\nbaz \xc3\xb6\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n'

View File

@ -1,39 +0,0 @@
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Canberra, Melbourne, Sydney
BEGIN:STANDARD
DTSTART:20010325T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3;UNTIL=20050327T070000Z
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
TZNAME:Standard Time
END:STANDARD
BEGIN:STANDARD
DTSTART:20060402T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=4;UNTIL=20060402T070000Z
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
TZNAME:Standard Time
END:STANDARD
BEGIN:STANDARD
DTSTART:20070325T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
TZNAME:Standard Time
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20001029T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
TZNAME:Daylight Savings Time
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:CommaTest
DTSTART;TZID="Canberra, Melbourne, Sydney":20080530T150000
END:VEVENT
END:VCALENDAR

View File

@ -1,9 +0,0 @@
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130117
DTEND;VALUE=DATE:20130118
RRULE:FREQ=WEEKLY;UNTIL=20130330T230000Z;BYDAY=TH
SUMMARY:Meeting
END:VEVENT
END:VCALENDAR

View File

@ -1,9 +0,0 @@
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130117
DTEND;VALUE=DATE:20130118
RRULE:FREQ=WEEKLY;UNTIL=20130330;BYDAY=TH
SUMMARY:Meeting
END:VEVENT
END:VCALENDAR

View File

@ -1,30 +0,0 @@
BEGIN:VCALENDAR
VERSION
:2.0
PRODID
:-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN
BEGIN:VEVENT
CREATED
:20060327T214227Z
LAST-MODIFIED
:20060313T080829Z
DTSTAMP
:20060116T231602Z
UID
:70922B3051D34A9E852570EC00022388
SUMMARY
:Monthly - All Hands Meeting with Joe Smith
STATUS
:CONFIRMED
CLASS
:PUBLIC
RRULE
:FREQ=MONTHLY;UNTIL=20061228;INTERVAL=1;BYDAY=4TH
DTSTART
:20060126T230000Z
DTEND
:20060127T000000Z
DESCRIPTION
:Repeat Meeting: - Occurs every 4th Thursday of each month
END:VEVENT
END:VCALENDAR

View File

@ -1,16 +0,0 @@
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
PRODID:-//LinkeSOFT GmbH//NONSGML DIMEX//EN
BEGIN:VEVENT
SEQUENCE:0
RRULE:FREQ=DAILY\;COUNT=10
DTEND:20030101T080000
UID:2008-05-29T17:31:42+02:00_865561242
CATEGORIES:Unfiled
SUMMARY:Something
DTSTART:20030101T070000
DTSTAMP:20080529T152100
END:VEVENT
END:VCALENDAR

View File

@ -1,5 +0,0 @@
sillyname:name
profile:sillyprofile
stuff:folded
line
morestuff;asinine:this line is not folded, but in practice probably ought to be, as it is exceptionally long, and moreover demonstratively stupid

View File

@ -1,11 +0,0 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//PYVOBJECT//NONSGML Version 1//EN
BEGIN:VEVENT
UID:Not very random UID
DTSTART:20060509T000000
CREATED:20060101T180000Z
DESCRIPTION:Test event
DTSTAMP:20170626T000000Z
END:VEVENT
END:VCALENDAR

View File

@ -1,13 +0,0 @@
BEGIN:VCARD
VERSION:3.0
FN:Daffy Duck Knudson (with Bugs Bunny and Mr. Pluto)
N:Knudson;Daffy Duck (with Bugs Bunny and Mr. Pluto)
NICKNAME:gnat and gnu and pluto
BDAY;value=date:02-10
TEL;type=HOME:+01-(0)2-765.43.21
TEL;type=CELL:+01-(0)5-555.55.55
ACCOUNT;type=HOME:010-1234567-05
ADR;type=HOME:;;Haight Street 512\;\nEscape\, Test;Novosibirsk;;80214;Gnuland
TEL;type=HOME:+01-(0)2-876.54.32
ORG:University of Novosibirsk;Department of Octopus Parthenogenesis
END:VCARD

View File

@ -1,5 +0,0 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
SUMMARY;blah=hi!:Bastille Day Party
END:VEVENT
END:VCALENDAR

View File

@ -1,41 +0,0 @@
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
X-WR-TIMEZONE;VALUE=TEXT:US/Pacific
METHOD:PUBLISH
PRODID:-//Apple Computer\, Inc//iCal 1.0//EN
X-WR-CALNAME;VALUE=TEXT:Example
VERSION:2.0
BEGIN:VEVENT
SEQUENCE:5
DTSTART;TZID=US/Pacific:20021028T140000
RRULE:FREQ=Weekly;COUNT=10
DTSTAMP:20021028T011706Z
SUMMARY:Coffee with Jason
UID:EC9439B1-FF65-11D6-9973-003065F99D04
DTEND;TZID=US/Pacific:20021028T150000
BEGIN:VALARM
TRIGGER;VALUE=DURATION:-P1D
ACTION:DISPLAY
DESCRIPTION:Event reminder\, with comma\nand line feed
END:VALARM
END:VEVENT
BEGIN:VTIMEZONE
X-LIC-LOCATION:Random location
TZID:US/Pacific
LAST-MODIFIED:19870101T000000Z
BEGIN:STANDARD
DTSTART:19671029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
END:VCALENDAR

View File

@ -1,107 +0,0 @@
BEGIN:VTIMEZONE
TZID:US/Pacific
BEGIN:STANDARD
DTSTART:19671029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:US/Eastern
BEGIN:STANDARD
DTSTART:19671029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:Santiago
BEGIN:STANDARD
DTSTART:19700314T000000
TZOFFSETFROM:-0300
TZOFFSETTO:-0400
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SA
TZNAME:Pacific SA Standard Time
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19701010T000000
TZOFFSETFROM:-0400
TZOFFSETTO:-0300
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=2SA
TZNAME:Pacific SA Daylight Time
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:W. Europe
BEGIN:STANDARD
DTSTART:19701025T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
TZNAME:W. Europe Standard Time
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19700329T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
TZNAME:W. Europe Daylight Time
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:US/Fictitious-Eastern
LAST-MODIFIED:19870101T000000Z
BEGIN:STANDARD
DTSTART:19671029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870405T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T070000Z
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:America/Montreal
LAST-MODIFIED:20051013T233643Z
BEGIN:DAYLIGHT
DTSTART:20050403T070000
TZOFFSETTO:-0400
TZOFFSETFROM:+0000
TZNAME:EDT
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:20051030T020000
TZOFFSETTO:-0500
TZOFFSETFROM:-0400
TZNAME:EST
END:STANDARD
END:VTIMEZONE

View File

@ -1,31 +0,0 @@
BEGIN:VTIMEZONE
TZID:US/Eastern
BEGIN:STANDARD
DTSTART:20001029T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10;UNTIL=20061029T060000Z
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
BEGIN:STANDARD
DTSTART:20071104T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20000402T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20060402T070000Z
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
BEGIN:DAYLIGHT
DTSTART:20070311T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
END:VTIMEZONE

View File

@ -1,23 +0,0 @@
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Екатеринбург
BEGIN:STANDARD
DTSTART:16011028T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:+0600
TZOFFSETTO:+0500
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010325T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
TZOFFSETFROM:+0500
TZOFFSETTO:+0600
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:CyrillicTest
DTSTART;TZID=Екатеринбург:20080530T150000
END:VEVENT
END:VCALENDAR

View File

@ -1,39 +0,0 @@
BEGIN:VCALENDAR
METHOD:PUBLISH
CALSCALE:GREGORIAN
PRODID:-//EVDB//www.evdb.com//EN
VERSION:2.0
X-WR-CALNAME:EVDB Event Feed
BEGIN:VEVENT
DTSTART:20060922T000100Z
DTEND:20060922T050100Z
DTSTAMP:20050914T163414Z
SUMMARY:The title こんにちはキティ
DESCRIPTION:hello\nHere is a description\n\n\nこんにちはキティ
\n\n\n\nZwei Java-schwere Entwicklerpositionen und irgendeine Art sond
erbar-klingende Netzsichtbarmachungöffnung\, an einer interessanten F
irma im Gebäude\, in dem ich angerufenen Semantic Research bearbeite.
1. Zauberer Des Semantica Software Engineer 2. Älterer Semantica Sof
tware-Englisch-3. Graph/Semantica Netz-Visualization/Navigation Sie ei
ngestufte Software-Entwicklung für die Regierung. Die Firma ist stark
und die Projekte sind sehr kühl und schließen irgendeinen Spielraum
ein. Wenn ich Ihnen irgendwie mehr erkläre\, muß ich Sie töten. Ps
. Tat schnell -- jemand ist\, wenn es hier interviewt\, wie ich dieses
schreibe. Er schaut intelligent (er trägt Kleidhosen) Semantica Soft
ware Engineer FIRMA: Semantische Forschung\, Inc. REPORTS ZU: Vizeprä
sident\, Produkt-Entwicklung POSITION: San Diego (Pint Loma) WEB SITE:
www.semanticresearch.com email: dorie@semanticresearch.com FIRMA-HINT
ERGRUND Semantische Forschung ist der führende Versorger der semantis
cher Netzwerkanschluß gegründeten nicht linearen Wissen Darstellung
Werkzeuge. Die Firma stellt diese Werkzeuge zum Intel\, zur reg.\, zum
EDU und zu den kommerziellen Märkten zur Verfügung. BRINGEN SIE ZUS
AMMENFASSUNG IN POSITION Semantische Forschung\, Inc. basiert in San D
iego\, Ca im alten realen Weltsan Diego Haus...\, das wir den Weltbest
en Platz haben zum zu arbeiten. Wir suchen nach Superstarentwicklern\,
um uns in der fortfahrenden Entwicklung unserer Semantica Produktseri
e zu unterstützen.
LOCATION:こんにちはキティ
SEQUENCE:0
UID:E0-001-000276068-2
END:VEVENT
END:VCALENDAR

View File

@ -1,18 +0,0 @@
home.begin:vcard
version:3.0
source:ldap://cn=Meister%20Berger,o=Universitaet%20Goerlitz,c=DE
name:Meister Berger
fn:Meister Berger
n:Berger;Meister
bday;value=date:1963-09-21
o:Universit=E6t G=F6rlitz
title:Mayor
title;language=de;value=text:Burgermeister
note:The Mayor of the great city of
Goerlitz in the great country of Germany.\nNext line.
email;internet:mb@goerlitz.de
home.tel;type=fax,voice;type=msg:+49 3581 123456
home.label:Hufenshlagel 1234\n
02828 Goerlitz\n
Deutschland
END:VCARD

View File

@ -1,13 +0,0 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VTODO
UID:20070313T123432Z-456553@example.com
DTSTAMP:20070313T123432Z
DUE;VALUE=DATE:20070501
SUMMARY:Submit Quebec Income Tax Return for 2006
CLASS:CONFIDENTIAL
CATEGORIES:FAMILY,FINANCE
STATUS:NEEDS-ACTION
END:VTODO
END:VCALENDAR

View File

@ -5,11 +5,5 @@ test = pytest
python-tag = py3
[tool:pytest]
addopts = --flake8 --isort --cov radicale --cov radicale_vobject -r s
norecursedirs = dist .cache .git build Radicale.egg-info .eggs venv
[isort]
skip = radicale_vobject
[flake8]
exclude = radicale_vobject/*
addopts = --flake8 --isort --cov radicale -r s
norecursedirs = dist .cache .git build Radicale.egg-info .eggs venv radicale_vobject