backend/source/services/calendar.ts
2024-09-21 10:56:00 +02:00

241 lines
4.8 KiB
TypeScript

namespace _zeitbild.service.calendar
{
/**
*/
export function add(
calendar_object : _zeitbild.type.calendar_object
) : Promise<_zeitbild.type.calendar_id>
{
return _zeitbild.repository.calendar.create(calendar_object);
}
/**
*/
export async function list(
search_term : (null | string)
) : Promise<
Array<
{
id : _zeitbild.type.calendar_id;
preview : {
name : string;
}
}
>
>
{
return (
_zeitbild.repository.calendar.list(search_term)
.then(
x => x.map(
(y : any) => ({
"id": y.key,
"preview": y.preview,
})
)
)
);
}
/**
*/
export function overview(
user_id : _zeitbild.type.user_id
) : Promise<
Array<
{
id : _zeitbild.type.calendar_id;
name : string;
access_level : _zeitbild.type.enum_access_level;
}
>
>
{
return _zeitbild.repository.calendar.overview(user_id);
}
/**
*/
export async function get(
calendar_id : _zeitbild.type.calendar_id
) : Promise<_zeitbild.type.calendar_object>
{
return _zeitbild.repository.calendar.read(calendar_id);
}
/**
*/
async function get_events(
calendar_id : _zeitbild.type.calendar_id,
from_pit : _zeitbild.helpers.type_pit,
to_pit : _zeitbild.helpers.type_pit
) : Promise<
Array<
_zeitbild.type.event_object
>
>
{
const calendar_object : _zeitbild.type.calendar_object = await _zeitbild.repository.calendar.read(calendar_id);
const resource_object : _zeitbild.type.resource_object = await _zeitbild.repository.resource.read(calendar_object.resource_id);
switch (resource_object.kind) {
case "local": {
return Promise.resolve(
resource_object.data.events
.filter(
(event : _zeitbild.type.event_object) => _zeitbild.helpers.pit_is_between(
_zeitbild.helpers.pit_from_datetime(event.begin),
from_pit,
to_pit
)
)
)
break;
}
case "caldav": {
// TODO readonly
const url : lib_plankton.url.type_url = lib_plankton.url.decode(
resource_object.data.url
);
const http_request : lib_plankton.http.type_request = {
"version": "HTTP/2",
"scheme": ((url.scheme === "https") ? "https" : "http"),
"host": url.host,
"path": (url.path ?? "/"),
"query": url.query,
"method": lib_plankton.http.enum_method.get,
"headers": {},
"body": null,
};
// TODO: cache?
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
http_request,
{
}
);
const vcalendar : lib_plankton.ical.type_vcalendar = lib_plankton.ical.ics_decode(
http_response.body.toString(),
{
}
);
return Promise.resolve(
vcalendar.vevents
.map(
(vevent : lib_plankton.ical.type_vevent) => (
(vevent.dtstart !== undefined)
?
{
"name": (
(vevent.summary !== undefined)
?
vevent.summary
:
"???"
),
"begin": _zeitbild.helpers.ical_dt_to_own_datetime(vevent.dtstart),
"end": (
(vevent.dtend !== undefined)
?
_zeitbild.helpers.ical_dt_to_own_datetime(vevent.dtend)
:
null
),
"location": (
(vevent.location !== undefined)
?
vevent.location
:
null
),
"description": (
(vevent.description !== undefined)
?
vevent.description
:
null
),
}
:
null
)
)
.filter(
(event) => (event !== null)
)
.filter(
(event) => _zeitbild.helpers.pit_is_between(
_zeitbild.helpers.pit_from_datetime(event.begin),
from_pit,
to_pit
)
)
);
break;
}
default: {
return Promise.reject(
new Error("invalid resource kind: " + resource_object["kind"])
);
break;
}
}
}
/**
*/
export async function gather_events(
calendar_ids : Array<_zeitbild.type.calendar_id>,
from_pit : _zeitbild.helpers.type_pit,
to_pit : _zeitbild.helpers.type_pit
) : Promise<
Array<
{
calendar_id : _zeitbild.type.calendar_id;
calendar_name : string;
event : _zeitbild.type.event_object;
}
>
>
{
return (
Promise.all(
calendar_ids
.map(
async (calendar_id) => {
const calendar_object : _zeitbild.type.calendar_object = await _zeitbild.repository.calendar.read(
calendar_id
);
const events : Array<_zeitbild.type.event_object> = await get_events(
calendar_id,
from_pit,
to_pit
);
return Promise.resolve(
events
.map(
(event) => ({
"calendar_id": calendar_id,
"calendar_name": calendar_object.name,
"event": event,
})
)
);
}
)
)
.then(
(sub_results) => sub_results.reduce(
(x, y) => x.concat(y),
[]
)
)
);
}
}