[task-340] soweit fertig
This commit is contained in:
parent
37f7a27e95
commit
21c2d9945c
218
data/reminder_check.testdata.json
Normal file
218
data/reminder_check.testdata.json
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "reminder_check.dueness-1",
|
||||||
|
"input": {
|
||||||
|
"reminder": {
|
||||||
|
"frequency": "daily",
|
||||||
|
"offset": 16,
|
||||||
|
"from": 24,
|
||||||
|
"to": 48
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
],
|
||||||
|
"datetime": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 27
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 15,
|
||||||
|
"minute": 30,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interval": 1
|
||||||
|
},
|
||||||
|
"output": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reminder_check.dueness-2",
|
||||||
|
"input": {
|
||||||
|
"reminder": {
|
||||||
|
"frequency": "daily",
|
||||||
|
"offset": 16,
|
||||||
|
"from": 24,
|
||||||
|
"to": 48
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
],
|
||||||
|
"datetime": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 27
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 16,
|
||||||
|
"minute": 30,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interval": 1
|
||||||
|
},
|
||||||
|
"output": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reminder_check.dueness-3",
|
||||||
|
"input": {
|
||||||
|
"reminder": {
|
||||||
|
"frequency": "daily",
|
||||||
|
"offset": 16,
|
||||||
|
"from": 24,
|
||||||
|
"to": 48
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
],
|
||||||
|
"datetime": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 27
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 17,
|
||||||
|
"minute": 30,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interval": 1
|
||||||
|
},
|
||||||
|
"output": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reminder_check.events-1",
|
||||||
|
"input": {
|
||||||
|
"reminder": {
|
||||||
|
"frequency": "daily",
|
||||||
|
"offset": 16,
|
||||||
|
"from": 24,
|
||||||
|
"to": 48
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"title": "e1",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 27
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 12,
|
||||||
|
"minute": 0,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"datetime": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 27
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 16,
|
||||||
|
"minute": 30,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interval": 1
|
||||||
|
},
|
||||||
|
"output": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reminder_check.events-2",
|
||||||
|
"input": {
|
||||||
|
"reminder": {
|
||||||
|
"frequency": "daily",
|
||||||
|
"offset": 16,
|
||||||
|
"from": 24,
|
||||||
|
"to": 48
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"title": "e1",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 28
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 12,
|
||||||
|
"minute": 0,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"datetime": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 27
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 16,
|
||||||
|
"minute": 30,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interval": 1
|
||||||
|
},
|
||||||
|
"output": ["e1"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reminder_check.events-3",
|
||||||
|
"input": {
|
||||||
|
"reminder": {
|
||||||
|
"frequency": "daily",
|
||||||
|
"offset": 16,
|
||||||
|
"from": 24,
|
||||||
|
"to": 48
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"title": "e1",
|
||||||
|
"begin": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 29
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 12,
|
||||||
|
"minute": 0,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"datetime": {
|
||||||
|
"timezone_shift": 0,
|
||||||
|
"date": {
|
||||||
|
"year": 2025,
|
||||||
|
"month": 6,
|
||||||
|
"day": 27
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"hour": 16,
|
||||||
|
"minute": 30,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interval": 1
|
||||||
|
},
|
||||||
|
"output": []
|
||||||
|
}
|
||||||
|
]
|
|
@ -1,122 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"reminder": {
|
|
||||||
"frequency": "daily",
|
|
||||||
"offset": 0,
|
|
||||||
"from": 24,
|
|
||||||
"to": 48
|
|
||||||
},
|
|
||||||
"event": {
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 25
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 12,
|
|
||||||
"minute": 0,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"datetime": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 23
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 10,
|
|
||||||
"minute": 0,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
"output": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"reminder": {
|
|
||||||
"frequency": "daily",
|
|
||||||
"offset": 0,
|
|
||||||
"from": 24,
|
|
||||||
"to": 48
|
|
||||||
},
|
|
||||||
"event": {
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 25
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 12,
|
|
||||||
"minute": 0,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"datetime": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 24
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 10,
|
|
||||||
"minute": 0,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
"output": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"reminder": {
|
|
||||||
"frequency": "daily",
|
|
||||||
"offset": 0,
|
|
||||||
"from": 24,
|
|
||||||
"to": 48
|
|
||||||
},
|
|
||||||
"event": {
|
|
||||||
"begin": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 25
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 12,
|
|
||||||
"minute": 0,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"datetime": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 25
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 10,
|
|
||||||
"minute": 0,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
"output": false
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,77 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"reminder": {
|
|
||||||
"frequency": "daily",
|
|
||||||
"offset": 16,
|
|
||||||
"from": 24,
|
|
||||||
"to": 48
|
|
||||||
},
|
|
||||||
"datetime": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 27
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 15,
|
|
||||||
"minute": 30,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
"output": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"reminder": {
|
|
||||||
"frequency": "daily",
|
|
||||||
"offset": 16,
|
|
||||||
"from": 24,
|
|
||||||
"to": 48
|
|
||||||
},
|
|
||||||
"datetime": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 27
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 16,
|
|
||||||
"minute": 30,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
"output": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"reminder": {
|
|
||||||
"frequency": "daily",
|
|
||||||
"offset": 16,
|
|
||||||
"from": 24,
|
|
||||||
"to": 48
|
|
||||||
},
|
|
||||||
"datetime": {
|
|
||||||
"timezone_shift": 0,
|
|
||||||
"date": {
|
|
||||||
"year": 2025,
|
|
||||||
"month": 6,
|
|
||||||
"day": 27
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"hour": 17,
|
|
||||||
"minute": 30,
|
|
||||||
"second": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interval": 1
|
|
||||||
},
|
|
||||||
"output": false
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -312,6 +312,7 @@ namespace _munin.conf
|
||||||
title : string;
|
title : string;
|
||||||
time : string;
|
time : string;
|
||||||
location : string;
|
location : string;
|
||||||
|
events : string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -532,7 +533,7 @@ namespace _munin.conf
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
"settings": conf_v4.settings,
|
"settings": conf_v4.settings,
|
||||||
"labels": conf_v4.labels,
|
"labels": Object.assign({"events": "Termine"}, conf_v4.labels),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1044,6 +1045,11 @@ namespace _munin.conf
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "wo"
|
"default": "wo"
|
||||||
},
|
},
|
||||||
|
"events": {
|
||||||
|
"nullable": false,
|
||||||
|
"type": "string",
|
||||||
|
"default": "Termine"
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"required": [
|
"required": [
|
||||||
|
|
160
source/logic.ts
160
source/logic.ts
|
@ -67,102 +67,65 @@ namespace _munin.logic
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function reminder_due(
|
export function reminder_check(
|
||||||
reminder : type_reminder,
|
reminder : type_reminder,
|
||||||
|
events_all : Array<_munin.type_event>,
|
||||||
{
|
{
|
||||||
"pit": pit = lib_plankton.pit.now(),
|
"pit": pit = lib_plankton.pit.now(),
|
||||||
"interval": interval = 1,
|
"interval": interval = 1,
|
||||||
} : {
|
}
|
||||||
|
: {
|
||||||
pit ?: lib_plankton.pit.type_pit;
|
pit ?: lib_plankton.pit.type_pit;
|
||||||
interval ?: int;
|
interval ?: int;
|
||||||
} = {
|
|
||||||
}
|
}
|
||||||
) : boolean
|
= {
|
||||||
|
}
|
||||||
|
) : (null | Array<_munin.type_event>)
|
||||||
{
|
{
|
||||||
const anchor : lib_plankton.pit.type_pit = frequency_anchor(
|
const anchor : lib_plankton.pit.type_pit = frequency_anchor(
|
||||||
reminder.frequency,
|
reminder.frequency,
|
||||||
{"pit": pit}
|
{"pit": pit}
|
||||||
);
|
);
|
||||||
const window_from : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
const dueness_window_from : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
||||||
anchor,
|
anchor,
|
||||||
(reminder.offset + 0)
|
(reminder.offset + 0)
|
||||||
);
|
);
|
||||||
const window_to : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
const dueness_window_to : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
||||||
anchor,
|
anchor,
|
||||||
(reminder.offset + interval)
|
(reminder.offset + interval)
|
||||||
);
|
);
|
||||||
const result : boolean = lib_plankton.pit.is_between(
|
const due : boolean = lib_plankton.pit.is_between(
|
||||||
pit,
|
pit,
|
||||||
window_from,
|
dueness_window_from,
|
||||||
window_to
|
dueness_window_to
|
||||||
);
|
);
|
||||||
lib_plankton.log._info(
|
if (! due)
|
||||||
"munin.logic.reminder_due",
|
|
||||||
{
|
{
|
||||||
"details": {
|
return null;
|
||||||
"reminder": reminder,
|
|
||||||
"datetime": lib_plankton.pit.to_datetime(pit),
|
|
||||||
"interval": interval,
|
|
||||||
"anchor": lib_plankton.pit.to_datetime(anchor),
|
|
||||||
"window_from": lib_plankton.pit.to_datetime(window_from),
|
|
||||||
"window_to": lib_plankton.pit.to_datetime(window_to),
|
|
||||||
"result": result,
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
export function reminder_covers_event(
|
|
||||||
reminder : type_reminder,
|
|
||||||
event : _munin.type_event,
|
|
||||||
{
|
{
|
||||||
"pit": pit = lib_plankton.pit.now(),
|
const events_window_from : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
||||||
} : {
|
|
||||||
pit ?: lib_plankton.pit.type_pit;
|
|
||||||
} = {
|
|
||||||
}
|
|
||||||
) : boolean
|
|
||||||
{
|
|
||||||
const anchor : lib_plankton.pit.type_pit = frequency_anchor(
|
|
||||||
reminder.frequency,
|
|
||||||
{"pit": pit}
|
|
||||||
);
|
|
||||||
const window_from : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
|
||||||
anchor,
|
anchor,
|
||||||
reminder.from
|
reminder.from
|
||||||
);
|
);
|
||||||
const window_to : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
const events_window_to : lib_plankton.pit.type_pit = lib_plankton.pit.shift_hour(
|
||||||
anchor,
|
anchor,
|
||||||
reminder.to
|
reminder.to
|
||||||
);
|
);
|
||||||
const event_begin : lib_plankton.pit.type_pit = lib_plankton.pit.from_datetime(
|
const events : Array<_munin.type_event> = (
|
||||||
event.begin
|
events_all
|
||||||
|
.filter(
|
||||||
|
(event) => lib_plankton.pit.is_between(
|
||||||
|
lib_plankton.pit.from_datetime(event.begin),
|
||||||
|
events_window_from,
|
||||||
|
events_window_to
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
const result : boolean = lib_plankton.pit.is_between(
|
return events;
|
||||||
event_begin,
|
|
||||||
window_from,
|
|
||||||
window_to
|
|
||||||
);
|
|
||||||
lib_plankton.log._info(
|
|
||||||
"munin.logic.reminder_covers_event",
|
|
||||||
{
|
|
||||||
"details": {
|
|
||||||
"reminder": reminder,
|
|
||||||
"event": event,
|
|
||||||
"datetime": lib_plankton.pit.to_datetime(pit),
|
|
||||||
"anchor": lib_plankton.pit.to_datetime(anchor),
|
|
||||||
"window_from": lib_plankton.pit.to_datetime(window_from),
|
|
||||||
"window_to": lib_plankton.pit.to_datetime(window_to),
|
|
||||||
"result": result,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,67 +136,77 @@ namespace _munin.logic
|
||||||
targets : Array<_munin.type_target>,
|
targets : Array<_munin.type_target>,
|
||||||
{
|
{
|
||||||
"dry_run": dry_run = false,
|
"dry_run": dry_run = false,
|
||||||
} : {
|
}
|
||||||
|
: {
|
||||||
dry_run ?: boolean;
|
dry_run ?: boolean;
|
||||||
} = {
|
}
|
||||||
|
= {
|
||||||
}
|
}
|
||||||
) : Promise<void>
|
) : Promise<void>
|
||||||
{
|
{
|
||||||
const now : lib_plankton.pit.type_pit = lib_plankton.pit.now();
|
const now : lib_plankton.pit.type_pit = lib_plankton.pit.now();
|
||||||
const events : Array<_munin.type_event> = (
|
const events_all : Array<_munin.type_event> = (
|
||||||
(await Promise.all(sources.map(source => source.fetch())))
|
(await Promise.all(sources.map(source => source.fetch())))
|
||||||
.reduce((x, y) => x.concat(y), [])
|
.reduce((x, y) => x.concat(y), [])
|
||||||
);
|
);
|
||||||
for (const target of targets) {
|
for (const target of targets)
|
||||||
for (const reminder of target.reminders) {
|
{
|
||||||
const due : boolean = reminder_due(
|
for (const reminder of target.reminders)
|
||||||
|
{
|
||||||
|
const events : Array<_munin.type_event> = reminder_check(
|
||||||
reminder,
|
reminder,
|
||||||
|
events_all,
|
||||||
{
|
{
|
||||||
"pit": now,
|
"pit": now,
|
||||||
"interval": conf.settings.interval,
|
"interval": conf.settings.interval,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (! due)
|
if (events === null)
|
||||||
{
|
{
|
||||||
// do nothing
|
lib_plankton.log._info(
|
||||||
|
"munin.run_iteration.reminder_not_due",
|
||||||
|
{
|
||||||
|
"details": {
|
||||||
|
"reminder": reminder,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (events.length <= 0)
|
||||||
|
{
|
||||||
|
lib_plankton.log._info(
|
||||||
|
"munin.run_iteration.no_matching_events",
|
||||||
|
{
|
||||||
|
"details": {
|
||||||
|
"reminder": reminder,
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
const events_matching : Array<_munin.type_event> = events.filter(
|
|
||||||
event => reminder_covers_event(
|
|
||||||
reminder,
|
|
||||||
event,
|
|
||||||
{
|
|
||||||
"pit": now,
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
);
|
);
|
||||||
if (events_matching.length <= 0) {
|
|
||||||
// do nothing
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lib_plankton.log._info(
|
lib_plankton.log._info(
|
||||||
"munin.remind.do",
|
"munin.run_iteration.remind",
|
||||||
{
|
{
|
||||||
"details": {
|
"details": {
|
||||||
|
"reminder": reminder,
|
||||||
"events": events,
|
"events": events,
|
||||||
"target": target.show(),
|
"target": target.show(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (dry_run) {
|
if (dry_run)
|
||||||
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
/**
|
|
||||||
* @todo bundle?
|
|
||||||
*/
|
|
||||||
for (const event of events_matching)
|
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
await target.send(conf.labels, event);
|
{
|
||||||
|
await target.send(conf.labels, events);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error)
|
||||||
|
{
|
||||||
lib_plankton.log.error(
|
lib_plankton.log.error(
|
||||||
"munin.remind.error",
|
"munin.remind.error",
|
||||||
{
|
{
|
||||||
|
@ -249,7 +222,6 @@ namespace _munin.logic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,22 +37,13 @@ namespace _munin.targets.email
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
async function send(
|
function summarize_event(
|
||||||
parameters : type_parameters,
|
parameters : type_parameters,
|
||||||
labels : _munin.type_labels,
|
labels : _munin.type_labels,
|
||||||
event : _munin.type_event
|
event : _munin.type_event
|
||||||
) : Promise<void>
|
) : string
|
||||||
{
|
{
|
||||||
await lib_plankton.email.send(
|
return lib_plankton.string.coin(
|
||||||
{
|
|
||||||
"host": parameters.smtp_host,
|
|
||||||
"port": parameters.smtp_port,
|
|
||||||
"username": parameters.smtp_username,
|
|
||||||
"password": parameters.smtp_password,
|
|
||||||
},
|
|
||||||
parameters.sender,
|
|
||||||
parameters.receivers,
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"[{{head}}] {{date}} : {{macro_tags}}{{title}}",
|
"[{{head}}] {{date}} : {{macro_tags}}{{title}}",
|
||||||
{
|
{
|
||||||
"head": labels.head,
|
"head": labels.head,
|
||||||
|
@ -68,8 +59,19 @@ namespace _munin.targets.email
|
||||||
),
|
),
|
||||||
"title": event.title,
|
"title": event.title,
|
||||||
}
|
}
|
||||||
),
|
);
|
||||||
lib_plankton.string.coin(
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
function render_event(
|
||||||
|
parameters : type_parameters,
|
||||||
|
labels : _munin.type_labels,
|
||||||
|
event : _munin.type_event
|
||||||
|
) : string
|
||||||
|
{
|
||||||
|
return lib_plankton.string.coin(
|
||||||
"{{title_label}} | {{macro_tags}}{{title_value}}\n{{time_label}} | {{time_value}}{{macro_location}}{{macro_description}}",
|
"{{title_label}} | {{macro_tags}}{{title_value}}\n{{time_label}} | {{time_value}}{{macro_location}}{{macro_description}}",
|
||||||
{
|
{
|
||||||
"title_label": labels.title.toUpperCase(),
|
"title_label": labels.title.toUpperCase(),
|
||||||
|
@ -115,6 +117,46 @@ namespace _munin.targets.email
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async function send(
|
||||||
|
parameters : type_parameters,
|
||||||
|
labels : _munin.type_labels,
|
||||||
|
events : Array<_munin.type_event>
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
await lib_plankton.email.send(
|
||||||
|
{
|
||||||
|
"host": parameters.smtp_host,
|
||||||
|
"port": parameters.smtp_port,
|
||||||
|
"username": parameters.smtp_username,
|
||||||
|
"password": parameters.smtp_password,
|
||||||
|
},
|
||||||
|
parameters.sender,
|
||||||
|
parameters.receivers,
|
||||||
|
(
|
||||||
|
(events.length === 1)
|
||||||
|
?
|
||||||
|
summarize_event(parameters, labels, events[0])
|
||||||
|
:
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"[{{head}}] {{count}} {{events}}",
|
||||||
|
{
|
||||||
|
"head": labels.head,
|
||||||
|
"count": events.length.toFixed(0),
|
||||||
|
"events": labels.events,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
(
|
||||||
|
events
|
||||||
|
.map(event => render_event(parameters, labels, event))
|
||||||
|
.join("\n\n---\n\n")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -134,7 +176,7 @@ namespace _munin.targets.email
|
||||||
"receivers": parameters.receivers.join(","),
|
"receivers": parameters.receivers.join(","),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
"send": (labels, event) => send(parameters, labels, event),
|
"send": (labels, events) => send(parameters, labels, events),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,19 +33,15 @@ namespace _munin.targets.telegram_bot
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
async function send(
|
function render_event(
|
||||||
parameters : type_parameters,
|
parameters : type_parameters,
|
||||||
labels : _munin.type_labels,
|
labels : _munin.type_labels,
|
||||||
event : _munin.type_event
|
event : _munin.type_event
|
||||||
) : Promise<void>
|
) : string
|
||||||
{
|
{
|
||||||
await lib_plankton.telegram.bot_call_send_message(
|
return lib_plankton.string.coin(
|
||||||
parameters.bot_token,
|
"{{title_label}} | {{macro_tags}}{{title_value}}\n{{time_label}} | {{time_value}}{{macro_location}}{{macro_description}}",
|
||||||
parameters.chat_id,
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"*{{head}}*\n\n\{{title_label}} | {{macro_tags}}{{title_value}}\n{{time_label}} | {{time_value}}{{macro_location}}{{macro_description}}",
|
|
||||||
{
|
{
|
||||||
"head": labels.head,
|
|
||||||
"macro_tags": (
|
"macro_tags": (
|
||||||
(parameters.hide_tags || (event.tags === null))
|
(parameters.hide_tags || (event.tags === null))
|
||||||
?
|
?
|
||||||
|
@ -89,6 +85,44 @@ namespace _munin.targets.telegram_bot
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async function send(
|
||||||
|
parameters : type_parameters,
|
||||||
|
labels : _munin.type_labels,
|
||||||
|
events : Array<_munin.type_event>
|
||||||
|
) : Promise<void>
|
||||||
|
{
|
||||||
|
await lib_plankton.telegram.bot_call_send_message(
|
||||||
|
parameters.bot_token,
|
||||||
|
parameters.chat_id,
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
"*{{head_core}}{{head_extra}}*\n\n{{events}}",
|
||||||
|
{
|
||||||
|
"head_core": labels.head,
|
||||||
|
"head_extra": (
|
||||||
|
(events.length <= 1)
|
||||||
|
?
|
||||||
|
""
|
||||||
|
:
|
||||||
|
lib_plankton.string.coin(
|
||||||
|
" ({{count}} {{events}})",
|
||||||
|
{
|
||||||
|
"count": events.length.toFixed(0),
|
||||||
|
"events": labels.events,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"events": (
|
||||||
|
events
|
||||||
|
.map(event => render_event(parameters, labels, event))
|
||||||
|
.join("\n\n---\n\n")
|
||||||
|
),
|
||||||
|
}
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
"parse_mode": "Markdown",
|
"parse_mode": "Markdown",
|
||||||
|
@ -111,7 +145,7 @@ namespace _munin.targets.telegram_bot
|
||||||
"chat_id": parameters.chat_id.toFixed(0),
|
"chat_id": parameters.chat_id.toFixed(0),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
"send": (labels, event) => send(parameters, labels, event),
|
"send": (labels, events) => send(parameters, labels, events),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
127
source/test.ts
127
source/test.ts
|
@ -22,8 +22,26 @@ namespace _munin.test
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @todo outsource?
|
||||||
*/
|
*/
|
||||||
async function reminder_due(
|
function lists_equal<type_element>(
|
||||||
|
list1 : Array<type_element>,
|
||||||
|
list2 : Array<type_element>
|
||||||
|
) : boolean
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(list1.length === list2.length)
|
||||||
|
&&
|
||||||
|
list1.every(
|
||||||
|
(element, index) => (element === list2[index])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async function reminder_check(
|
||||||
) : Promise<void>
|
) : Promise<void>
|
||||||
{
|
{
|
||||||
type type_input = {
|
type type_input = {
|
||||||
|
@ -33,32 +51,49 @@ namespace _munin.test
|
||||||
from : int;
|
from : int;
|
||||||
to : int;
|
to : int;
|
||||||
};
|
};
|
||||||
|
events : Array<
|
||||||
|
{
|
||||||
|
title : string;
|
||||||
|
begin : lib_plankton.pit.type_datetime;
|
||||||
|
}
|
||||||
|
>;
|
||||||
datetime : lib_plankton.pit.type_datetime;
|
datetime : lib_plankton.pit.type_datetime;
|
||||||
interval : int;
|
interval : int;
|
||||||
};
|
};
|
||||||
type type_output = boolean;
|
type type_output = (null | Array<string>);
|
||||||
const testcases : Array<
|
const testcases : Array<
|
||||||
_munin.helpers.test.type_testcase<
|
_munin.helpers.test.type_testcase<
|
||||||
type_input,
|
type_input,
|
||||||
type_output
|
type_output
|
||||||
>
|
>
|
||||||
> = await _munin.helpers.test.get_data<type_input, type_output>(
|
> = await _munin.helpers.test.get_data<type_input, type_output>(
|
||||||
"data/reminder_due.testdata.json",
|
"data/reminder_check.testdata.json",
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const testcase of testcases)
|
for (const testcase of testcases)
|
||||||
{
|
{
|
||||||
_munin.helpers.test.start(testcase.name);
|
_munin.helpers.test.start(testcase.name);
|
||||||
|
|
||||||
// execution
|
// execution
|
||||||
const result : boolean = _munin.logic.reminder_due(
|
const result : (null | Array<_munin.type_event>) = _munin.logic.reminder_check(
|
||||||
{
|
{
|
||||||
"frequency": _munin.logic.frequency_decode(testcase.input.reminder.frequency),
|
"frequency": _munin.logic.frequency_decode(testcase.input.reminder.frequency),
|
||||||
"offset": testcase.input.reminder.offset,
|
"offset": testcase.input.reminder.offset,
|
||||||
"from": testcase.input.reminder.from,
|
"from": testcase.input.reminder.from,
|
||||||
"to": testcase.input.reminder.to,
|
"to": testcase.input.reminder.to,
|
||||||
},
|
},
|
||||||
|
testcase.input.events.map(
|
||||||
|
event_raw => ({
|
||||||
|
"title": event_raw.title,
|
||||||
|
"begin": event_raw.begin,
|
||||||
|
"end": null,
|
||||||
|
"description": null,
|
||||||
|
"location": null,
|
||||||
|
"tags": null,
|
||||||
|
})
|
||||||
|
),
|
||||||
{
|
{
|
||||||
"pit": lib_plankton.pit.from_datetime(testcase.input.datetime),
|
"pit": lib_plankton.pit.from_datetime(testcase.input.datetime),
|
||||||
"interval": testcase.input.interval,
|
"interval": testcase.input.interval,
|
||||||
|
@ -66,71 +101,26 @@ namespace _munin.test
|
||||||
);
|
);
|
||||||
|
|
||||||
// assertions
|
// assertions
|
||||||
if (result !== testcase.output)
|
if (
|
||||||
|
(
|
||||||
|
(testcase.output === null)
|
||||||
|
&&
|
||||||
|
(result === null)
|
||||||
|
)
|
||||||
|
||
|
||||||
|
(
|
||||||
|
(testcase.output !== null)
|
||||||
|
&&
|
||||||
|
lists_equal<string>(
|
||||||
|
result.map(event => event.title),
|
||||||
|
testcase.output
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
_munin.helpers.test.fail(testcase.name);
|
// success
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
async function reminder_covers_event(
|
|
||||||
) : Promise<void>
|
|
||||||
{
|
|
||||||
type type_input = {
|
|
||||||
reminder : {
|
|
||||||
frequency : string;
|
|
||||||
offset : int;
|
|
||||||
from : int;
|
|
||||||
to : int;
|
|
||||||
};
|
|
||||||
event : {
|
|
||||||
begin : lib_plankton.pit.type_datetime;
|
|
||||||
};
|
|
||||||
datetime : lib_plankton.pit.type_datetime;
|
|
||||||
interval : int;
|
|
||||||
};
|
|
||||||
type type_output = boolean;
|
|
||||||
const testcases : Array<
|
|
||||||
_munin.helpers.test.type_testcase<
|
|
||||||
type_input,
|
|
||||||
type_output
|
|
||||||
>
|
|
||||||
> = await _munin.helpers.test.get_data<type_input, type_output>(
|
|
||||||
"data/reminder_covers_event.testdata.json",
|
|
||||||
{
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const testcase of testcases)
|
|
||||||
{
|
|
||||||
_munin.helpers.test.start(testcase.name);
|
|
||||||
|
|
||||||
// execution
|
|
||||||
const result : boolean = _munin.logic.reminder_covers_event(
|
|
||||||
{
|
|
||||||
"frequency": _munin.logic.frequency_decode(testcase.input.reminder.frequency),
|
|
||||||
"offset": testcase.input.reminder.offset,
|
|
||||||
"from": testcase.input.reminder.from,
|
|
||||||
"to": testcase.input.reminder.to,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "test",
|
|
||||||
"begin": testcase.input.event.begin,
|
|
||||||
"end": null,
|
|
||||||
"description": null,
|
|
||||||
"location": null,
|
|
||||||
"tags": null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pit": lib_plankton.pit.from_datetime(testcase.input.datetime),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// assertions
|
|
||||||
if (result !== testcase.output)
|
|
||||||
{
|
{
|
||||||
_munin.helpers.test.fail(testcase.name);
|
_munin.helpers.test.fail(testcase.name);
|
||||||
}
|
}
|
||||||
|
@ -143,8 +133,7 @@ namespace _munin.test
|
||||||
export async function all(
|
export async function all(
|
||||||
) : Promise<void>
|
) : Promise<void>
|
||||||
{
|
{
|
||||||
await reminder_due();
|
await reminder_check();
|
||||||
await reminder_covers_event();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace _munin
|
||||||
title : string;
|
title : string;
|
||||||
time : string;
|
time : string;
|
||||||
location : string;
|
location : string;
|
||||||
|
events : string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ namespace _munin
|
||||||
send : (
|
send : (
|
||||||
(
|
(
|
||||||
labels : type_labels,
|
labels : type_labels,
|
||||||
event : type_event
|
events : Array<type_event>
|
||||||
)
|
)
|
||||||
=>
|
=>
|
||||||
Promise<void>
|
Promise<void>
|
||||||
|
|
Loading…
Reference in a new issue