/* This file is part of »zeitbild«. Copyright 2025 'kcf' »zeitbild« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »zeitbild« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »zeitbild«. If not, see . */ namespace _zeitbild.sample { /** */ type type_date_absolute = { year : int; month : int; day : int; }; /** */ type type_date_relative = Array< { action : "trunc_week"; args : [int]; } | { action : "shift_week"; args : [int]; } | { action : "shift_day"; args : [int]; } >; /** */ type type_ywd = { year : int; week : int; day : int; }; /** */ type type_time = { hour : int; minute : int; second : int; }; /** */ type type_datetime = ( { timezone_shift : int; time : (null | type_time); } & ( { date_absolute : type_date_absolute; } | { date_relative : type_date_relative; } ) ); /** */ type type_data = { users : Array< { id : int; name : string; email_address : string; dav_token : (null | string); password : string; } >; calendars : Array< { id : int; name : string; access : { public ?: boolean; default_level : ("none" | "view" | "edit" | "admin"); attributed : Array< { user_id : int; level : ("none" | "view" | "edit" | "admin"); } >; }; resource : ( { kind : "local"; data : { events : Array< { /** * @todo rename to "title" */ name : string; begin : type_datetime; end : ( null | type_datetime ); location : ( null | string ); link : ( null | string ); description : ( null | string ); } > }; } | { kind : "ics_feed"; data : { url : string; from_fucked_up_wordpress ?: boolean; }; } ); } >; }; /** */ function decode_datetime( datetime : type_datetime ) : lib_plankton.pit.type_datetime { if ("date_relative" in datetime) { return { "timezone_shift": datetime.timezone_shift, "date": lib_plankton.call.convey( lib_plankton.pit.now(), ( datetime.date_relative.map<(x : any) => any>( entry => { switch (entry.action) { // default: {throw (new Error("unhandled action: " + entry.action));} case "trunc_week": {return (x => lib_plankton.pit.trunc_week(x));} case "shift_week": {return (x => lib_plankton.pit.shift_week(x, entry.args[0]));} case "shift_day": {return (x => lib_plankton.pit.shift_day(x, entry.args[0]));} } } ) .concat( [ lib_plankton.pit.to_datetime, x => x.date, ] ) ) ), "time": datetime.time, }; } else { return { "timezone_shift": datetime.timezone_shift, "date": datetime.date_absolute, "time": datetime.time, }; } } /** */ export async function init( data : type_data ) : Promise { let track : { user : Record< int, _zeitbild.type_user_id >; calendar : Record< int, _zeitbild.type_user_id >; } = { "user": {}, "calendar": {}, }; for await (const user_raw of data.users) { const user_object : _zeitbild.type_user_object = { "name": user_raw.name, "email_address": user_raw.email_address, "dav_token": user_raw.dav_token, }; const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.add( user_object ); await _zeitbild.service.auth_internal.set( user_raw.name, user_raw.password ); track.user[user_raw.id] = user_id; } for await (const calendar_raw of data.calendars) { let resource_object : _zeitbild.type_resource_object; let resource_id : _zeitbild.type_resource_id; switch (calendar_raw.resource.kind) { case "local": { resource_object = { "kind": "local", "data": { "event_ids": [], } }; resource_id = await _zeitbild.service.resource.add( resource_object ); /*const event_ids : Array<_zeitbild.type_local_resource_event_id> = */await Promise.all( calendar_raw.resource.data.events .map( (event_raw) => { const event : _zeitbild.type_event_object = { "name": event_raw.name, "begin": decode_datetime(event_raw.begin), "end": ( (event_raw.end === null) ? null : decode_datetime(event_raw.end) ), "location": event_raw.location, "link": event_raw.link, "description": event_raw.description, }; return _zeitbild.service.resource.event_add(resource_id, event); } ) ); break; } case "ics_feed": { resource_object = { "kind": "ics_feed", "data": { "url": calendar_raw.resource.data.url, "from_fucked_up_wordpress": (calendar_raw.resource.data.from_fucked_up_wordpress ?? false), } }; resource_id = await _zeitbild.service.resource.add( resource_object ); break; } } const calendar_object : _zeitbild.type_calendar_object = { "name": calendar_raw.name, "access": { "public": (calendar_raw.access.public ?? false), "default_level": _zeitbild.value_object.access_level.from_string(calendar_raw.access.default_level), "attributed": lib_plankton.map.hashmap.implementation_map( lib_plankton.map.hashmap.make( x => x.toFixed(0), { "pairs": ( calendar_raw.access.attributed .map( (entry) => ({ "key": track.user[entry.user_id], "value": _zeitbild.value_object.access_level.from_string(entry.level), }) ) ), } ) ), }, "resource_id": resource_id, }; const calendar_id : _zeitbild.type_calendar_id = await _zeitbild.service.calendar.add( calendar_object ); track.calendar[calendar_raw.id] = calendar_id; } return Promise.resolve(undefined); } }