Compare commits
3 commits
10e3862fc0
...
530c0ce116
Author | SHA1 | Date | |
---|---|---|---|
![]() |
530c0ce116 | ||
![]() |
431f1a1847 | ||
![]() |
f4811a43bf |
8 changed files with 312 additions and 269 deletions
80
lib/plankton/plankton.d.ts
vendored
80
lib/plankton/plankton.d.ts
vendored
|
@ -1,11 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
type int = number;
|
declare type int = number;
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
type float = number;
|
declare type float = number;
|
||||||
declare class Buffer {
|
declare class Buffer {
|
||||||
constructor(x: string, modifier?: string);
|
constructor(x: string, modifier?: string);
|
||||||
toString(modifier?: string): string;
|
toString(modifier?: string): string;
|
||||||
|
@ -19,7 +19,7 @@ declare namespace lib_plankton.base {
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
type type_pseudopointer<type_value> = {
|
declare type type_pseudopointer<type_value> = {
|
||||||
value: type_value;
|
value: type_value;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
@ -868,33 +868,11 @@ 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
|
|
||||||
*/
|
*/
|
||||||
type type_mana_snapshot = {
|
function try_catch_wrap<type_value>(get_value: (() => type_value)): {
|
||||||
timestamp: float;
|
value: (null | type_value);
|
||||||
value: float;
|
error: (null | any);
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* 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.file {
|
declare namespace lib_plankton.file {
|
||||||
/**
|
/**
|
||||||
|
@ -1825,7 +1803,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<Awaited<type_item>>;
|
read(key: any): Promise<type_item>;
|
||||||
search(term: any): Promise<{
|
search(term: any): Promise<{
|
||||||
key: string;
|
key: string;
|
||||||
preview: string;
|
preview: string;
|
||||||
|
@ -3014,7 +2992,7 @@ declare namespace lib_plankton.pit {
|
||||||
/**
|
/**
|
||||||
* @todo test
|
* @todo test
|
||||||
*/
|
*/
|
||||||
function to_datetime(pit: type_pit, options?: {
|
function to_datetime(pit: type_pit, { timezone_shift, }?: {
|
||||||
timezone_shift?: int;
|
timezone_shift?: int;
|
||||||
}): type_datetime;
|
}): type_datetime;
|
||||||
/**
|
/**
|
||||||
|
@ -3064,6 +3042,48 @@ 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.www_form {
|
declare namespace lib_plankton.www_form {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2046,63 +2046,22 @@ 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
|
|
||||||
*/
|
*/
|
||||||
async function rate_limit_check(setup, heft) {
|
function try_catch_wrap(get_value) {
|
||||||
if (heft > setup.capacity) {
|
try {
|
||||||
return Promise.resolve({
|
return {
|
||||||
"granted": false,
|
"value": get_value(),
|
||||||
"seconds": null,
|
"error": null,
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
else {
|
catch (error) {
|
||||||
// get current value
|
return {
|
||||||
const current_timestamp = (Date.now() / 1000);
|
"value": null,
|
||||||
const old_snapshot_raw = (await setup.get_snapshot());
|
"error": error,
|
||||||
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 = {}));
|
||||||
/*
|
/*
|
||||||
|
@ -2225,7 +2184,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 (g && (g = 0, op[0] && (_ = 0)), _) try {
|
while (_) 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]) {
|
||||||
|
@ -3824,7 +3783,7 @@ var lib_plankton;
|
||||||
return {
|
return {
|
||||||
"reports": [
|
"reports": [
|
||||||
{
|
{
|
||||||
"incident": "no valid apaptions",
|
"incident": "no valid adaptions",
|
||||||
"details": {
|
"details": {
|
||||||
"sub_adaptions": sub_adaptions,
|
"sub_adaptions": sub_adaptions,
|
||||||
}
|
}
|
||||||
|
@ -4634,11 +4593,16 @@ 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(
|
||||||
|
"lib_plankton.string.coin",
|
||||||
|
{
|
||||||
"key": key,
|
"key": key,
|
||||||
"regex": regexp_argument.toString(),
|
"regex": regexp_argument.toString(),
|
||||||
"value": value,
|
"value": value,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
*/
|
||||||
str = str.replace(regexp_argument, value);
|
str = str.replace(regexp_argument, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4646,11 +4610,16 @@ 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(
|
||||||
|
"lib_plankton.string.coin",
|
||||||
|
{
|
||||||
"key": key,
|
"key": key,
|
||||||
"regex": regexp_argument.toString(),
|
"regex": regexp_argument.toString(),
|
||||||
"value": value,
|
"value": value,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
*/
|
||||||
str = str.replace(regexp_argument, value);
|
str = str.replace(regexp_argument, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6735,12 +6704,6 @@ var lib_plankton;
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
class class_relation {
|
class class_relation {
|
||||||
/**
|
|
||||||
* @author fenris
|
|
||||||
*/
|
|
||||||
check(value, reference) {
|
|
||||||
return this.predicate(value, reference);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
|
@ -6750,6 +6713,12 @@ var lib_plankton;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @author fenris
|
||||||
|
*/
|
||||||
|
check(value, reference) {
|
||||||
|
return this.predicate(value, reference);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @author fenris
|
* @author fenris
|
||||||
*/
|
*/
|
||||||
|
@ -8421,18 +8390,15 @@ var lib_plankton;
|
||||||
/**
|
/**
|
||||||
* @todo test
|
* @todo test
|
||||||
*/
|
*/
|
||||||
function to_datetime(pit, options = {}) {
|
function to_datetime(pit, { timezone_shift = 0, } = {}) {
|
||||||
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 + ((options.timezone_shift * (60 * 60)) * 1000)),
|
(x) => (x + ((timezone_shift * (60 * 60)) * 1000)),
|
||||||
(x) => new Date(x),
|
(x) => new Date(x),
|
||||||
x => x.toISOString(),
|
x => x.toISOString(),
|
||||||
x => ({
|
x => ({
|
||||||
"timezone_shift": options.timezone_shift,
|
"timezone_shift": 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)),
|
||||||
|
@ -8729,6 +8695,182 @@ 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 = {}));
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
},
|
},
|
||||||
"tree": {
|
"tree": {
|
||||||
"common.timezone_shift": "Zeitzonen-Verschiebung",
|
"common.timezone_shift": "Zeitzonen-Verschiebung",
|
||||||
|
"common.timezone_indicator": "ZZ:",
|
||||||
"common.date": "Datum",
|
"common.date": "Datum",
|
||||||
"common.time": "Uhrzeit",
|
"common.time": "Uhrzeit",
|
||||||
"common.weekday.monday": "Mo",
|
"common.weekday.monday": "Mo",
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
"access_level.admin": "voll",
|
"access_level.admin": "voll",
|
||||||
"event.event": "Termin",
|
"event.event": "Termin",
|
||||||
"event.name": "Name",
|
"event.name": "Name",
|
||||||
|
"event.when": "Zeit",
|
||||||
"event.begin": "Anfang",
|
"event.begin": "Anfang",
|
||||||
"event.end": "Ende",
|
"event.end": "Ende",
|
||||||
"event.location": "Ort",
|
"event.location": "Ort",
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
},
|
},
|
||||||
"tree": {
|
"tree": {
|
||||||
"common.timezone_shift": "Timezone shift",
|
"common.timezone_shift": "Timezone shift",
|
||||||
|
"common.timezone_indicator": "TZ:",
|
||||||
"common.date": "date",
|
"common.date": "date",
|
||||||
"common.time": "time",
|
"common.time": "time",
|
||||||
"common.weekday.monday": "Mon",
|
"common.weekday.monday": "Mon",
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
"access_level.admin": "full",
|
"access_level.admin": "full",
|
||||||
"event.event": "event",
|
"event.event": "event",
|
||||||
"event.name": "name",
|
"event.name": "name",
|
||||||
|
"event.when": "time",
|
||||||
"event.begin": "begin",
|
"event.begin": "begin",
|
||||||
"event.end": "end",
|
"event.end": "end",
|
||||||
"event.location": "location",
|
"event.location": "location",
|
||||||
|
|
|
@ -75,106 +75,6 @@ namespace _zeitbild.frontend_web.helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo timezone
|
|
||||||
*/
|
|
||||||
export function date_format(
|
|
||||||
date : lib_plankton.pit.type_date
|
|
||||||
) : string
|
|
||||||
{
|
|
||||||
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"),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo timezone
|
|
||||||
*/
|
|
||||||
export function time_format(
|
|
||||||
time : lib_plankton.pit.type_time
|
|
||||||
) : string
|
|
||||||
{
|
|
||||||
return lib_plankton.string.coin(
|
|
||||||
"{{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"),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo timezone
|
|
||||||
*/
|
|
||||||
export function datetime_format(
|
|
||||||
datetime : (null | lib_plankton.pit.type_datetime)
|
|
||||||
) : string
|
|
||||||
{
|
|
||||||
if (datetime === null) {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return lib_plankton.string.coin(
|
|
||||||
"{{date}}{{macro_time}}",
|
|
||||||
{
|
|
||||||
"date": date_format(datetime.date),
|
|
||||||
"macro_time": (
|
|
||||||
(datetime.time === null)
|
|
||||||
?
|
|
||||||
""
|
|
||||||
:
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
",{{time}}",
|
|
||||||
{
|
|
||||||
"time": time_format(datetime.time),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
export function timespan_format(
|
|
||||||
from : lib_plankton.pit.type_datetime,
|
|
||||||
to : (null | lib_plankton.pit.type_datetime)
|
|
||||||
) : string
|
|
||||||
{
|
|
||||||
let result : string = "";
|
|
||||||
result += datetime_format(from);
|
|
||||||
if (to === null) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result += " - ";
|
|
||||||
if (
|
|
||||||
(from.date.year === to.date.year)
|
|
||||||
&&
|
|
||||||
(from.date.month === to.date.month)
|
|
||||||
&&
|
|
||||||
(from.date.day === to.date.day)
|
|
||||||
) {
|
|
||||||
// only time
|
|
||||||
result += time_format(to.time);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result += datetime_format(to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function input_access_level(
|
export function input_access_level(
|
||||||
|
|
|
@ -144,7 +144,15 @@ namespace _zeitbild.frontend_web.widgets.listview
|
||||||
{
|
{
|
||||||
"name_value": entry.event_object.name,
|
"name_value": entry.event_object.name,
|
||||||
"calendar_value": entry.calendar_name,
|
"calendar_value": entry.calendar_name,
|
||||||
"when_value": _zeitbild.frontend_web.helpers.timespan_format(entry.event_object.begin, entry.event_object.end),
|
"when_value": lib_plankton.pit.timespan_format(
|
||||||
|
entry.event_object.begin,
|
||||||
|
entry.event_object.end,
|
||||||
|
{
|
||||||
|
"timezone_indicator": lib_plankton.translate.get("common.timezone_indicator"),
|
||||||
|
"adjust_to_ce": true,
|
||||||
|
"show_timezone": false,
|
||||||
|
}
|
||||||
|
),
|
||||||
"location_label": lib_plankton.translate.get("event.location"),
|
"location_label": lib_plankton.translate.get("event.location"),
|
||||||
"location_extra_classes": (
|
"location_extra_classes": (
|
||||||
(entry.event_object.location === null)
|
(entry.event_object.location === null)
|
||||||
|
|
|
@ -127,65 +127,16 @@ namespace _zeitbild.frontend_web.widgets.weekview
|
||||||
lib_plankton.string.coin(
|
lib_plankton.string.coin(
|
||||||
"{{label}}: {{value}}\n",
|
"{{label}}: {{value}}\n",
|
||||||
{
|
{
|
||||||
"label": lib_plankton.translate.get("event.begin"),
|
"label": lib_plankton.translate.get("event.when"),
|
||||||
"value": lib_plankton.string.coin(
|
"value": lib_plankton.pit.timespan_format(
|
||||||
"{{hour}}:{{minute}}",
|
event_object.begin,
|
||||||
|
event_object.end,
|
||||||
{
|
{
|
||||||
"hour": event_object.begin.time.hour.toFixed(0).padStart(2, "0"),
|
"timezone_indicator": lib_plankton.translate.get("common.timezone_indicator"),
|
||||||
"minute": event_object.begin.time.minute.toFixed(0).padStart(2, "0"),
|
"adjust_to_ce": true,
|
||||||
|
"show_timezone": true,
|
||||||
|
"omit_date": true,
|
||||||
}
|
}
|
||||||
), // TODO: outsource
|
|
||||||
}
|
|
||||||
)
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
+
|
|
||||||
(
|
|
||||||
(event_object.end !== null)
|
|
||||||
?
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"{{label}}: {{value}}\n",
|
|
||||||
{
|
|
||||||
"label": lib_plankton.translate.get("event.end"),
|
|
||||||
"value": (
|
|
||||||
[
|
|
||||||
(
|
|
||||||
(
|
|
||||||
(event_object.end.date.year !== event_object.begin.date.year)
|
|
||||||
||
|
|
||||||
(event_object.end.date.month !== event_object.begin.date.month)
|
|
||||||
||
|
|
||||||
(event_object.end.date.day !== event_object.begin.date.day)
|
|
||||||
)
|
|
||||||
?
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"{{year}}-{{month}}-{{day}}",
|
|
||||||
{
|
|
||||||
"year": event_object.end.date.year.toFixed(0).padStart(4, "0"),
|
|
||||||
"month": event_object.end.date.month.toFixed(0).padStart(2, "0"),
|
|
||||||
"day": event_object.end.date.day.toFixed(0).padStart(2, "0"),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
:
|
|
||||||
null
|
|
||||||
),
|
|
||||||
(
|
|
||||||
(event_object.end.time !== null)
|
|
||||||
?
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"{{hour}}:{{minute}}",
|
|
||||||
{
|
|
||||||
"hour": event_object.end.time.hour.toFixed(0).padStart(2, "0"),
|
|
||||||
"minute": event_object.end.time.minute.toFixed(0).padStart(2, "0"),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
:
|
|
||||||
null
|
|
||||||
),
|
|
||||||
]
|
|
||||||
.filter(x => (x !== null))
|
|
||||||
.join(",")
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -438,7 +389,24 @@ namespace _zeitbild.frontend_web.widgets.weekview
|
||||||
.forEach(
|
.forEach(
|
||||||
(entry) => {
|
(entry) => {
|
||||||
const distance_seconds : int = (
|
const distance_seconds : int = (
|
||||||
lib_plankton.pit.from_datetime(entry.event_object.begin)
|
lib_plankton.pit.from_datetime(
|
||||||
|
/**
|
||||||
|
* so that events without a start time will be put in the correct box
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
"timezone_shift": entry.event_object.begin.timezone_shift,
|
||||||
|
"date": entry.event_object.begin.date,
|
||||||
|
"time": (
|
||||||
|
entry.event_object.begin.time
|
||||||
|
??
|
||||||
|
{
|
||||||
|
"hour": 12,
|
||||||
|
"minute": 0,
|
||||||
|
"second": 0
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
-
|
-
|
||||||
from_pit
|
from_pit
|
||||||
);
|
);
|
||||||
|
@ -626,7 +594,7 @@ namespace _zeitbild.frontend_web.widgets.weekview
|
||||||
"title": lib_plankton.call.convey(
|
"title": lib_plankton.call.convey(
|
||||||
cell.pit,
|
cell.pit,
|
||||||
[
|
[
|
||||||
lib_plankton.pit.to_datetime,
|
lib_plankton.pit.to_datetime_ce,
|
||||||
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
|
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
|
||||||
"{{year}}-{{month}}-{{day}}",
|
"{{year}}-{{month}}-{{day}}",
|
||||||
{
|
{
|
||||||
|
@ -640,7 +608,7 @@ namespace _zeitbild.frontend_web.widgets.weekview
|
||||||
"day": lib_plankton.call.convey(
|
"day": lib_plankton.call.convey(
|
||||||
cell.pit,
|
cell.pit,
|
||||||
[
|
[
|
||||||
lib_plankton.pit.to_datetime,
|
lib_plankton.pit.to_datetime_ce,
|
||||||
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
|
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
|
||||||
"{{day}}",
|
"{{day}}",
|
||||||
{
|
{
|
||||||
|
@ -654,7 +622,7 @@ namespace _zeitbild.frontend_web.widgets.weekview
|
||||||
"rel": lib_plankton.call.convey(
|
"rel": lib_plankton.call.convey(
|
||||||
cell.pit,
|
cell.pit,
|
||||||
[
|
[
|
||||||
lib_plankton.pit.to_datetime,
|
lib_plankton.pit.to_datetime_ce,
|
||||||
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
|
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
|
||||||
"{{year}}-{{month}}-{{day}}",
|
"{{year}}-{{month}}-{{day}}",
|
||||||
{
|
{
|
||||||
|
|
1
todo.md
1
todo.md
|
@ -1 +1,2 @@
|
||||||
- unterschiedliche Ansichten für Betrachten und Bearbeiten von Terminen und Kalendern
|
- unterschiedliche Ansichten für Betrachten und Bearbeiten von Terminen und Kalendern
|
||||||
|
- zu verwendende Zeitzone nicht fest auf mitteleuropäische setzen
|
||||||
|
|
Loading…
Add table
Reference in a new issue