Repository navigation
Add iCalendar (.ics) to CSV conversion and back (#340) - #381
Conversation
- Read VEVENT and VTODO into 14 CSV columns: ISO 8601 times with the original offset, all-day as dates, TZID in its own column, RRULE, EXDATE and RECURRENCE-ID kept raw; JSON and other data formats via CSV. - Resolve offsets from a same-calendar VTIMEZONE without RRULE first, then the system time-zone database, else keep floating time. - Write CSV back to iCalendar (VEVENT/VTODO, VTIMEZONE built from the zone's real transitions, 75-octet folding, no BOM). - Register ics/ical on the data donut, add an "iCalendar" preset on the back of the spreadsheets donut (settings schema 33), update the data engine description in every UI language and the docs. Closes KnifeLemon#340
Windows has no history for Nepal Standard Time (always +05:45), so the 1985 +05:30 case failed there. Moscow (+04:00 in 2013, +03:00 now) has the same history on Windows and in the IANA database.
|
@SeoJCalive 님, 정말 감사합니다. #340에서 합의한 내용을 그대로 구현해 주셨고, 실제 Apple·Google 캘린더로 왕복 테스트까지 해 주셔서 큰 도움이 됐습니다. CI는 초록이고, 로컬에서도 format, 빌드, Core, 데이터 엔진 테스트(94개), 로컬라이제이션 테스트가 모두 통과했습니다. 질문 주신 부분에 답변드립니다.
Draft를 풀기 전에 하나만 고쳐 주세요. CSV → ICS 변환에서 일부 셀이 그대로 출력됩니다. UID나 RRULE에 줄바꿈이 있거나, EXDATE/Recurrence ID에 EXDATE/RECURRENCE-ID가 아닌 줄이 있으면 그 줄이 별도의 콘텐츠 줄로 들어갑니다. 실제로 RRULE 셀에 BEGIN:VALARM을, EXDATE 셀에 END:VEVENT / BEGIN:VEVENT / SUMMARY:Injected를 넣은 CSV로 시험해 보니, 만들어진 .ics에 일정이 하나 더 생기고 VALARM은 닫히지 않았습니다. CSV는 다른 사람에게서 받아 캘린더로 가져올 수도 있으니 아래처럼 부탁드립니다.
이 경우에 대한 테스트와 스키마 번호만 정리해서 Ready로 바꿔 주시면 머지하겠습니다. 다시 한번 감사드립니다! |
A CSV cell could break out of its property when converting CSV to ICS: a line break in UID or RRULE, or extra lines in the EXDATE and Recurrence ID columns, became content lines of their own (an extra VEVENT, an unclosed VALARM). - UID, RRULE and Time zone with CR or LF are dropped (UID falls back to the generated one); a time zone with ':', ';' or '"' is dropped too. - EXDATE and Recurrence ID columns keep only EXDATE / RECURRENCE-ID lines. - Organizer and attendee cells lose CR/LF, and quotes are removed from the CN display name. Filee's own ICS -> CSV output writes those three cells on one line, so round trips are unchanged.
|
@KnifeLemon 님, 직접 만든 CSV로 시험해 주셔서 감사합니다. 말씀대로 CSV → ICS 쪽이 그 셀들을 그대로 믿고 있었습니다. 1c06463에서 고쳤습니다.
Filee의 ICS → CSV 출력은 UID, RRULE, Time zone을 한 줄로 쓰기 때문에, 왕복 변환 결과는 달라지지 않습니다. #351이 머지되면 리베이스해서 알려 주시는 다음 빈 스키마 번호로 옮기고, 먼저 들어온 언어 파일(zh-TW, fr 등)에도 문장을 추가한 뒤 Ready로 바꾸겠습니다. |
|
@SeoJCalive 님, 1c06463 확인했어요. 말씀드린 경우가 모두 막혔고, 테스트도 딱 필요한 부분을 확인하네요. 빠르게 고쳐 주셔서 감사합니다! #351을 기다리실 필요는 없어요. 스키마 번호와 그사이 들어온 프랑스어·번체 중국어 파일의 문장은 머지할 때 저희가 맞출게요. 준비되시면 Draft만 풀어 주세요. |
|
@KnifeLemon님, 감사합니다 Draft는 풀어놓았습니다! |
KnifeLemon
left a comment
There was a problem hiding this comment.
Draft 해제 확인했어요. 감사합니다! 머지할 때 스키마 번호와 프랑스어·번체 중국어·네팔어 문장은 저희가 맞출게요.
|
@SeoJCalive 님, #464로 머지됐어요. 감사합니다! 설정 마이그레이션은 스키마 36이 됐고, 그사이 들어온 프랑스어·번체 중국어·네팔어 파일의 데이터 엔진 설명도 새 문장에 맞췄어요. 다음 릴리스에 들어가요. |
…ne text for fr, zh-TW, ne The iCalendar step becomes v36 after KnifeLemon#432's v35, AppSettings.CurrentSchemaVersion goes to 36 and the iCalendar migration test starts from 35. engine.data.description now names iCalendar events in English; French and Traditional Chinese still said vCard only, and Nepali had an older one-line text. All three now say what the English one says. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… zh-TW, ne The everyday-tools step becomes v37 after KnifeLemon#381's v36, AppSettings.CurrentSchemaVersion goes to 37, its offers table is Version37Offers, and the migration tests start from 36. French, Traditional Chinese and Nepali get the twelve new strings (the media tool preset names, the slideshow options and the too-many-pictures error) in en.json's order, using each file's existing terms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What does this change?
Closes #340. Following your answer in #340, iCalendar files now convert to CSV and JSON, and CSV converts back to iCalendar. It plugs into
DataConverterthe same way vCard does, with its own parser (Data/ICalendar.cs).Type,Title,Start,End,All day,Time zone,Location,Description,Organizer,Attendees,RRULE,EXDATE,Recurrence ID,UID.Type=todo. Their end comes fromDUE.X-properties, VJOURNAL and the like are skipped.2026-10-27T14:30:00+09:00). UTC values keep theirZ.Time zonecolumn.ics ↔ csv.Summary,Subject,제목,开始…).icsandicalare added to the data donut.engine.data.descriptionnow reads "vCard contacts and iCalendar events to CSV and back." in all 10 languages. There are no new keys. The data row inREADME.mdand the engine table and data section indocs/ENGINES.mdare updated too.How was it tested?
dotnet format --verify-no-changes: passesdotnet testICalendarTests)filee convert) with files exported from real calendar apps.--to csvand--to jsonresults matched what the app shows..icswith--to icsand imported it into a new calendar. All 4 events kept their times, all-day flag, recurrence (4 times, 1 excluded), location and note.Screenshots (UI changes)
(Not applicable) The only visible changes are one "iCalendar" chip on the back of the spreadsheets donut and the engine description. Instead, here is the conversion of a file exported from Google Calendar:
Checklist
src/Filee.App/Assets/i18n/*.jsonfiles (no new keys; the existing sentence is updated in all 10 languages)THIRD-PARTY-NOTICES.md(not applicable, no new libraries)Points I'd like you to check
1. Schema number
2. Overlap with #351
DataConverter.cs. If it is merged first, I'll rebase this PR.fr.json/ne.json.3. Google exports one-off events in UTC
DTSTART:20261027T053000Z.Ztime and an emptyTime zone. Recurring events keep their TZID and come out as+09:00.4. Known limits (also written in
docs/ENGINES.md)