kopia lustrzana https://github.com/collective/icalendar
used bytestrings where appropriate
needed to introduce a unicode version of FOLD called uFOLD some internal cleanup seems to be needed, not everything uses unicode just yetpull/113/head
rodzic
c32987cf12
commit
fa22b7763e
|
@ -93,9 +93,10 @@ def param_value(value):
|
|||
|
||||
# Could be improved
|
||||
NAME = re.compile('[\w-]+')
|
||||
UNSAFE_CHAR = re.compile(b'[\x00-\x08\x0a-\x1f\x7F",:;]')
|
||||
QUNSAFE_CHAR = re.compile(b'[\x00-\x08\x0a-\x1f\x7F"]')
|
||||
UNSAFE_CHAR = re.compile('[\x00-\x08\x0a-\x1f\x7F",:;]')
|
||||
QUNSAFE_CHAR = re.compile('[\x00-\x08\x0a-\x1f\x7F"]')
|
||||
FOLD = re.compile(b'(\r?\n)+[ \t]')
|
||||
uFOLD = re.compile(u'(\r?\n)+[ \t]')
|
||||
NEWLINE = re.compile(r'\r?\n')
|
||||
|
||||
|
||||
|
@ -328,7 +329,7 @@ class Contentline(compat.unicode_type):
|
|||
"""
|
||||
ical = to_unicode(ical)
|
||||
# a fold is carriage return followed by either a space or a tab
|
||||
return cls(FOLD.sub('', ical), strict=strict)
|
||||
return cls(uFOLD.sub('', ical), strict=strict)
|
||||
|
||||
def to_ical(self):
|
||||
"""Long content lines are folded so they are less than 75 characters.
|
||||
|
@ -351,12 +352,13 @@ class Contentlines(list):
|
|||
def from_ical(cls, st):
|
||||
"""Parses a string into content lines.
|
||||
"""
|
||||
st = to_unicode(st)
|
||||
try:
|
||||
# a fold is carriage return followed by either a space or a tab
|
||||
unfolded = FOLD.sub(b'', st)
|
||||
unfolded = uFOLD.sub('', st)
|
||||
lines = cls(Contentline(line) for
|
||||
line in unfolded.splitlines() if line)
|
||||
lines.append(b'') # '\r\n' at the end of every content line
|
||||
lines.append('') # '\r\n' at the end of every content line
|
||||
return lines
|
||||
except:
|
||||
raise
|
||||
|
|
|
@ -18,8 +18,8 @@ class TestPropertyParams(unittest.TestCase):
|
|||
ical.add('organizer', cal_address)
|
||||
|
||||
ical_str = Calendar.to_ical(ical)
|
||||
exp_str = """BEGIN:VCALENDAR\r\nORGANIZER;CN="Doe, John":"""\
|
||||
"""mailto:john.doe@example.org\r\nEND:VCALENDAR\r\n"""
|
||||
exp_str = b"""BEGIN:VCALENDAR\r\nORGANIZER;CN="Doe, John":"""\
|
||||
b"""mailto:john.doe@example.org\r\nEND:VCALENDAR\r\n"""
|
||||
|
||||
self.assertEqual(ical_str, exp_str)
|
||||
|
||||
|
@ -34,23 +34,25 @@ class TestPropertyParams(unittest.TestCase):
|
|||
vevent = Event()
|
||||
vevent['ORGANIZER'] = cal_address
|
||||
self.assertEqual(
|
||||
vevent.to_ical(),
|
||||
'BEGIN:VEVENT\r\n'
|
||||
'ORGANIZER;CN="Джон Доу":mailto:john.doe@example.org\r\n'
|
||||
'END:VEVENT\r\n'
|
||||
vevent.to_ical().decode('utf-8'),
|
||||
u'BEGIN:VEVENT\r\n'
|
||||
u'ORGANIZER;CN="Джон Доу":mailto:john.doe@example.org\r\n'
|
||||
u'END:VEVENT\r\n'
|
||||
)
|
||||
self.assertEqual(vevent['ORGANIZER'].params['CN'], 'Джон Доу')
|
||||
|
||||
self.assertEqual(vevent['ORGANIZER'].params['CN'],
|
||||
'Джон Доу')
|
||||
|
||||
def test_quoting(self):
|
||||
# not double-quoted
|
||||
self._test_quoting(u"Aramis", 'Aramis')
|
||||
self._test_quoting(u"Aramis", u'Aramis')
|
||||
# if a space is present - enclose in double quotes
|
||||
self._test_quoting(u"Aramis Alameda", '"Aramis Alameda"')
|
||||
self._test_quoting(u"Aramis Alameda", u'"Aramis Alameda"')
|
||||
# a single quote in parameter value - double quote the value
|
||||
self._test_quoting("Aramis d'Alameda", '"Aramis d\'Alameda"')
|
||||
self._test_quoting(u"Aramis d'Alameda", u'"Aramis d\'Alameda"')
|
||||
# double quote is replaced with single quote
|
||||
self._test_quoting("Aramis d\"Alameda", '"Aramis d\'Alameda"')
|
||||
self._test_quoting(u"Арамис д'Аламеда", '"Арамис д\'Аламеда"')
|
||||
self._test_quoting(u"Aramis d\"Alameda", u'"Aramis d\'Alameda"')
|
||||
self._test_quoting(u"Арамис д'Аламеда", u'"Арамис д\'Аламеда"')
|
||||
|
||||
def _test_quoting(self, cn_param, cn_quoted):
|
||||
"""
|
||||
|
@ -63,8 +65,8 @@ class TestPropertyParams(unittest.TestCase):
|
|||
vevent.add('ATTENDEE', attendee)
|
||||
self.assertEqual(
|
||||
vevent.to_ical(),
|
||||
'BEGIN:VEVENT\r\nATTENDEE;CN=%s:test@mail.com\r\nEND:VEVENT\r\n'
|
||||
% cn_quoted
|
||||
b'BEGIN:VEVENT\r\nATTENDEE;CN=' + cn_quoted.encode('utf-8') +
|
||||
b':test@mail.com\r\nEND:VEVENT\r\n'
|
||||
)
|
||||
|
||||
def test_escaping(self):
|
||||
|
@ -91,18 +93,18 @@ class TestPropertyParams(unittest.TestCase):
|
|||
r'that, that; %th%%at%\ that:'
|
||||
)
|
||||
self.assertEqual(
|
||||
vevent['ORGANIZER'].to_ical(),
|
||||
r'это, то; that\ %th%%at%:'
|
||||
vevent['ORGANIZER'].to_ical().decode('utf-8'),
|
||||
u'это, то; that\\ %th%%at%:'
|
||||
)
|
||||
|
||||
def test_parameters_class(self):
|
||||
|
||||
# Simple parameter:value pair
|
||||
p = Parameters(parameter1='Value1')
|
||||
self.assertEqual(p.to_ical(), 'PARAMETER1=Value1')
|
||||
self.assertEqual(p.to_ical(), b'PARAMETER1=Value1')
|
||||
|
||||
# keys are converted to upper
|
||||
self.assertEqual(p.keys(), ['PARAMETER1'])
|
||||
self.assertEqual(list(p.keys()), ['PARAMETER1'])
|
||||
|
||||
# Parameters are case insensitive
|
||||
self.assertEqual(p['parameter1'], 'Value1')
|
||||
|
@ -110,22 +112,22 @@ class TestPropertyParams(unittest.TestCase):
|
|||
|
||||
# Parameter with list of values must be seperated by comma
|
||||
p = Parameters({'parameter1': ['Value1', 'Value2']})
|
||||
self.assertEqual(p.to_ical(), 'PARAMETER1=Value1,Value2')
|
||||
self.assertEqual(p.to_ical(), b'PARAMETER1=Value1,Value2')
|
||||
|
||||
# Multiple parameters must be seperated by a semicolon
|
||||
p = Parameters({'RSVP': 'TRUE', 'ROLE': 'REQ-PARTICIPANT'})
|
||||
self.assertEqual(p.to_ical(), 'ROLE=REQ-PARTICIPANT;RSVP=TRUE')
|
||||
self.assertEqual(p.to_ical(), b'ROLE=REQ-PARTICIPANT;RSVP=TRUE')
|
||||
|
||||
# Parameter values containing ',;:' must be double quoted
|
||||
p = Parameters({'ALTREP': 'http://www.wiz.org'})
|
||||
self.assertEqual(p.to_ical(), 'ALTREP="http://www.wiz.org"')
|
||||
self.assertEqual(p.to_ical(), b'ALTREP="http://www.wiz.org"')
|
||||
|
||||
# list items must be quoted seperately
|
||||
p = Parameters({'MEMBER': ['MAILTO:projectA@host.com',
|
||||
'MAILTO:projectB@host.com']})
|
||||
self.assertEqual(
|
||||
p.to_ical(),
|
||||
'MEMBER="MAILTO:projectA@host.com","MAILTO:projectB@host.com"'
|
||||
b'MEMBER="MAILTO:projectA@host.com","MAILTO:projectB@host.com"'
|
||||
)
|
||||
|
||||
# Now the whole sheebang
|
||||
|
@ -134,8 +136,8 @@ class TestPropertyParams(unittest.TestCase):
|
|||
'ALTREP': ['http://www.wiz.org', 'value4']})
|
||||
self.assertEqual(
|
||||
p.to_ical(),
|
||||
('ALTREP="http://www.wiz.org",value4;PARAMETER1=Value1;'
|
||||
'PARAMETER2=Value2,Value3')
|
||||
(b'ALTREP="http://www.wiz.org",value4;PARAMETER1=Value1;'
|
||||
b'PARAMETER2=Value2,Value3')
|
||||
)
|
||||
|
||||
# We can also parse parameter strings
|
||||
|
@ -198,7 +200,7 @@ END:VCALENDAR"""
|
|||
event = cal.walk("VEVENT")[0]
|
||||
event['attendee'][0]
|
||||
self.assertEqual(event['attendee'][0].to_ical(),
|
||||
'MAILTO:rembrand@xs4all.nl')
|
||||
b'MAILTO:rembrand@xs4all.nl')
|
||||
self.assertEqual(event['attendee'][0].params.to_ical(),
|
||||
'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE')
|
||||
b'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE')
|
||||
self.assertEqual(event['attendee'][0].params['cn'], u'RembrandXS')
|
||||
|
|
Ładowanie…
Reference in New Issue