icalendar_actor/src/icalendar_actor.nim

61 lines
2.1 KiB
Nim

# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[json, sequtils, tables, uri]
import preserves, preserves/jsonhooks, syndicate
from syndicate/protocols/dataspace import Observe
import ./icalendar_components
type Observe = dataspace.Observe[Cap]
type BootArgs {.preservesDictionary.} = object
dataspace: Cap
proc importCalendar(location: string): Component =
let uri = parseUri(location)
if uri.scheme != "file":
raiseAssert """only supported calendar schema is "file" ignoring """ & location
else:
var
js = parseFile(uri.path)
pr = jsonhooks.toPreserveHook(js, void)
if not result.fromPreserve(pr):
# TODO: convert directly from JsonNode
raise newException(ValueError, "Preserves was not a valid iCalendar component")
if result.label != "vcalendar":
raise newException(ValueError, "Preserves was not a valid vcalendar @component")
proc toPreserveHook(prop: Property; E: typedesc): Preserve[E] =
initRecord(prop.label,
prop.parameters.toPreserve(E),
prop.`type`.toPreserve(E),
prop.values.toPreserve(E),
)
proc toPreserveHook(comp: Component; E: typedesc): Preserve[E] =
initRecord(comp.label,
comp.properties.toPreserve(E),
comp.components.toPreserve(E),
)
proc serve(turn: var Turn; url: string): Cap =
let ds = newDataspace(turn)
let calendar = importCalendar(url)
run(turn.facet) do (turn: var Turn):
for prop in calendar.properties:
discard publish(turn, ds, prop)
for comp in calendar.components:
discard publish(turn, ds, comp)
ds
runActor("icalendar_actor") do (root: Cap; turn: var Turn):
connectStdio(root, turn)
stderr.writeLine "connected stdio to ", root
during(turn, root, ?BootArgs) do (ds: Cap):
stderr.writeLine "got dataspace at ", ds
during(turn, ds, ?Observe(pattern: !CalendarDataspace) ?? {0: grabLit()}) do (url: string):
let cap = serve(turn, url)
stderr.writeLine "serving ", url, " at ", cap
discard publish(turn, ds, initRecord("calendar", url.toPreserve(Cap), cap.toPreserve(Cap)))