backend/source/sample.ts

337 lines
6.8 KiB
TypeScript

/*
This file is part of »zeitbild«.
Copyright 2025 'kcf' <fenris@folksprak.org>
»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 <http://www.gnu.org/licenses/>.
*/
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<void>
{
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<void>(undefined);
}
}