munin/source/sources/ical_feed.ts

152 lines
3.8 KiB
TypeScript
Raw Normal View History

2025-05-06 21:26:30 +02:00
/*
This file is part of »munin«.
Copyright 2025 'Fenris Wolf' <fenris@folksprak.org>
»munin« 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.
»munin« 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 »munin«. If not, see <http://www.gnu.org/licenses/>.
*/
namespace _munin.sources.ical_feed
2025-04-25 00:48:05 +02:00
{
/**
*/
export type type_parameters = {
url : string;
2025-04-25 00:48:05 +02:00
filtration : {
category_whitelist : (null | Array<string>);
category_blacklist : (null | Array<string>);
title_whitelist : (null | Array<string>);
title_blacklist : (null | Array<string>);
2025-04-25 00:48:05 +02:00
};
};
/**
*/
async function fetch(
parameters : type_parameters
2025-04-25 12:50:13 +02:00
) : Promise<Array<_munin.type_event>>
2025-04-25 00:48:05 +02:00
{
const url : lib_plankton.url.type_url = lib_plankton.url.decode(parameters.url);
2025-04-25 00:48:05 +02:00
const http_request : lib_plankton.http.type_request = {
"scheme": (url.scheme as ("http" | "https")),
"host": url.host,
"path": url.path,
2025-04-25 00:48:05 +02:00
"version": "HTTP/2",
"method": lib_plankton.http.enum_method.get,
"query": ("?" + url.query),
2025-04-25 00:48:05 +02:00
"headers": {},
"body": null,
};
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(http_request);
const ics : string = http_response.body.toString();
const vcalendar : lib_plankton.ical.type_vcalendar = lib_plankton.ical.ics_decode(ics);
2025-04-25 12:50:13 +02:00
const events : Array<_munin.type_event> = (
2025-04-25 00:48:05 +02:00
vcalendar.vevents
.filter(
vevent => (
// category whitelist
2025-04-25 12:50:13 +02:00
(
(parameters.filtration.category_whitelist === null)
||
vevent.categories.some(
2025-04-25 12:50:13 +02:00
category => (
parameters.filtration.category_whitelist
.map(category_ => category_.toLowerCase())
.includes(category.toLowerCase())
2025-04-25 12:50:13 +02:00
)
)
)
2025-04-25 00:48:05 +02:00
&&
// category blacklist
2025-04-25 12:50:13 +02:00
(
(parameters.filtration.category_blacklist === null)
||
vevent.categories.every (
category => ! (
parameters.filtration.category_blacklist
.map(category_ => category_.toLowerCase())
.includes(category.toLowerCase())
)
)
)
&&
// title whitelist
(
(parameters.filtration.title_whitelist === null)
||
parameters.filtration.title_whitelist.some(
2025-04-25 12:50:13 +02:00
title => (
vevent.summary.toLowerCase()
.includes(title.toLowerCase())
)
)
)
&&
// title blacklist
(
(parameters.filtration.title_blacklist === null)
||
parameters.filtration.title_blacklist.every(
title => ! (
vevent.summary.toLowerCase()
.includes(title.toLowerCase())
2025-04-25 12:50:13 +02:00
)
)
)
2025-04-25 00:48:05 +02:00
)
)
.map(
vevent => {
const begin : lib_plankton.pit.type_datetime = {
2025-05-13 19:19:51 +02:00
"timezone_shift": 0,
2025-04-25 00:48:05 +02:00
"date": vevent.dtstart.value.date,
"time": vevent.dtstart.value.time,
};
const end : lib_plankton.pit.type_datetime = {
2025-05-13 19:19:51 +02:00
"timezone_shift": 0,
2025-04-25 00:48:05 +02:00
"date": vevent.dtend.value.date,
"time": vevent.dtend.value.time,
};
2025-04-25 12:50:13 +02:00
const event : _munin.type_event = {
2025-04-25 00:48:05 +02:00
"title": vevent.summary,
"begin": begin,
"end": end,
2025-04-25 12:50:13 +02:00
"location": (vevent.location ?? null),
"tags": vevent.categories,
2025-04-25 00:48:05 +02:00
};
return event;
}
)
);
return events;
}
/**
*/
export function implementation_source(
parameters : type_parameters
2025-04-25 12:50:13 +02:00
) : _munin.type_source
2025-04-25 00:48:05 +02:00
{
return {
"fetch": () => fetch(parameters),
};
}
}