Compare commits
No commits in common. "c9b882edbe2a5971b98e8cfe95080c5034507ba8" and "0f5dede94d4f86d62346dac7d389d19e5df5882d" have entirely different histories.
c9b882edbe
...
0f5dede94d
9 changed files with 149 additions and 519 deletions
101
lib/plankton/plankton.d.ts
vendored
101
lib/plankton/plankton.d.ts
vendored
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
declare type int = number;
|
type int = number;
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
declare type float = number;
|
type float = number;
|
||||||
declare var process: any;
|
declare var process: any;
|
||||||
declare var require: any;
|
declare var require: any;
|
||||||
declare class Buffer {
|
declare class Buffer {
|
||||||
|
@ -22,7 +22,7 @@ declare namespace lib_plankton.base {
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
declare type type_pseudopointer<type_value> = {
|
type type_pseudopointer<type_value> = {
|
||||||
value: type_value;
|
value: type_value;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
@ -644,11 +644,33 @@ declare namespace lib_plankton.call {
|
||||||
fallback?: (null | ((coproduct?: type_coproduct) => type_output));
|
fallback?: (null | ((coproduct?: type_coproduct) => type_output));
|
||||||
}): type_output;
|
}): type_output;
|
||||||
/**
|
/**
|
||||||
|
* for rate_limit_check
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
function try_catch_wrap<type_value>(get_value: (() => type_value)): {
|
type type_mana_snapshot = {
|
||||||
value: (null | type_value);
|
timestamp: float;
|
||||||
error: (null | any);
|
value: float;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* rate limiting algorithm, based on the idea of mana (magic power) in video games:
|
||||||
|
* - an actor has a fixed mana capacity, i.e. the maximum amount of available power
|
||||||
|
* - an actor has a fixed rate of mana regeneration, i.e. how fast the power is filled up (linear growth)
|
||||||
|
* - an action has a defined mana heft, i.e. how much power is required and deducted in order to execute it
|
||||||
|
* - mana states are represented by snapshots, i.e. the amount of power at a certain point in time
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
function rate_limit_check(setup: {
|
||||||
|
capacity: float;
|
||||||
|
regeneration_rate: float;
|
||||||
|
get_snapshot: (() => Promise<(null | type_mana_snapshot)>);
|
||||||
|
set_snapshot: ((snapshot: type_mana_snapshot) => Promise<void>);
|
||||||
|
update_snapshot: ((timestamp: float, value_increment: float) => Promise<void>);
|
||||||
|
}, heft: float): Promise<{
|
||||||
|
granted: boolean;
|
||||||
|
seconds: (null | float);
|
||||||
|
}>;
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.email {
|
declare namespace lib_plankton.email {
|
||||||
/**
|
/**
|
||||||
|
@ -2164,7 +2186,7 @@ declare namespace lib_plankton.storage.memory {
|
||||||
clear(): Promise<void>;
|
clear(): Promise<void>;
|
||||||
write(key: any, value: any): Promise<boolean>;
|
write(key: any, value: any): Promise<boolean>;
|
||||||
delete(key: any): Promise<void>;
|
delete(key: any): Promise<void>;
|
||||||
read(key: any): Promise<type_item>;
|
read(key: any): Promise<Awaited<type_item>>;
|
||||||
search(term: any): Promise<{
|
search(term: any): Promise<{
|
||||||
key: string;
|
key: string;
|
||||||
preview: string;
|
preview: string;
|
||||||
|
@ -3095,7 +3117,7 @@ declare namespace lib_plankton.pit {
|
||||||
/**
|
/**
|
||||||
* @todo test
|
* @todo test
|
||||||
*/
|
*/
|
||||||
function to_datetime(pit: type_pit, { timezone_shift, }?: {
|
function to_datetime(pit: type_pit, options?: {
|
||||||
timezone_shift?: int;
|
timezone_shift?: int;
|
||||||
}): type_datetime;
|
}): type_datetime;
|
||||||
/**
|
/**
|
||||||
|
@ -3145,48 +3167,6 @@ declare namespace lib_plankton.pit {
|
||||||
* @todo write tests
|
* @todo write tests
|
||||||
*/
|
*/
|
||||||
function cest_switch_off(year: int): type_pit;
|
function cest_switch_off(year: int): type_pit;
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function timezone_shift_ce(pit: type_pit): int;
|
|
||||||
/**
|
|
||||||
* [convenience]
|
|
||||||
*/
|
|
||||||
function to_datetime_ce(pit: type_pit): type_datetime;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function datetime_translate(datetime: type_datetime, timezone_shift: int): type_datetime;
|
|
||||||
/**
|
|
||||||
* [convenience]
|
|
||||||
*/
|
|
||||||
function datetime_translate_ce(datetime: type_datetime): type_datetime;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function timezone_shift_format(timezone_shift: int): string;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function date_format(date: type_date): string;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function time_format(time: type_time, { show_seconds, }?: {
|
|
||||||
show_seconds?: boolean;
|
|
||||||
}): string;
|
|
||||||
/**
|
|
||||||
* @todo show timezone
|
|
||||||
*/
|
|
||||||
function datetime_format(datetime: (null | type_datetime), { timezone_indicator, show_timezone, adjust_to_ce, omit_date, }?: {
|
|
||||||
timezone_indicator?: string;
|
|
||||||
show_timezone?: boolean;
|
|
||||||
adjust_to_ce?: boolean;
|
|
||||||
omit_date?: boolean;
|
|
||||||
}): string;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function timespan_format(from: type_datetime, to: (null | type_datetime), { timezone_indicator, show_timezone, adjust_to_ce, omit_date, }?: {
|
|
||||||
timezone_indicator?: string;
|
|
||||||
show_timezone?: boolean;
|
|
||||||
adjust_to_ce?: boolean;
|
|
||||||
omit_date?: boolean;
|
|
||||||
}): string;
|
|
||||||
}
|
}
|
||||||
declare namespace lib_plankton.ical {
|
declare namespace lib_plankton.ical {
|
||||||
/**
|
/**
|
||||||
|
@ -3294,14 +3274,9 @@ declare namespace lib_plankton.ical {
|
||||||
};
|
};
|
||||||
last_modified?: type_datetime;
|
last_modified?: type_datetime;
|
||||||
location?: string;
|
location?: string;
|
||||||
/**
|
|
||||||
* @see https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.3
|
|
||||||
*/
|
|
||||||
organizer?: {
|
organizer?: {
|
||||||
value?: string;
|
|
||||||
cn?: string;
|
cn?: string;
|
||||||
dir?: string;
|
value?: string;
|
||||||
sent_by?: string;
|
|
||||||
};
|
};
|
||||||
priority?: int;
|
priority?: int;
|
||||||
sequence?: int;
|
sequence?: int;
|
||||||
|
@ -3350,18 +3325,8 @@ declare namespace lib_plankton.ical {
|
||||||
* @see https://icalendar.org/iCalendar-RFC-5545/
|
* @see https://icalendar.org/iCalendar-RFC-5545/
|
||||||
* @todo implement edge cases
|
* @todo implement edge cases
|
||||||
*/
|
*/
|
||||||
function ics_decode_multi(ics_raw: string, { ignore_unhandled_instruction_keys, from_fucked_up_wordpress, }?: {
|
function ics_decode(ics: string, options?: {
|
||||||
ignore_unhandled_instruction_keys?: boolean;
|
debug?: boolean;
|
||||||
from_fucked_up_wordpress?: boolean;
|
|
||||||
}): Array<type_vcalendar>;
|
|
||||||
/**
|
|
||||||
* @see https://www.rfc-editor.org/rfc/rfc5545
|
|
||||||
* @see https://icalendar.org/iCalendar-RFC-5545/
|
|
||||||
* @todo implement edge cases
|
|
||||||
*/
|
|
||||||
function ics_decode(ics: string, { ignore_unhandled_instruction_keys, from_fucked_up_wordpress, }?: {
|
|
||||||
ignore_unhandled_instruction_keys?: boolean;
|
|
||||||
from_fucked_up_wordpress?: boolean;
|
|
||||||
}): type_vcalendar;
|
}): type_vcalendar;
|
||||||
/**
|
/**
|
||||||
* @todo method
|
* @todo method
|
||||||
|
|
|
@ -1494,22 +1494,63 @@ var lib_plankton;
|
||||||
}
|
}
|
||||||
call.distinguish = distinguish;
|
call.distinguish = distinguish;
|
||||||
/**
|
/**
|
||||||
|
* rate limiting algorithm, based on the idea of mana (magic power) in video games:
|
||||||
|
* - an actor has a fixed mana capacity, i.e. the maximum amount of available power
|
||||||
|
* - an actor has a fixed rate of mana regeneration, i.e. how fast the power is filled up (linear growth)
|
||||||
|
* - an action has a defined mana heft, i.e. how much power is required and deducted in order to execute it
|
||||||
|
* - mana states are represented by snapshots, i.e. the amount of power at a certain point in time
|
||||||
|
*
|
||||||
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
function try_catch_wrap(get_value) {
|
async function rate_limit_check(setup, heft) {
|
||||||
try {
|
if (heft > setup.capacity) {
|
||||||
return {
|
return Promise.resolve({
|
||||||
"value": get_value(),
|
"granted": false,
|
||||||
"error": null,
|
"seconds": null,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
catch (error) {
|
else {
|
||||||
return {
|
// get current value
|
||||||
"value": null,
|
const current_timestamp = (Date.now() / 1000);
|
||||||
"error": error,
|
const old_snapshot_raw = (await setup.get_snapshot());
|
||||||
};
|
const old_snapshot = (old_snapshot_raw
|
||||||
|
??
|
||||||
|
{ "timestamp": current_timestamp, "value": setup.capacity });
|
||||||
|
const seconds_passed = (current_timestamp - old_snapshot.timestamp);
|
||||||
|
const current_value = Math.min(setup.capacity, (old_snapshot.value
|
||||||
|
+
|
||||||
|
(setup.regeneration_rate
|
||||||
|
*
|
||||||
|
seconds_passed)));
|
||||||
|
// analyze
|
||||||
|
if (current_value < heft) {
|
||||||
|
// too less
|
||||||
|
const seconds_needed = ((setup.regeneration_rate <= 0)
|
||||||
|
? null
|
||||||
|
: ((heft - old_snapshot.value) / setup.regeneration_rate));
|
||||||
|
return Promise.resolve({
|
||||||
|
"granted": false,
|
||||||
|
"seconds": ((seconds_needed === null) ? null : (seconds_needed - seconds_passed)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// enough -> update snapshot
|
||||||
|
const new_value = (current_value - heft);
|
||||||
|
// set_snapshot
|
||||||
|
if (old_snapshot_raw === null) {
|
||||||
|
await setup.set_snapshot({ "timestamp": current_timestamp, "value": new_value });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await setup.update_snapshot(current_timestamp, (new_value - old_snapshot.value));
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
"granted": true,
|
||||||
|
"seconds": 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
call.try_catch_wrap = try_catch_wrap;
|
call.rate_limit_check = rate_limit_check;
|
||||||
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
})(call = lib_plankton.call || (lib_plankton.call = {}));
|
||||||
})(lib_plankton || (lib_plankton = {}));
|
})(lib_plankton || (lib_plankton = {}));
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
@ -1527,7 +1568,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
function step(op) {
|
function step(op) {
|
||||||
if (f) throw new TypeError("Generator is already executing.");
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
while (_) try {
|
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
switch (op[0]) {
|
switch (op[0]) {
|
||||||
|
@ -4859,16 +4900,11 @@ var lib_plankton;
|
||||||
if (options.legacy) {
|
if (options.legacy) {
|
||||||
const value = args[key];
|
const value = args[key];
|
||||||
const regexp_argument = new RegExp("\\${" + key + "}", "g");
|
const regexp_argument = new RegExp("\\${" + key + "}", "g");
|
||||||
/*
|
lib_plankton.log.debug("lib_plankton.string.coin", {
|
||||||
lib_plankton.log.debug(
|
"key": key,
|
||||||
"lib_plankton.string.coin",
|
"regex": regexp_argument.toString(),
|
||||||
{
|
"value": value,
|
||||||
"key": key,
|
});
|
||||||
"regex": regexp_argument.toString(),
|
|
||||||
"value": value,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
str = str.replace(regexp_argument, value);
|
str = str.replace(regexp_argument, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4876,16 +4912,11 @@ var lib_plankton;
|
||||||
{
|
{
|
||||||
const value = args[key];
|
const value = args[key];
|
||||||
const regexp_argument = new RegExp(options.open + key + options.close, "g");
|
const regexp_argument = new RegExp(options.open + key + options.close, "g");
|
||||||
/*
|
lib_plankton.log.debug("lib_plankton.string.coin", {
|
||||||
lib_plankton.log.debug(
|
"key": key,
|
||||||
"lib_plankton.string.coin",
|
"regex": regexp_argument.toString(),
|
||||||
{
|
"value": value,
|
||||||
"key": key,
|
});
|
||||||
"regex": regexp_argument.toString(),
|
|
||||||
"value": value,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
str = str.replace(regexp_argument, value);
|
str = str.replace(regexp_argument, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6533,7 +6564,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
function step(op) {
|
function step(op) {
|
||||||
if (f) throw new TypeError("Generator is already executing.");
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
while (_) try {
|
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
switch (op[0]) {
|
switch (op[0]) {
|
||||||
|
@ -10138,7 +10169,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
function step(op) {
|
function step(op) {
|
||||||
if (f) throw new TypeError("Generator is already executing.");
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
while (_) try {
|
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
switch (op[0]) {
|
switch (op[0]) {
|
||||||
|
@ -10647,15 +10678,18 @@ var lib_plankton;
|
||||||
/**
|
/**
|
||||||
* @todo test
|
* @todo test
|
||||||
*/
|
*/
|
||||||
function to_datetime(pit, { timezone_shift = 0, } = {}) {
|
function to_datetime(pit, options = {}) {
|
||||||
|
options = Object.assign({
|
||||||
|
"timezone_shift": 0,
|
||||||
|
}, options);
|
||||||
return lib_plankton.call.convey(pit, [
|
return lib_plankton.call.convey(pit, [
|
||||||
to_date_object,
|
to_date_object,
|
||||||
(x) => x.getTime(),
|
(x) => x.getTime(),
|
||||||
(x) => (x + ((timezone_shift * (60 * 60)) * 1000)),
|
(x) => (x + ((options.timezone_shift * (60 * 60)) * 1000)),
|
||||||
(x) => new Date(x),
|
(x) => new Date(x),
|
||||||
x => x.toISOString(),
|
x => x.toISOString(),
|
||||||
x => ({
|
x => ({
|
||||||
"timezone_shift": timezone_shift,
|
"timezone_shift": options.timezone_shift,
|
||||||
"date": {
|
"date": {
|
||||||
"year": parseInt(x.slice(0, 4)),
|
"year": parseInt(x.slice(0, 4)),
|
||||||
"month": parseInt(x.slice(5, 7)),
|
"month": parseInt(x.slice(5, 7)),
|
||||||
|
@ -10952,182 +10986,6 @@ var lib_plankton;
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
pit_1.cest_switch_off = cest_switch_off;
|
pit_1.cest_switch_off = cest_switch_off;
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function timezone_shift_ce(pit) {
|
|
||||||
const year = to_datetime(pit).date.year;
|
|
||||||
return (is_between(pit, cest_switch_on(year), cest_switch_off(year))
|
|
||||||
? +2
|
|
||||||
: +1);
|
|
||||||
}
|
|
||||||
pit_1.timezone_shift_ce = timezone_shift_ce;
|
|
||||||
/**
|
|
||||||
* [convenience]
|
|
||||||
*/
|
|
||||||
function to_datetime_ce(pit) {
|
|
||||||
return to_datetime(pit, {
|
|
||||||
"timezone_shift": timezone_shift_ce(pit),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
pit_1.to_datetime_ce = to_datetime_ce;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function datetime_translate(datetime, timezone_shift) {
|
|
||||||
if (datetime.timezone_shift === timezone_shift) {
|
|
||||||
return datetime;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const pit = from_datetime(datetime);
|
|
||||||
const pit_shifted = shift_hour(pit, (timezone_shift - datetime.timezone_shift));
|
|
||||||
const datetime_shifted = to_datetime(pit_shifted);
|
|
||||||
return {
|
|
||||||
"timezone_shift": timezone_shift,
|
|
||||||
"date": datetime_shifted.date,
|
|
||||||
"time": ((datetime.time === null)
|
|
||||||
?
|
|
||||||
null
|
|
||||||
: datetime_shifted.time)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pit_1.datetime_translate = datetime_translate;
|
|
||||||
/**
|
|
||||||
* [convenience]
|
|
||||||
*/
|
|
||||||
function datetime_translate_ce(datetime) {
|
|
||||||
return datetime_translate(datetime, timezone_shift_ce(from_datetime(datetime)));
|
|
||||||
}
|
|
||||||
pit_1.datetime_translate_ce = datetime_translate_ce;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function timezone_shift_format(timezone_shift) {
|
|
||||||
return lib_plankton.string.coin("{{sign}}{{value}}", {
|
|
||||||
"sign": ((timezone_shift === 0)
|
|
||||||
?
|
|
||||||
" "
|
|
||||||
:
|
|
||||||
((timezone_shift > 0)
|
|
||||||
?
|
|
||||||
"+"
|
|
||||||
:
|
|
||||||
"-")),
|
|
||||||
"value": Math.abs(timezone_shift).toFixed(0),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
pit_1.timezone_shift_format = timezone_shift_format;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function date_format(date) {
|
|
||||||
return lib_plankton.string.coin("{{year}}-{{month}}-{{day}}", {
|
|
||||||
"year": date.year.toFixed(0).padStart(4, "0"),
|
|
||||||
"month": date.month.toFixed(0).padStart(2, "0"),
|
|
||||||
"day": date.day.toFixed(0).padStart(2, "0"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
pit_1.date_format = date_format;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function time_format(time, { show_seconds = false, } = {}) {
|
|
||||||
return lib_plankton.string.coin((show_seconds
|
|
||||||
?
|
|
||||||
"{{hour}}:{{minute}}:{{seconds}}"
|
|
||||||
:
|
|
||||||
"{{hour}}:{{minute}}"), {
|
|
||||||
"hour": time.hour.toFixed(0).padStart(2, "0"),
|
|
||||||
"minute": time.minute.toFixed(0).padStart(2, "0"),
|
|
||||||
"second": time.second.toFixed(0).padStart(2, "0"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
pit_1.time_format = time_format;
|
|
||||||
/**
|
|
||||||
* @todo show timezone
|
|
||||||
*/
|
|
||||||
function datetime_format(datetime, { timezone_indicator = "", show_timezone = false, adjust_to_ce = false, omit_date = false, } = {}) {
|
|
||||||
if (datetime === null) {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const datetime_adjusted = (adjust_to_ce
|
|
||||||
?
|
|
||||||
to_datetime_ce(from_datetime(datetime))
|
|
||||||
:
|
|
||||||
datetime);
|
|
||||||
return lib_plankton.string.coin("{{macro_date_and_time}}{{macro_timezone}}", {
|
|
||||||
"macro_date_and_time": ([
|
|
||||||
// date
|
|
||||||
(omit_date
|
|
||||||
?
|
|
||||||
null
|
|
||||||
:
|
|
||||||
date_format(datetime_adjusted.date)),
|
|
||||||
// time
|
|
||||||
((datetime_adjusted.time === null)
|
|
||||||
?
|
|
||||||
null
|
|
||||||
:
|
|
||||||
time_format(datetime_adjusted.time)),
|
|
||||||
]
|
|
||||||
.filter(x => (x !== null))
|
|
||||||
.join(", ")),
|
|
||||||
"macro_timezone": (show_timezone
|
|
||||||
?
|
|
||||||
lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", {
|
|
||||||
"timezone_indicator": timezone_indicator,
|
|
||||||
"timezone_value": timezone_shift_format(datetime_adjusted.timezone_shift),
|
|
||||||
})
|
|
||||||
:
|
|
||||||
""),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pit_1.datetime_format = datetime_format;
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
function timespan_format(from, to, { timezone_indicator = "", show_timezone = false, adjust_to_ce = false, omit_date = false, } = {}) {
|
|
||||||
const from_adjusted = (adjust_to_ce
|
|
||||||
?
|
|
||||||
datetime_translate_ce(from)
|
|
||||||
:
|
|
||||||
from);
|
|
||||||
const to_adjusted = ((to === null)
|
|
||||||
?
|
|
||||||
null
|
|
||||||
:
|
|
||||||
(adjust_to_ce
|
|
||||||
?
|
|
||||||
datetime_translate_ce(to)
|
|
||||||
:
|
|
||||||
to));
|
|
||||||
return lib_plankton.string.coin("{{from}}{{to_macro}}{{macro_timezone}}", {
|
|
||||||
"from": datetime_format(from_adjusted, {
|
|
||||||
"show_timezone": false,
|
|
||||||
"adjust_to_ce": false,
|
|
||||||
"omit_date": omit_date,
|
|
||||||
}),
|
|
||||||
"to_macro": ((to_adjusted === null)
|
|
||||||
?
|
|
||||||
""
|
|
||||||
:
|
|
||||||
lib_plankton.string.coin(" - {{to}}", {
|
|
||||||
"to": datetime_format(to_adjusted, {
|
|
||||||
"omit_date": ((from_adjusted.date.year === to_adjusted.date.year)
|
|
||||||
&&
|
|
||||||
(from_adjusted.date.month === to_adjusted.date.month)
|
|
||||||
&&
|
|
||||||
(from_adjusted.date.day === to_adjusted.date.day))
|
|
||||||
}),
|
|
||||||
})),
|
|
||||||
"macro_timezone": (show_timezone
|
|
||||||
?
|
|
||||||
lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", {
|
|
||||||
"timezone_indicator": timezone_indicator,
|
|
||||||
"timezone_value": timezone_shift_format(from_adjusted.timezone_shift),
|
|
||||||
})
|
|
||||||
:
|
|
||||||
""),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
pit_1.timespan_format = timespan_format;
|
|
||||||
})(pit = lib_plankton.pit || (lib_plankton.pit = {}));
|
})(pit = lib_plankton.pit || (lib_plankton.pit = {}));
|
||||||
})(lib_plankton || (lib_plankton = {}));
|
})(lib_plankton || (lib_plankton = {}));
|
||||||
/*
|
/*
|
||||||
|
@ -11349,22 +11207,11 @@ var lib_plankton;
|
||||||
* @see https://icalendar.org/iCalendar-RFC-5545/
|
* @see https://icalendar.org/iCalendar-RFC-5545/
|
||||||
* @todo implement edge cases
|
* @todo implement edge cases
|
||||||
*/
|
*/
|
||||||
function ics_decode_multi(ics_raw, { ignore_unhandled_instruction_keys = false, from_fucked_up_wordpress = false, } = {}) {
|
function ics_decode(ics, options = {}) {
|
||||||
|
options = Object.assign({
|
||||||
|
"debug": false,
|
||||||
|
}, options);
|
||||||
// preprocessing
|
// preprocessing
|
||||||
let ics;
|
|
||||||
if (from_fucked_up_wordpress) {
|
|
||||||
ics = (ics_raw
|
|
||||||
.replace(new RegExp("\r", "g"), "")
|
|
||||||
.replace(new RegExp("END:VCALENDAR", "g"), "")
|
|
||||||
.replace(new RegExp("\n", "g"), "\r\n")
|
|
||||||
.replace(new RegExp("END:VEVENT", "g"), "END:VEVENT\r\nEND:VCALENDAR"));
|
|
||||||
lib_plankton.log.debug("plankton.ical.ics_decode.preprocessing.wordpress_fuckup", {
|
|
||||||
"result": ics,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ics = ics_raw;
|
|
||||||
}
|
|
||||||
const lines = ics.split("\r\n");
|
const lines = ics.split("\r\n");
|
||||||
let content_lines = [];
|
let content_lines = [];
|
||||||
let content_line_buffer = null;
|
let content_line_buffer = null;
|
||||||
|
@ -11401,12 +11248,6 @@ var lib_plankton;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (content_line_buffer === null) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
content_lines.push(content_line_buffer);
|
|
||||||
}
|
|
||||||
const instructions = content_lines.map((content_line) => {
|
const instructions = content_lines.map((content_line) => {
|
||||||
const parts = content_line.split(":");
|
const parts = content_line.split(":");
|
||||||
const parts_left = parts[0].split(";");
|
const parts_left = parts[0].split(";");
|
||||||
|
@ -11418,21 +11259,16 @@ var lib_plankton;
|
||||||
.map(x => x.replace(new RegExp("\\\\,", "g"), ","))),
|
.map(x => x.replace(new RegExp("\\\\,", "g"), ","))),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
lib_plankton.log.debug("plankton.ical.ics_decode_multi.instructions", {
|
|
||||||
"instructions": instructions,
|
|
||||||
});
|
|
||||||
// core
|
// core
|
||||||
let state = {
|
let state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_begin,
|
"label": enum_decode_state_label.expect_vcalendar_begin,
|
||||||
"vcalendar_list": [],
|
|
||||||
"vcalendar": null,
|
"vcalendar": null,
|
||||||
"vevent": null,
|
"vevent": null,
|
||||||
};
|
};
|
||||||
instructions.forEach((instruction) => {
|
instructions.forEach((instruction) => {
|
||||||
lib_plankton.log.debug("plankton.ical.ics_decode_multi.step", {
|
if (options.debug) {
|
||||||
"state": state,
|
console.info(JSON.stringify({ "instruction": instruction, "state": state }, undefined, "\t"));
|
||||||
"current_instruction": instruction,
|
}
|
||||||
});
|
|
||||||
switch (state.label) {
|
switch (state.label) {
|
||||||
default: {
|
default: {
|
||||||
throw (new Error("unhandled state label: " + state.label));
|
throw (new Error("unhandled state label: " + state.label));
|
||||||
|
@ -11441,27 +11277,18 @@ var lib_plankton;
|
||||||
case enum_decode_state_label.expect_vcalendar_begin: {
|
case enum_decode_state_label.expect_vcalendar_begin: {
|
||||||
switch (instruction.command) {
|
switch (instruction.command) {
|
||||||
default: {
|
default: {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_instruction_key", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
});
|
|
||||||
throw (new Error("unexpected instruction key: " + instruction.command));
|
throw (new Error("unexpected instruction key: " + instruction.command));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "BEGIN": {
|
case "BEGIN": {
|
||||||
switch (instruction.value[0]) {
|
switch (instruction.value[0]) {
|
||||||
default: {
|
default: {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_instruction_value", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
});
|
|
||||||
throw (new Error("unexpected instruction value: " + instruction.value[0]));
|
throw (new Error("unexpected instruction value: " + instruction.value[0]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VCALENDAR": {
|
case "VCALENDAR": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_property,
|
"label": enum_decode_state_label.expect_vcalendar_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": {
|
"vcalendar": {
|
||||||
"version": "",
|
"version": "",
|
||||||
"prodid": "",
|
"prodid": "",
|
||||||
|
@ -11482,7 +11309,6 @@ var lib_plankton;
|
||||||
case "VERSION": {
|
case "VERSION": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_property,
|
"label": enum_decode_state_label.expect_vcalendar_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["version", instruction.value[0]]])),
|
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["version", instruction.value[0]]])),
|
||||||
"vevent": state.vevent,
|
"vevent": state.vevent,
|
||||||
};
|
};
|
||||||
|
@ -11491,7 +11317,6 @@ var lib_plankton;
|
||||||
case "PRODID": {
|
case "PRODID": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_property,
|
"label": enum_decode_state_label.expect_vcalendar_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["prodid", instruction.value[0]]])),
|
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["prodid", instruction.value[0]]])),
|
||||||
"vevent": state.vevent,
|
"vevent": state.vevent,
|
||||||
};
|
};
|
||||||
|
@ -11500,46 +11325,25 @@ var lib_plankton;
|
||||||
case "METHOD": {
|
case "METHOD": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_property,
|
"label": enum_decode_state_label.expect_vcalendar_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["method", instruction.value[0]]])),
|
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["method", instruction.value[0]]])),
|
||||||
"vevent": state.vevent,
|
"vevent": state.vevent,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "CALSCALE": {
|
|
||||||
state = {
|
|
||||||
"label": enum_decode_state_label.expect_vcalendar_property,
|
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["calscale", instruction.value[0]]])),
|
|
||||||
"vevent": state.vevent,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "BEGIN": {
|
case "BEGIN": {
|
||||||
const object = instruction.value[0];
|
const object = instruction.value[0];
|
||||||
switch (object) {
|
switch (object) {
|
||||||
default: {
|
default: {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unhandled_object", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
"object": object,
|
|
||||||
});
|
|
||||||
throw (new Error("unhandled object: " + object));
|
throw (new Error("unhandled object: " + object));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VCALENDAR": {
|
case "VCALENDAR": {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unexpected_object", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
"object": object,
|
|
||||||
});
|
|
||||||
throw (new Error("unexpected object: " + object));
|
throw (new Error("unexpected object: " + object));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VEVENT": {
|
case "VEVENT": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": {
|
"vevent": {
|
||||||
"uid": "",
|
"uid": "",
|
||||||
|
@ -11558,19 +11362,13 @@ var lib_plankton;
|
||||||
const object = instruction.value[0];
|
const object = instruction.value[0];
|
||||||
switch (object) {
|
switch (object) {
|
||||||
default: {
|
default: {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vcalendar.unhandled_object", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
"object": object,
|
|
||||||
});
|
|
||||||
throw (new Error("unhandled object: " + object));
|
throw (new Error("unhandled object: " + object));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VCALENDAR": {
|
case "VCALENDAR": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_begin,
|
"label": enum_decode_state_label.done,
|
||||||
"vcalendar_list": state.vcalendar_list.concat([state.vcalendar]),
|
"vcalendar": state.vcalendar,
|
||||||
"vcalendar": null,
|
|
||||||
"vevent": state.vevent,
|
"vevent": state.vevent,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
@ -11584,10 +11382,6 @@ var lib_plankton;
|
||||||
const value = instruction.value.join(";");
|
const value = instruction.value.join(";");
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_property,
|
"label": enum_decode_state_label.expect_vcalendar_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
/**
|
|
||||||
* @todo not sure; state.vcalendar might be null
|
|
||||||
*/
|
|
||||||
"vcalendar": Object.assign(state.vcalendar, {
|
"vcalendar": Object.assign(state.vcalendar, {
|
||||||
"x_props": Object.assign((state.vcalendar.x_props ?? {}), Object.fromEntries([[key, value]]))
|
"x_props": Object.assign((state.vcalendar.x_props ?? {}), Object.fromEntries([[key, value]]))
|
||||||
}),
|
}),
|
||||||
|
@ -11595,16 +11389,8 @@ var lib_plankton;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lib_plankton.log.warning("plankton.ical.ics_decode.error.vcalendar.unhandled_instruction_key", {
|
console.info({ "instruction": instruction, "state": state });
|
||||||
"state": state,
|
throw (new Error("unhandled instruction key: " + instruction.command));
|
||||||
"instruction": instruction,
|
|
||||||
});
|
|
||||||
if (ignore_unhandled_instruction_keys) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw (new Error("unhandled instruction key: " + instruction.command));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11616,7 +11402,6 @@ var lib_plankton;
|
||||||
case "UID": {
|
case "UID": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["uid", instruction.value[0]]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["uid", instruction.value[0]]])),
|
||||||
};
|
};
|
||||||
|
@ -11625,20 +11410,14 @@ var lib_plankton;
|
||||||
case "DTSTART": {
|
case "DTSTART": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||||||
[
|
[
|
||||||
"dtstart",
|
"dtstart",
|
||||||
Object.assign({
|
{
|
||||||
|
"tzid": instruction.parameters["tzid"],
|
||||||
"value": datetime_decode(instruction.value[0]),
|
"value": datetime_decode(instruction.value[0]),
|
||||||
}, (("tzid" in instruction.parameters)
|
}
|
||||||
?
|
|
||||||
{
|
|
||||||
"tzid": instruction.parameters["tzid"],
|
|
||||||
}
|
|
||||||
:
|
|
||||||
{}))
|
|
||||||
]
|
]
|
||||||
])),
|
])),
|
||||||
};
|
};
|
||||||
|
@ -11647,20 +11426,14 @@ var lib_plankton;
|
||||||
case "DTEND": {
|
case "DTEND": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||||||
[
|
[
|
||||||
"dtend",
|
"dtend",
|
||||||
Object.assign({
|
{
|
||||||
|
"tzid": instruction.parameters["tzid"],
|
||||||
"value": datetime_decode(instruction.value[0]),
|
"value": datetime_decode(instruction.value[0]),
|
||||||
}, (("tzid" in instruction.parameters)
|
}
|
||||||
?
|
|
||||||
{
|
|
||||||
"tzid": instruction.parameters["tzid"],
|
|
||||||
}
|
|
||||||
:
|
|
||||||
{}))
|
|
||||||
]
|
]
|
||||||
])),
|
])),
|
||||||
};
|
};
|
||||||
|
@ -11669,7 +11442,6 @@ var lib_plankton;
|
||||||
case "DTSTAMP": {
|
case "DTSTAMP": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||||||
[
|
[
|
||||||
|
@ -11683,7 +11455,6 @@ var lib_plankton;
|
||||||
case "SEQUENCE": {
|
case "SEQUENCE": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["sequence", parseInt(instruction.value[0])]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["sequence", parseInt(instruction.value[0])]])),
|
||||||
};
|
};
|
||||||
|
@ -11692,7 +11463,6 @@ var lib_plankton;
|
||||||
case "TRANSP": {
|
case "TRANSP": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["transp", transp_decode(instruction.value[0])]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["transp", transp_decode(instruction.value[0])]])),
|
||||||
};
|
};
|
||||||
|
@ -11701,7 +11471,6 @@ var lib_plankton;
|
||||||
case "SUMMARY": {
|
case "SUMMARY": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["summary", instruction.value[0]]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["summary", instruction.value[0]]])),
|
||||||
};
|
};
|
||||||
|
@ -11710,7 +11479,6 @@ var lib_plankton;
|
||||||
case "CLASS": {
|
case "CLASS": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["class", class_decode(instruction.value[0])]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["class", class_decode(instruction.value[0])]])),
|
||||||
};
|
};
|
||||||
|
@ -11719,7 +11487,6 @@ var lib_plankton;
|
||||||
case "STATUS": {
|
case "STATUS": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["status", event_status_decode(instruction.value[0])]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["status", event_status_decode(instruction.value[0])]])),
|
||||||
};
|
};
|
||||||
|
@ -11728,7 +11495,6 @@ var lib_plankton;
|
||||||
case "DESCRIPTION": {
|
case "DESCRIPTION": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["description", instruction.value[0]]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["description", instruction.value[0]]])),
|
||||||
};
|
};
|
||||||
|
@ -11737,7 +11503,6 @@ var lib_plankton;
|
||||||
case "CATEGORIES": {
|
case "CATEGORIES": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["categories", instruction.value[0].split(",")]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["categories", instruction.value[0].split(",")]])),
|
||||||
};
|
};
|
||||||
|
@ -11746,7 +11511,6 @@ var lib_plankton;
|
||||||
case "CREATED": {
|
case "CREATED": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||||||
[
|
[
|
||||||
|
@ -11762,7 +11526,6 @@ var lib_plankton;
|
||||||
case "LOCATION": {
|
case "LOCATION": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["location", instruction.value[0]]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["location", instruction.value[0]]])),
|
||||||
};
|
};
|
||||||
|
@ -11771,7 +11534,6 @@ var lib_plankton;
|
||||||
case "URL": {
|
case "URL": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["url", instruction.value[0]]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["url", instruction.value[0]]])),
|
||||||
};
|
};
|
||||||
|
@ -11780,7 +11542,6 @@ var lib_plankton;
|
||||||
case "LAST-MODIFIED": {
|
case "LAST-MODIFIED": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
||||||
[
|
[
|
||||||
|
@ -11796,58 +11557,23 @@ var lib_plankton;
|
||||||
case "ATTENDEE": {
|
case "ATTENDEE": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([["attendee", instruction.value[0]]])),
|
"vevent": Object.assign(state.vevent, Object.fromEntries([["attendee", instruction.value[0]]])),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "ORGANIZER": {
|
|
||||||
state = {
|
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
|
||||||
"vevent": Object.assign(state.vevent, Object.fromEntries([
|
|
||||||
[
|
|
||||||
"organizer",
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @todo parameters
|
|
||||||
*/
|
|
||||||
"value": instruction.value[0],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
])),
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "BEGIN": {
|
case "BEGIN": {
|
||||||
const object = instruction.value[0];
|
const object = instruction.value[0];
|
||||||
switch (object) {
|
switch (object) {
|
||||||
default: {
|
default: {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unhandled_object", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
"object": object,
|
|
||||||
});
|
|
||||||
throw (new Error("unhandled object: " + object));
|
throw (new Error("unhandled object: " + object));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VCALENDAR": {
|
case "VCALENDAR": {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unexpected_object", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
"object": object,
|
|
||||||
});
|
|
||||||
throw (new Error("unexpected object: " + object));
|
throw (new Error("unexpected object: " + object));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VEVENT": {
|
case "VEVENT": {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unexpected_object", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
"object": object,
|
|
||||||
});
|
|
||||||
throw (new Error("unexpected object: " + object));
|
throw (new Error("unexpected object: " + object));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11858,18 +11584,12 @@ var lib_plankton;
|
||||||
const object = instruction.value[0];
|
const object = instruction.value[0];
|
||||||
switch (object) {
|
switch (object) {
|
||||||
default: {
|
default: {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.vevent.unhandled_value", {
|
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
"value": object,
|
|
||||||
});
|
|
||||||
throw (new Error("unhandled value: " + object));
|
throw (new Error("unhandled value: " + object));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VEVENT": {
|
case "VEVENT": {
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vcalendar_property,
|
"label": enum_decode_state_label.expect_vcalendar_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": Object.assign(state.vcalendar, {
|
"vcalendar": Object.assign(state.vcalendar, {
|
||||||
"vevents": state.vcalendar.vevents.concat([state.vevent]),
|
"vevents": state.vcalendar.vevents.concat([state.vevent]),
|
||||||
}),
|
}),
|
||||||
|
@ -11886,7 +11606,6 @@ var lib_plankton;
|
||||||
const value = instruction.value.join(";");
|
const value = instruction.value.join(";");
|
||||||
state = {
|
state = {
|
||||||
"label": enum_decode_state_label.expect_vevent_property,
|
"label": enum_decode_state_label.expect_vevent_property,
|
||||||
"vcalendar_list": state.vcalendar_list,
|
|
||||||
"vcalendar": state.vcalendar,
|
"vcalendar": state.vcalendar,
|
||||||
"vevent": Object.assign(state.vevent, {
|
"vevent": Object.assign(state.vevent, {
|
||||||
"x_props": Object.assign((state.vevent.x_props ?? {}), Object.fromEntries([[key, value]]))
|
"x_props": Object.assign((state.vevent.x_props ?? {}), Object.fromEntries([[key, value]]))
|
||||||
|
@ -11894,16 +11613,8 @@ var lib_plankton;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lib_plankton.log.warning("plankton.ical.ics_decode.error.vevent.unhandled_instruction_key", {
|
console.info({ "instruction": instruction, "state": state });
|
||||||
"state": state,
|
throw (new Error("unhandled instruction key: " + instruction.command));
|
||||||
"instruction": instruction,
|
|
||||||
});
|
|
||||||
if (ignore_unhandled_instruction_keys) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw (new Error("unhandled instruction key: " + instruction.command));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -11911,39 +11622,13 @@ var lib_plankton;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case enum_decode_state_label.done: {
|
case enum_decode_state_label.done: {
|
||||||
lib_plankton.log.error("plankton.ical.ics_decode.error.end_expected", {
|
console.info({ "instruction": instruction, "state": state });
|
||||||
"state": state,
|
|
||||||
"instruction": instruction,
|
|
||||||
});
|
|
||||||
throw (new Error("end expected"));
|
throw (new Error("end expected"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return state.vcalendar_list;
|
return state.vcalendar;
|
||||||
}
|
|
||||||
ical.ics_decode_multi = ics_decode_multi;
|
|
||||||
/**
|
|
||||||
* @see https://www.rfc-editor.org/rfc/rfc5545
|
|
||||||
* @see https://icalendar.org/iCalendar-RFC-5545/
|
|
||||||
* @todo implement edge cases
|
|
||||||
*/
|
|
||||||
function ics_decode(ics, { ignore_unhandled_instruction_keys = false, from_fucked_up_wordpress = false, } = {}) {
|
|
||||||
const vcalendar_list = ics_decode_multi(ics, {
|
|
||||||
"ignore_unhandled_instruction_keys": ignore_unhandled_instruction_keys,
|
|
||||||
"from_fucked_up_wordpress": from_fucked_up_wordpress,
|
|
||||||
});
|
|
||||||
if (vcalendar_list.length < 1) {
|
|
||||||
throw (new Error("no calendar data found"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (vcalendar_list.length > 1) {
|
|
||||||
throw (new Error("ambiguous calendar data found"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return vcalendar_list[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ical.ics_decode = ics_decode;
|
ical.ics_decode = ics_decode;
|
||||||
/**
|
/**
|
||||||
|
@ -14799,7 +14484,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
function step(op) {
|
function step(op) {
|
||||||
if (f) throw new TypeError("Generator is already executing.");
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
while (_) try {
|
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
switch (op[0]) {
|
switch (op[0]) {
|
||||||
|
|
|
@ -33,7 +33,6 @@ namespace _zeitbild.api
|
||||||
data : {
|
data : {
|
||||||
url : string;
|
url : string;
|
||||||
read_only : boolean;
|
read_only : boolean;
|
||||||
from_fucked_up_wordpress : boolean;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -80,7 +79,6 @@ namespace _zeitbild.api
|
||||||
"data": {
|
"data": {
|
||||||
"url": stuff.input.resource.data.url,
|
"url": stuff.input.resource.data.url,
|
||||||
"read_only": stuff.input.resource.data.read_only,
|
"read_only": stuff.input.resource.data.read_only,
|
||||||
"from_fucked_up_wordpress": stuff.input.resource.data.from_fucked_up_wordpress,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -168,31 +168,27 @@ namespace _zeitbild.api
|
||||||
user_id
|
user_id
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
(data) => Promise.resolve(
|
(data) => Promise.resolve({
|
||||||
{
|
"status_code": 200,
|
||||||
"status_code": 200,
|
"data": (
|
||||||
"data": (
|
data
|
||||||
data
|
.map(
|
||||||
.map(
|
(entry) => ({
|
||||||
(entry) => ({
|
"calendar_id": entry.calendar_id,
|
||||||
"calendar_id": entry.calendar_id,
|
"calendar_name": entry.calendar_name,
|
||||||
"calendar_name": entry.calendar_name,
|
"access_level": _zeitbild.api.access_level_encode(entry.access_level),
|
||||||
"access_level": _zeitbild.api.access_level_encode(entry.access_level),
|
"event_id": entry.event_id,
|
||||||
"event_id": entry.event_id,
|
"event_object": entry.event_object,
|
||||||
"event_object": entry.event_object,
|
})
|
||||||
})
|
)
|
||||||
)
|
),
|
||||||
),
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
.catch(
|
.catch(
|
||||||
(reason) => Promise.resolve(
|
(reason) => Promise.resolve({
|
||||||
{
|
"status_code": 403,
|
||||||
"status_code": 403,
|
"data": String(reason),
|
||||||
"data": String(reason),
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace _zeitbild.database
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
const _compatible_revisions : Array<string> = [
|
const _compatible_revisions : Array<string> = [
|
||||||
"r4",
|
"r3",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ type type_data = {
|
||||||
data : {
|
data : {
|
||||||
url : string;
|
url : string;
|
||||||
read_only : boolean;
|
read_only : boolean;
|
||||||
from_fucked_up_wordpress ?: boolean;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -110,7 +109,6 @@ async function data_init(
|
||||||
"data": {
|
"data": {
|
||||||
"url": calendar_raw.resource.data.url,
|
"url": calendar_raw.resource.data.url,
|
||||||
"read_only": calendar_raw.resource.data.read_only,
|
"read_only": calendar_raw.resource.data.read_only,
|
||||||
"from_fucked_up_wordpress": (calendar_raw.resource.data.from_fucked_up_wordpress ?? false),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
resource_id = await _zeitbild.service.resource.add(
|
resource_id = await _zeitbild.service.resource.add(
|
||||||
|
|
|
@ -366,7 +366,6 @@ namespace _zeitbild.repository.resource
|
||||||
"data": {
|
"data": {
|
||||||
"url": dataset_extra_caldav["url"],
|
"url": dataset_extra_caldav["url"],
|
||||||
"read_only": dataset_extra_caldav["read_only"],
|
"read_only": dataset_extra_caldav["read_only"],
|
||||||
"from_fucked_up_wordpress": dataset_extra_caldav["from_fucked_up_wordpress"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -410,7 +409,6 @@ namespace _zeitbild.repository.resource
|
||||||
{
|
{
|
||||||
"url": resource_object.data.url,
|
"url": resource_object.data.url,
|
||||||
"read_only": resource_object.data.read_only,
|
"read_only": resource_object.data.read_only,
|
||||||
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create(
|
const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create(
|
||||||
|
|
|
@ -348,20 +348,11 @@ namespace _zeitbild.service.calendar
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const ics_raw : string = http_response.body.toString();
|
const vcalendar : lib_plankton.ical.type_vcalendar = lib_plankton.ical.ics_decode(
|
||||||
const vcalendar_list : Array<lib_plankton.ical.type_vcalendar> = lib_plankton.ical.ics_decode_multi(
|
http_response.body.toString(),
|
||||||
ics_raw,
|
|
||||||
{
|
{
|
||||||
"ignore_unhandled_instruction_keys": resource_object.data.from_fucked_up_wordpress,
|
|
||||||
"from_fucked_up_wordpress": resource_object.data.from_fucked_up_wordpress,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const vcalendar : lib_plankton.ical.type_vcalendar = {
|
|
||||||
// required
|
|
||||||
"version": vcalendar_list[0].version,
|
|
||||||
"prodid": vcalendar_list[0].prodid,
|
|
||||||
"vevents": vcalendar_list.map(x => x.vevents).reduce((x, y) => x.concat(y), []),
|
|
||||||
};
|
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
vcalendar.vevents
|
vcalendar.vevents
|
||||||
.map(
|
.map(
|
||||||
|
|
|
@ -86,7 +86,6 @@ namespace _zeitbild
|
||||||
data : {
|
data : {
|
||||||
url : string;
|
url : string;
|
||||||
read_only : boolean;
|
read_only : boolean;
|
||||||
from_fucked_up_wordpress : boolean;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue