ValueError: A VEVENT must have at most one CATEGORIES: How to figure out at which VEVENT reading fails?
I'm using ics-py through https://github.com/prometheus42/libreoffice-ical-importer/blob/master/src/ical2csv.py . When trying to convert a calendar exported from Thunderbird, I get following error:
src/ical2csv.py ~/Dokumente/Privat.ics Writing to CSV file: /home/me/Dokumente/Privat.ics.csv Reading iCalendar file... Traceback (most recent call last): File "src/ical2csv.py", line 91, in
convert_ical_file() File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/click/core.py", line 1130, in call return self.main(*args, **kwargs) File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/click/core.py", line 1055, in main rv = self.invoke(ctx) File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/click/core.py", line 1404, in invoke return ctx.invoke(self.callback, **ctx.params) File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/click/core.py", line 760, in invoke return __callback(*args, **kwargs) File "src/ical2csv.py", line 66, in convert_ical_file write_csv_file(read_ical_file(icalendar_file), csv_file) File "src/ical2csv.py", line 24, in read_ical_file c = Calendar(calendar_file.read()) File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/ics/icalendar.py", line 69, in init self._populate(containers[0]) # Use first calendar File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/ics/component.py", line 59, in _populate parser(self, lines) # Send a list or empty list File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/ics/parsers/icalendar_parser.py", line 71, in parse_vevent calendar.events = set(map(event_factory, lines)) File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/ics/parsers/icalendar_parser.py", line 69, in event_factory return Event._from_container(x, tz=calendar._timezones) File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/ics/component.py", line 31, in _from_container k._populate(container) File "/home/me/Downloads/programme/libreoffice-ical-importer/LO-ICAL/lib/python3.8/site-packages/ics/component.py", line 54, in _populate raise ValueError( ValueError: A VEVENT must have at most one CATEGORIES
I checked the file, all events have at most one category. How can I figure out at which VEVENT the import / reading of the calendar fails? Why isn't this information output by default?
Hi :)
Would it be possible to share the ics file that is making ics fail ? Also, could you try with the pre-release version of 0.8 to see if it still fails and if so, if the error message is better. (pip install --pre ics to install ics-0.8.0.dev0)
Hi,
I am joining the conversation as I observed some similar issue with v0.7.2, but when a VEVENT was actually part of more than one category (example: "VACATION" and "OUT-OF-OFFICE") :)
Situation that can indeed occurs according to RFC 5545:
Description: This property is used to specify categories or subtypes of the calendar component. The categories are useful in searching for a calendar component of a particular type and category. Within the "VEVENT", "VTODO", or "VJOURNAL" calendar components, more than one category can be specified as a COMMA-separated list of categories.
The 0.8.0-dev0 version was not helpful in my case as I observed some other issue (when passing in datetime formated with arrow module).
However, I could iterate a bit on the ics code (v0.7.2) and see the troubles in the event_parser.py (walking from the ValueError raised line 56 on component.py).
Coming from the idea the event.categories is defined as a set(), I played with the @option decorator and produced some results when combined with exploding line potentially now a List()
However:
- It is a bit dirty
- I am not 100% sure there are no side effects as I do not master the codebase of the module
@option(multiple=True)
def parse_categories(event, line):
event.categories = set()
if line:
#breakpoint()
# In the regular expression: Only match unquoted commas.
#for cat in re.split("(?<!\\\\),", line.value):
for lin in line:
for cat in re.split("(?<!\\\\),", lin.value):
event.categories.update({unescape_string(cat)})
... But given that you are now treating the categories as a List() in the 0.8.0-dev0 version, I guess it will potentially solve our problems :)
My recommendation would be to migrate to 0.8. It removed arrow as that caused multiple issues with time zones and local time stamps, but it also added a revamped parser, which e.g. now also stores line numbers with the parsed data for better error reporting. If you really need arrow, you can simply (un)wrap the time stamps that are passed between your code and the library.