diff --git a/misc/data-example.json b/misc/data-example.json
index e564273..79a3f1e 100644
--- a/misc/data-example.json
+++ b/misc/data-example.json
@@ -27,6 +27,7 @@
"id": 1,
"name": "LV Lampukistan",
"access": {
+ "public": true,
"default_level": "view",
"attributed": [
{
@@ -47,12 +48,20 @@
"name": "Aufstand: Mieten",
"begin": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 14},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [-1]},
+ {"action": "shift_day", "args": [6]}
+ ],
"time": {"hour": 12, "minute": 0, "second": 0}
},
"end": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 14},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [-1]},
+ {"action": "shift_day", "args": [6]}
+ ],
"time": {"hour": 15, "minute": 0, "second": 0}
},
"location": "Porada Ninfu, Haupt-Markt",
@@ -62,12 +71,20 @@
"name": "Aufstand: Waffen",
"begin": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 21},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [0]},
+ {"action": "shift_day", "args": [6]}
+ ],
"time": {"hour": 12, "minute": 0, "second": 0}
},
"end": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 21},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [0]},
+ {"action": "shift_day", "args": [6]}
+ ],
"time": {"hour": 15, "minute": 0, "second": 0}
},
"location": "Tandreell, Stoiber-Platz",
@@ -77,12 +94,20 @@
"name": "Aufstand: Essen",
"begin": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 10, "day": 28},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [1]},
+ {"action": "shift_day", "args": [6]}
+ ],
"time": {"hour": 12, "minute": 0, "second": 0}
},
"end": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 10, "day": 28},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [1]},
+ {"action": "shift_day", "args": [6]}
+ ],
"time": {"hour": 15, "minute": 0, "second": 0}
},
"location": "Kawanda, Nord-Bahnhof",
@@ -96,6 +121,7 @@
"id": 2,
"name": "KV Zepettel-Region",
"access": {
+ "public": false,
"default_level": "view",
"attributed": [
{
@@ -116,12 +142,20 @@
"name": "Feier: Bier",
"begin": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 18},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [0]},
+ {"action": "shift_day", "args": [3]}
+ ],
"time": {"hour": 18, "minute": 0, "second": 0}
},
"end": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 18},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [0]},
+ {"action": "shift_day", "args": [3]}
+ ],
"time": {"hour": 23, "minute": 0, "second": 0}
},
"location": "Rudschadinedschad, Schlamm-Park",
@@ -131,12 +165,20 @@
"name": "Feier: Schnapps",
"begin": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 10, "day": 1},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [2]},
+ {"action": "shift_day", "args": [2]}
+ ],
"time": {"hour": 18, "minute": 0, "second": 0}
},
"end": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 10, "day": 1},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [2]},
+ {"action": "shift_day", "args": [2]}
+ ],
"time": {"hour": 23, "minute": 0, "second": 0}
},
"location": "Kawanda, Ratten-Platz",
@@ -150,6 +192,7 @@
"id": 3,
"name": "OV Kawanda",
"access": {
+ "public": false,
"default_level": "view",
"attributed": [
{
@@ -166,12 +209,20 @@
"name": "Aufräumen: Flaschen",
"begin": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 24},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [1]},
+ {"action": "shift_day", "args": [2]}
+ ],
"time": {"hour": 15, "minute": 0, "second": 0}
},
"end": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 24},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [1]},
+ {"action": "shift_day", "args": [2]}
+ ],
"time": {"hour": 17, "minute": 0, "second": 0}
},
"location": "Kawanda, Penner-Allee",
@@ -185,6 +236,7 @@
"id": 4,
"name": "KV Zepettel-Region | intern",
"access": {
+ "public": false,
"default_level": "none",
"attributed": [
{
@@ -205,12 +257,20 @@
"name": "Infostand",
"begin": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 16},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [0]},
+ {"action": "shift_day", "args": [1]}
+ ],
"time": {"hour": 10, "minute": 0, "second": 0}
},
"end": {
"timezone_shift": 2,
- "date": {"year": 2025, "month": 9, "day": 16},
+ "date_relative": [
+ {"action": "trunc_week", "args": []},
+ {"action": "shift_week", "args": [0]},
+ {"action": "shift_day", "args": [1]}
+ ],
"time": {"hour": 14, "minute": 0, "second": 0}
},
"location": "Rudschadinedschad, Schabracken-Markt",
diff --git a/source/main.ts b/source/main.ts
index e4705a1..b588706 100644
--- a/source/main.ts
+++ b/source/main.ts
@@ -19,164 +19,6 @@ along with »zeitbild«. If not, see .
-/**
- */
-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<
- _zeitbild.type_event_object
- >
- };
- }
- |
- {
- kind : "ics_feed";
- data : {
- url : string;
- from_fucked_up_wordpress ?: boolean;
- };
- }
- );
- }
- >;
-};
-
-
-/**
- */
-async function data_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 : _zeitbild.type_event_object) => _zeitbild.service.resource.event_add(resource_id, event_raw)
- )
- );
- 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);
-}
-
-
/**
*/
async function main(
@@ -227,8 +69,8 @@ async function main(
"description": "conf-expose"
},
{
- "name": "fill",
- "description": "fill"
+ "name": "sample",
+ "description": "sample"
},
{
"name": "help",
@@ -417,9 +259,9 @@ async function main(
);
break;
}
- case "fill":
+ case "sample":
{
- await data_init(
+ await _zeitbild.sample.init(
lib_plankton.json.decode(
await lib_plankton.file.read(args.data_path)
)
diff --git a/source/sample.ts b/source/sample.ts
new file mode 100644
index 0000000..8002e8c
--- /dev/null
+++ b/source/sample.ts
@@ -0,0 +1,336 @@
+/*
+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);
+ }
+
+}
diff --git a/source/types.ts b/source/types.ts
index 023f787..d1f1b84 100644
--- a/source/types.ts
+++ b/source/types.ts
@@ -58,6 +58,9 @@ namespace _zeitbild
/**
*/
export type type_event_object = {
+ /**
+ * @todo rename to "title"
+ */
name : string;
begin : lib_plankton.pit.type_datetime;
end : (
diff --git a/tools/makefile b/tools/makefile
index ce88995..9866701 100644
--- a/tools/makefile
+++ b/tools/makefile
@@ -80,6 +80,7 @@ ${dir_temp}/zeitbild-unlinked.js: \
${dir_source}/api/actions/events.ts \
${dir_source}/api/actions/export_ics.ts \
${dir_source}/api/functions.ts \
+ ${dir_source}/sample.ts \
${dir_source}/main.ts
@ ${cmd_log} "compile …"
@ ${cmd_mkdir} $(dir $@)