/* This file is part of »munin«. Copyright 2025 'Fenris Wolf' »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 . */ /** * @todo versioning */ namespace _munin.conf { /** */ type type_conf_v1 = { sources : Array< ( { kind : "kalender_digital", data : { path : string; filtration : { category_blacklist : Array; title_blacklist : Array; }; }; } ) >; targets : Array< ( { kind : "telegram_bot", data : { bot_token : string; chat_id : int; /** * in hours */ interval : Array; } } ) >; 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; title_blacklist : Array; }; }; } ) >; targets : Array< ( { kind : "telegram_bot", data : { bot_token : string; chat_id : int; /** * in hours */ interval : Array; } } ) >; settings : { poll_delay : 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, "settings": { "poll_delay": 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", }, "interval": { "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": { "poll_delay": { "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 { 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; } } } }