579 lines
10 KiB
TypeScript
579 lines
10 KiB
TypeScript
/*
|
|
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/>.
|
|
*/
|
|
|
|
|
|
/**
|
|
* @todo versioning
|
|
*/
|
|
namespace _munin.conf
|
|
{
|
|
|
|
/**
|
|
*/
|
|
type type_conf_v1 = {
|
|
sources : Array<
|
|
(
|
|
{
|
|
kind : "kalender_digital",
|
|
data : {
|
|
path : string;
|
|
filtration : {
|
|
category_blacklist : Array<string>;
|
|
title_blacklist : Array<string>;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
>;
|
|
targets : Array<
|
|
(
|
|
{
|
|
kind : "telegram_bot",
|
|
data : {
|
|
bot_token : string;
|
|
chat_id : int;
|
|
/**
|
|
* in hours
|
|
*/
|
|
interval : Array<int>;
|
|
}
|
|
}
|
|
)
|
|
>;
|
|
frequency : float;
|
|
labels : {
|
|
head : string;
|
|
title : string;
|
|
time : string;
|
|
location : string;
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
*/
|
|
type type_conf_v2 = {
|
|
sources : Array<
|
|
(
|
|
{
|
|
kind : "ical_feed",
|
|
data : {
|
|
url : string;
|
|
filtration : {
|
|
category_blacklist : Array<string>;
|
|
title_blacklist : Array<string>;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
>;
|
|
targets : Array<
|
|
(
|
|
{
|
|
kind : "telegram_bot",
|
|
data : {
|
|
bot_token : string;
|
|
chat_id : int;
|
|
/**
|
|
* in hours
|
|
*/
|
|
reminders : Array<int>;
|
|
}
|
|
}
|
|
)
|
|
>;
|
|
settings : {
|
|
interval : float;
|
|
};
|
|
labels : {
|
|
head : string;
|
|
title : string;
|
|
time : string;
|
|
location : string;
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
*/
|
|
export type type_conf = type_conf_v2;
|
|
|
|
|
|
/**
|
|
*/
|
|
function convert_from_v1(
|
|
conf_v1 : type_conf_v1
|
|
) : type_conf_v2
|
|
{
|
|
return {
|
|
"sources": conf_v1.sources.map(
|
|
source => {
|
|
switch (source.kind) {
|
|
case "kalender_digital": {
|
|
return {
|
|
"kind": "ical_feed",
|
|
"data": {
|
|
"url": lib_plankton.url.encode(
|
|
{
|
|
"scheme": "https",
|
|
"host": "export.kalender.digital",
|
|
"username": null,
|
|
"password": null,
|
|
"port": null,
|
|
"path": ("/ics/" + source.data.path + ".ics"),
|
|
"query": "past_months=0&future_months=1",
|
|
"hash": null,
|
|
}
|
|
),
|
|
"filtration": source.data.filtration,
|
|
}
|
|
};
|
|
break;
|
|
}
|
|
default: {
|
|
// return source;
|
|
throw (new Error("unhandled source kind: " + source.kind));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
),
|
|
"targets": conf_v1.targets.map(
|
|
target => {
|
|
switch (target.kind) {
|
|
case "telegram_bot": {
|
|
return {
|
|
"kind": "telegram_bot",
|
|
"data": {
|
|
"bot_token": target.data.bot_token,
|
|
"chat_id": target.data.chat_id,
|
|
"reminders": target.data.interval,
|
|
},
|
|
};
|
|
break;
|
|
}
|
|
default: {
|
|
// return target;
|
|
throw (new Error("unhandled target kind: " + target.kind));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
),
|
|
"settings": {
|
|
"interval": conf_v1.frequency,
|
|
},
|
|
"labels": conf_v1.labels,
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema_source_kalender_digital(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
return {
|
|
"type": "object",
|
|
"properties": {
|
|
"kind": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
"enum": ["kalender_digital"]
|
|
},
|
|
"data": {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {
|
|
"nullable": false,
|
|
"type": "string"
|
|
},
|
|
"filtration": {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"category_blacklist": {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
},
|
|
"default": [],
|
|
},
|
|
"title_blacklist": {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
},
|
|
"default": [],
|
|
},
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
],
|
|
"default": {}
|
|
},
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"path",
|
|
]
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"kind",
|
|
"data",
|
|
]
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema_source_ical_feed(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
return {
|
|
"type": "object",
|
|
"properties": {
|
|
"kind": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
"enum": ["ical_feed"]
|
|
},
|
|
"data": {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"url": {
|
|
"nullable": false,
|
|
"type": "string"
|
|
},
|
|
"filtration": {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"category_blacklist": {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
},
|
|
"default": [],
|
|
},
|
|
"title_blacklist": {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
},
|
|
"default": [],
|
|
},
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
],
|
|
"default": {}
|
|
},
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"url",
|
|
]
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"kind",
|
|
"data",
|
|
]
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema_sources(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
switch (version) {
|
|
case "1": {
|
|
return {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"anyOf": [
|
|
schema_source_kalender_digital(version),
|
|
],
|
|
}
|
|
};
|
|
break;
|
|
}
|
|
default:
|
|
case "2": {
|
|
return {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"anyOf": [
|
|
schema_source_ical_feed(version),
|
|
],
|
|
}
|
|
};
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema_target_telegram_bot(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
return {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"kind": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
"enum": ["telegram_bot"]
|
|
},
|
|
"data": {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"bot_token": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
},
|
|
"chat_id": {
|
|
"nullable": false,
|
|
"type": "integer",
|
|
},
|
|
"reminders": {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"type": "integer"
|
|
},
|
|
"default": [24.0],
|
|
},
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"bot_token",
|
|
"chat_id",
|
|
]
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"kind",
|
|
"data",
|
|
]
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema_targets(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
return {
|
|
"nullable": false,
|
|
"type": "array",
|
|
"items": {
|
|
"nullable": false,
|
|
"anyOf": [
|
|
schema_target_telegram_bot(version),
|
|
],
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema_settings(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
return {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"interval": {
|
|
"nullable": false,
|
|
"type": "number",
|
|
"default": 1.0
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
],
|
|
"default": {
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema_labels(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
return {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"head": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
"default": "Termin-Erinnerung"
|
|
},
|
|
"title": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
"default": "was"
|
|
},
|
|
"time": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
"default": "wann"
|
|
},
|
|
"location": {
|
|
"nullable": false,
|
|
"type": "string",
|
|
"default": "wo"
|
|
},
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
],
|
|
"default": {}
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function schema(
|
|
version : string
|
|
) : lib_plankton.conf.type_schema
|
|
{
|
|
switch (version) {
|
|
case "1": {
|
|
return {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"sources": schema_sources(version),
|
|
"targets": schema_targets(version),
|
|
"frequency": {
|
|
"nullable": false,
|
|
"type": "number",
|
|
"default": 1.0,
|
|
},
|
|
"labels": schema_labels(version),
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"sources",
|
|
"targets",
|
|
],
|
|
};
|
|
break;
|
|
}
|
|
default:
|
|
case "2": {
|
|
return {
|
|
"nullable": false,
|
|
"type": "object",
|
|
"properties": {
|
|
"sources": schema_sources(version),
|
|
"targets": schema_targets(version),
|
|
"settings": schema_settings(version),
|
|
"labels": schema_labels(version),
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"sources",
|
|
"targets",
|
|
],
|
|
};
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export async function load(
|
|
path : string
|
|
) : Promise<type_conf>
|
|
{
|
|
const conf_raw : {version : string; content : any} = await lib_plankton.conf.load_versioned(
|
|
path,
|
|
schema,
|
|
{
|
|
"1": {"target": "2", "function": convert_from_v1},
|
|
"2": null,
|
|
}
|
|
);
|
|
|
|
switch (conf_raw.version) {
|
|
case "1": {
|
|
const conf_v2 : type_conf_v2 = convert_from_v1(conf_raw.content);
|
|
return conf_v2;
|
|
break;
|
|
}
|
|
case "2": {
|
|
const conf_v2 : type_conf_v2 = (conf_raw.content as type_conf_v2);
|
|
return conf_v2;
|
|
break;
|
|
}
|
|
default: {
|
|
throw (new Error("invalid version: " + conf_raw.version));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|