From 9f03d0471dfac7dbc325dbfad8f4016e53f854a9 Mon Sep 17 00:00:00 2001 From: George Lemon Date: Fri, 12 Apr 2024 16:56:06 +0300 Subject: [PATCH] wip Signed-off-by: George Lemon --- ical.nimble | 13 ++++++ src/ical.nim | 90 ++++++++++++++++++++++++++++++++++++++++++ src/ical/submodule.nim | 12 ++++++ tests/config.nims | 1 + tests/test1.nim | 8 ++++ 5 files changed, 124 insertions(+) create mode 100644 ical.nimble create mode 100644 src/ical.nim create mode 100644 src/ical/submodule.nim create mode 100644 tests/config.nims create mode 100644 tests/test1.nim diff --git a/ical.nimble b/ical.nimble new file mode 100644 index 0000000..b23edde --- /dev/null +++ b/ical.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "George Lemon" +description = "A tolerant, minimal iCalendar reader & writer for Nim" +license = "MIT" +srcDir = "src" + + +# Dependencies + +requires "nim >= 2.0.2" +requires "uuid4" \ No newline at end of file diff --git a/src/ical.nim b/src/ical.nim new file mode 100644 index 0000000..c7a8fdf --- /dev/null +++ b/src/ical.nim @@ -0,0 +1,90 @@ +# A tolerant, minimal iCalendar reader & writer for Nim. +# +# (c) 2024 George Lemon | MIT license +# Made by Humans from OpenPeeps +# https://github.com/openpeeps/ical + +import std/[strutils, tables, times] +import pkg/uuid4 + +type + CalendarEventStatus* = enum # VEVENT + eventTentative = "TENTATIVE" + eventConfirmed = "CONFIRMED" + eventCanceled = "CANCELED" + + CalendarTodoStatus* = enum # VTODO + todoNeedsAction = "NEEDS-ACTION" + todoCompleted = "COMPLETED" + todoInProcess = "IN-PROCESS" + todoCanceled = "CANCELED" + + CalendarJournalStatus* = enum # VJOURNAL + journalDraft = "DRAFT" + journalFinal = "FINAL" + journalCanceled = "CANCELED" + + CalendarType* = enum + calendarTypeEvent = "VEVENT" + calendarTypeTodo = "VTODO" + calendarTypeJournal = "VJOURNAL" + + CalendarEvent* = object + id: Uuid + case calendarType: CalendarType + of calendarTypeEvent: + eventStatus: CalendarEventStatus + eventStartDate, eventEndDate: DateTime + else: discard # todo + + Calendar* = object + id: string + locale: string = "EN" + events: OrderedTable[string, CalendarEvent] + +const + # https://github.com/peterbraden/ical.js/blob/master/examples/example_rrule.ics + # https://icalendar.org/iCalendar-RFC-5545/4-icalendar-object-examples.html + propProdid = "PRODID:-//$1//$2\n" + propBegin = "BEGIN:$1\n" + propEnd = "END:$1\n" + propVersion = "VERSION:$1\n" + propScale = "CALSCALE:GREGORIAN\n" + propMethod = "METHOD:$1\n" + propUuid = "UID:$1\n" + propDTStart = "DTSTART:$1\n" + propStatus = "STATUS:$1\n" + propDTEnd = "DTEND:$1\n" + propDTStamp = "DTSTAMP:$1\n" + propLastModified = "LAST-MODIFIED:$1\n" + +proc initCalendar*(id: string): Calendar = + Calendar(id: id) + +proc event*(cal: var Calendar, startDate, endDate: DateTime, + status: CalendarEventStatus = eventConfirmed) = + let id = uuid4() + cal.events[$id] = CalendarEvent(id: id, + eventStartDate: startDate, + eventEndDate: endDate, + eventStatus: status, + calendarType: CalendarType.calendarTypeEvent + ) + +proc `$`*(cal: Calendar): string = + result = propBegin % ["VCALENDAR"] + add result, propVersion % "2.0" + add result, propProdid % [cal.id, cal.locale] + add result, propMethod % "PUBLISH" + for id, ev in cal.events: + add result, propBegin % $(ev.calendarType) + add result, propDTStamp % format(now(), "yyyyMMdd'T'HHmmss") + add result, propUuid % id + case ev.calendarType + of calendarTypeEvent: + add result, propStatus % $(ev.eventStatus) + add result, propDTStart % format(ev.eventStartDate, "yyyyMMdd") + add result, propDTEND % format(ev.eventEndDate, "yyyyMMdd") + else: discard # todo + add result, propEnd % $(ev.calendarType) + add result, propEnd % ["VCALENDAR"] diff --git a/src/ical/submodule.nim b/src/ical/submodule.nim new file mode 100644 index 0000000..8e21c99 --- /dev/null +++ b/src/ical/submodule.nim @@ -0,0 +1,12 @@ +# This is just an example to get you started. Users of your library will +# import this file by writing ``import ical/submodule``. Feel free to rename or +# remove this file altogether. You may create additional modules alongside +# this file as required. + +type + Submodule* = object + name*: string + +proc initSubmodule*(): Submodule = + ## Initialises a new ``Submodule`` object. + Submodule(name: "Anonymous") diff --git a/tests/config.nims b/tests/config.nims new file mode 100644 index 0000000..3bb69f8 --- /dev/null +++ b/tests/config.nims @@ -0,0 +1 @@ +switch("path", "$projectDir/../src") \ No newline at end of file diff --git a/tests/test1.nim b/tests/test1.nim new file mode 100644 index 0000000..fc7bd45 --- /dev/null +++ b/tests/test1.nim @@ -0,0 +1,8 @@ +import unittest, times +import ical + +test "can add": + var cal = initCalendar("GOODCORP") + cal.event(now() + 1.days, now() + 2.days) + cal.event(now() + 4.days, now() + 10.days) + echo cal \ No newline at end of file