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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2025-04-27 22:30:22 +02:00
|
|
|
namespace _munin.sources.ical_feed
|
2025-04-25 00:48:05 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
export type type_parameters = {
|
2025-04-27 22:30:22 +02:00
|
|
|
url : string;
|
2025-04-25 00:48:05 +02:00
|
|
|
filtration : {
|
2025-05-18 07:42:04 +02:00
|
|
|
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
|
|
|
{
|
2025-04-27 22:30:22 +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 = {
|
2025-04-27 22:30:22 +02:00
|
|
|
"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,
|
2025-04-28 21:51:03 +02:00
|
|
|
"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 => (
|
2025-05-18 07:42:04 +02:00
|
|
|
// category whitelist
|
2025-04-25 12:50:13 +02:00
|
|
|
(
|
2025-05-18 07:42:04 +02:00
|
|
|
(parameters.filtration.category_whitelist === null)
|
|
|
|
||
|
|
|
|
vevent.categories.some(
|
2025-04-25 12:50:13 +02:00
|
|
|
category => (
|
2025-05-18 07:42:04 +02:00
|
|
|
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
|
|
|
&&
|
2025-05-18 07:42:04 +02:00
|
|
|
// category blacklist
|
2025-04-25 12:50:13 +02:00
|
|
|
(
|
2025-05-18 07:42:04 +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 => (
|
2025-05-18 07:42:04 +02:00
|
|
|
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-06-12 07:25:15 +02:00
|
|
|
"description": (vevent.description ?? null),
|
2025-04-25 12:50:13 +02:00
|
|
|
"location": (vevent.location ?? null),
|
2025-05-06 22:12:02 +02:00
|
|
|
"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),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|