fix(import): read the Fossify/Simple Calendar .ics dialect (#225)
Their exporter writes the last day an all-day event occupies as DTEND, where RFC 5545 means the day after. Read literally every all-day event was a day short and single-day ones — birthdays, memorials, name days — came out zero length, which the provider expands into no instances at all, so they never appeared. IcsQuirks sniffs the producer and shifts the end; independently, an all-day event may no longer end at or before its start and an all-day DURATION is floored at P1D. Fossify also emits a bare ";BYDAY=" for weekly events with no weekday mask. EventRecurrence.parse throws on that, out of insert, and nothing caught it — one such row failed the entire file. sanitizeRrule now drops empty and malformed parts, and importEvents isolates each event, counting rejects into IcsImportSummary.failed instead of unwinding the batch. Rest of the dialect: VTODO imports as events (was dropped silently), CATEGORIES stands in for the X-WR-CALNAME they never write, bare EXDATE day codes resolve against a timed series' own time of day, and their positive VALARM trigger is read as "on the day" so all-day reminders fire at the hour the setting names rather than at UTC midnight. Colours come across too: X-FOSSIFY-EVENT-COLOR / COLOR / the category colour as fallback, plus the X-SMT-* legacy spellings, snapped in Oklab to the nearest key a palette account publishes since those reject a raw EVENT_COLOR. Closes #225
This commit is contained in:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- **Calendars imported from Fossify Calendar arrive intact.** Fossify writes the
|
||||
last day an all-day event occupies where iCalendar means the day after it, so
|
||||
every birthday, anniversary and memorial in an export was zero days long and
|
||||
vanished on import — and a faulty repeat rule it writes for weekly events
|
||||
could abort the whole file with nothing but "couldn't read this" on screen.
|
||||
Both are handled now: an event the calendar refuses is left out and counted
|
||||
instead of costing you the rest of the import, tasks come across as events
|
||||
rather than being dropped in silence, deleted occurrences of a repeating event
|
||||
stay deleted, and reminders land at the time you chose rather than at midnight
|
||||
([#225]).
|
||||
- **Imported events keep their colour.** A colour from another app is matched to
|
||||
the closest one your calendar's account offers, so a migrated calendar still
|
||||
reads at a glance ([#225]).
|
||||
|
||||
## [2.19.2] — 2026-08-17
|
||||
|
||||
### Changed
|
||||
@@ -1455,3 +1470,4 @@ automatically, with zero telemetry and no internet permission.
|
||||
[#192]: https://codeberg.org/jlmakiola/calendula/issues/192
|
||||
[#196]: https://codeberg.org/jlmakiola/calendula/issues/196
|
||||
[#214]: https://codeberg.org/jlmakiola/calendula/issues/214
|
||||
[#225]: https://codeberg.org/jlmakiola/calendula/issues/225
|
||||
|
||||
Reference in New Issue
Block a user