kopia lustrzana https://github.com/collective/icalendar
Fixes bug when date-time is recognized as time
Date-time was recognized incorrectly as a date or time. This resulted in wrong representation of some iCalendar strings. Also adds "errors" list in Component for saving error strings from parsing. https://github.com/collective/icalendar/issues/174 https://github.com/collective/icalendar/issues/168pull/175/head
rodzic
ff1f2eec3d
commit
70a7b5a167
|
@ -10,6 +10,10 @@ New:
|
|||
|
||||
Fixes:
|
||||
|
||||
- Fixed date-time being recognized as date or time during parsing. Added
|
||||
better error handling to parsing from ical strings.
|
||||
[stlaz]
|
||||
|
||||
- Added __version__ attribute to init.py
|
||||
[TomTry]
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ icalendar contributors
|
|||
- Ronan Dunklau <ronan@dunklau.fr>
|
||||
- Russ <russ@rw.id.au>
|
||||
- Sidnei da Silva <sidnei@enfoldsystems.com>
|
||||
- Stanislav Láznička <slaznick@redhat.com>
|
||||
- Stanislav Ochotnicky <sochotnicky@redhat.com>
|
||||
- Stefan Schwarzer <sschwarzer@sschwarzer.net>
|
||||
- Thomas Bruederli <thomas@roundcube.net>
|
||||
|
|
|
@ -80,8 +80,8 @@ class Component(CaselessDict):
|
|||
super(Component, self).__init__(*args, **kwargs)
|
||||
# set parameters here for properties that use non-default values
|
||||
self.subcomponents = [] # Components can be nested.
|
||||
self.is_broken = False # True if we ignored an exception while
|
||||
# parsing a property
|
||||
self.errors = list() # If we ignored exception(s) while
|
||||
# parsing a property, contains error strings
|
||||
|
||||
# def is_compliant(self, name):
|
||||
# """Returns True is the given property name is compliant with the
|
||||
|
@ -309,14 +309,14 @@ class Component(CaselessDict):
|
|||
|
||||
try:
|
||||
name, params, vals = line.parts()
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
# if unable to parse a line within a component
|
||||
# that ignores exceptions, mark the component
|
||||
# as broken and skip the line. otherwise raise.
|
||||
component = stack[-1] if stack else None
|
||||
if not component or not component.ignore_exceptions:
|
||||
raise
|
||||
component.is_broken = True
|
||||
component.errors.append((None, str(e)))
|
||||
continue
|
||||
|
||||
uname = name.upper()
|
||||
|
@ -338,8 +338,7 @@ class Component(CaselessDict):
|
|||
if not stack: # we are at the end
|
||||
comps.append(component)
|
||||
else:
|
||||
if not component.is_broken:
|
||||
stack[-1].add_component(component)
|
||||
stack[-1].add_component(component)
|
||||
if vals == 'VTIMEZONE' and \
|
||||
'TZID' in component and \
|
||||
component['TZID'] not in pytz.all_timezones and \
|
||||
|
@ -356,10 +355,11 @@ class Component(CaselessDict):
|
|||
vals = factory(factory.from_ical(vals, params['TZID']))
|
||||
else:
|
||||
vals = factory(factory.from_ical(vals))
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
if not component.ignore_exceptions:
|
||||
raise
|
||||
component.is_broken = True
|
||||
component.errors.append((uname, str(e)))
|
||||
component.add(name, None, encode=0)
|
||||
else:
|
||||
vals.params = params
|
||||
component.add(name, vals, encode=0)
|
||||
|
|
|
@ -341,7 +341,7 @@ class Contentline(compat.unicode_type):
|
|||
return (name, params, values)
|
||||
except ValueError as exc:
|
||||
raise ValueError(
|
||||
u"Content line could not be parsed into parts: %r: %s"
|
||||
u"Content line could not be parsed into parts: '%s': %s"
|
||||
% (self, exc)
|
||||
)
|
||||
|
||||
|
|
|
@ -313,13 +313,15 @@ class vDDDTypes(object):
|
|||
u = ical.upper()
|
||||
if u.startswith(('P', '-P', '+P')):
|
||||
return vDuration.from_ical(ical)
|
||||
try:
|
||||
|
||||
if len(ical) in (15, 16):
|
||||
return vDatetime.from_ical(ical, timezone=timezone)
|
||||
except ValueError:
|
||||
try:
|
||||
return vDate.from_ical(ical)
|
||||
except ValueError:
|
||||
return vTime.from_ical(ical)
|
||||
elif len(ical) == 8:
|
||||
return vDate.from_ical(ical)
|
||||
elif len(ical) in (6,7):
|
||||
return vTime.from_ical(ical)
|
||||
else:
|
||||
raise ValueError("Expected datetime, date, or time, got: '%s'" % ical)
|
||||
|
||||
|
||||
class vDate(object):
|
||||
|
|
|
@ -200,7 +200,9 @@ X
|
|||
END:VEVENT"""
|
||||
event = icalendar.Calendar.from_ical(ical_str)
|
||||
self.assertTrue(isinstance(event, icalendar.Event))
|
||||
self.assertTrue(event.is_broken)
|
||||
self.assertEqual(event.errors,
|
||||
[(None, "Content line could not be parsed into parts: 'X': Invalid content line")]
|
||||
)
|
||||
|
||||
def test_issue_104__no_ignore_exceptions(self):
|
||||
"""
|
||||
|
|
|
@ -389,8 +389,9 @@ class TestCal(unittest.TestCase):
|
|||
directory = tempfile.mkdtemp()
|
||||
open(os.path.join(directory, 'test.ics'), 'wb').write(cal.to_ical())
|
||||
|
||||
# Parsing a complete calendar from a string will silently ignore bogus
|
||||
# events. The bogosity in the following is the third EXDATE: it has an
|
||||
# Parsing a complete calendar from a string will silently ignore wrong
|
||||
# events but adding the error information to the component's 'errors'
|
||||
# attribute. The error in the following is the third EXDATE: it has an
|
||||
# empty DATE.
|
||||
s = '\r\n'.join(('BEGIN:VCALENDAR',
|
||||
'PRODID:-//Google Inc//Google Calendar 70.9054//EN',
|
||||
|
@ -405,7 +406,7 @@ class TestCal(unittest.TestCase):
|
|||
'EXDATE;VALUE=DATE:20080311',
|
||||
'END:VEVENT',
|
||||
'BEGIN:VEVENT',
|
||||
'DESCRIPTION:Bogus event',
|
||||
'DESCRIPTION:Wrong event',
|
||||
'DTSTART;VALUE=DATE:20080303',
|
||||
'DTEND;VALUE=DATE:20080304',
|
||||
'RRULE:FREQ=DAILY;UNTIL=20080323T235959Z',
|
||||
|
@ -416,4 +417,9 @@ class TestCal(unittest.TestCase):
|
|||
self.assertEqual(
|
||||
[e['DESCRIPTION'].to_ical()
|
||||
for e in icalendar.cal.Calendar.from_ical(s).walk('VEVENT')],
|
||||
[b'Perfectly OK event'])
|
||||
[b'Perfectly OK event', b'Wrong event'])
|
||||
self.assertEqual(
|
||||
[e.errors
|
||||
for e in icalendar.cal.Calendar.from_ical(s).walk('VEVENT')],
|
||||
[[], [('EXDATE', "Expected datetime, date, or time, got: ''")]]
|
||||
)
|
||||
|
|
Ładowanie…
Reference in New Issue