590 lines
10 KiB
TypeScript
590 lines
10 KiB
TypeScript
|
|
/**
|
|
*/
|
|
namespace _zeitbild.frontend.helpers
|
|
{
|
|
|
|
/**
|
|
*/
|
|
var _template_cache : Record<string, string> = {};
|
|
|
|
|
|
/**
|
|
* @todo caching
|
|
*/
|
|
export async function template_coin(
|
|
name : string,
|
|
data : Record<string, string>
|
|
) : Promise<string>
|
|
{
|
|
let content : string;
|
|
if (! (name in _template_cache)) {
|
|
content = (
|
|
(
|
|
await lib_plankton.file.read(
|
|
lib_plankton.string.coin(
|
|
"templates/{{name}}.html.tpl",
|
|
{
|
|
"name": name,
|
|
}
|
|
)
|
|
)
|
|
)
|
|
.toString()
|
|
);
|
|
_template_cache[name] = content;
|
|
}
|
|
else {
|
|
content = _template_cache[name];
|
|
}
|
|
return Promise.resolve<string>(
|
|
lib_plankton.string.coin(
|
|
content,
|
|
data
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* @todo outsource
|
|
*/
|
|
export async function promise_row<type_result>(
|
|
members : Array<
|
|
() => Promise<type_result>
|
|
>
|
|
) : Promise<
|
|
Array<
|
|
type_result
|
|
>
|
|
>
|
|
{
|
|
let results : Array<type_result> = [];
|
|
for await (const member of members) {
|
|
results.push(await member());
|
|
}
|
|
return Promise.resolve<Array<type_result>>(results);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function date_object_get_week_of_year(
|
|
date : Date
|
|
) : int
|
|
{
|
|
let date_ : Date = new Date(date.getTime());
|
|
date_.setHours(0, 0, 0, 0);
|
|
// Thursday in current week decides the year.
|
|
date_.setDate(date_.getDate() + 3 - (date_.getDay() + 6) % 7);
|
|
// January 4 is always in week 1.
|
|
let week1 : Date = new Date(date_.getFullYear(), 0, 4);
|
|
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
|
|
return (
|
|
1
|
|
+
|
|
Math.round(
|
|
(
|
|
((date_.getTime() - week1.getTime()) / 86400000)
|
|
-
|
|
3
|
|
+
|
|
(week1.getDay() + 6) % 7
|
|
)
|
|
/
|
|
7
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* @todo unite with type_datetimeobject?
|
|
*/
|
|
export type type_datetime = {
|
|
timezone_shift : int;
|
|
date : type_date;
|
|
time : (
|
|
null
|
|
|
|
|
type_time
|
|
);
|
|
};
|
|
|
|
|
|
/**
|
|
* @todo timezone_shift
|
|
*/
|
|
function datetime_from_date_object(
|
|
date : Date,
|
|
options : {
|
|
timezone_shift ?: int;
|
|
} = {}
|
|
) : type_datetime
|
|
{
|
|
options = Object.assign(
|
|
{
|
|
"timezone_shift": 0,
|
|
},
|
|
options
|
|
);
|
|
const date_ : Date = lib_plankton.call.convey(
|
|
date,
|
|
[
|
|
(x : Date) => x.getTime(),
|
|
(x : int) => (x + (((options.timezone_shift as int) * (60 * 60)) * 1000)),
|
|
(x : int) => new Date(x),
|
|
]
|
|
);
|
|
const iso_string : string = date_.toISOString();
|
|
return {
|
|
"timezone_shift": (options.timezone_shift as int),
|
|
"date": {
|
|
"year": parseInt(iso_string.slice(0, 4)),
|
|
"month": parseInt(iso_string.slice(5, 7)),
|
|
"day": parseInt(iso_string.slice(8, 10)),
|
|
},
|
|
"time": {
|
|
"hour": parseInt(iso_string.slice(11, 13)),
|
|
"minute": parseInt(iso_string.slice(14, 16)),
|
|
"second": parseInt(iso_string.slice(17, 19)),
|
|
},
|
|
};
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @todo negative shift?
|
|
*/
|
|
function datetime_to_date_object(
|
|
datetime : type_datetime
|
|
) : Date
|
|
{
|
|
const iso_string : string = lib_plankton.string.coin(
|
|
"{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.000+{{shift}}",
|
|
{
|
|
"year": datetime.date.year.toFixed(0).padStart(4, "0"),
|
|
"month": datetime.date.month.toFixed(0).padStart(2, "0"),
|
|
"day": datetime.date.day.toFixed(0).padStart(2, "0"),
|
|
"hour": ((datetime.time !== null) ? datetime.time.hour : 0).toFixed(0).padStart(2, "0"),
|
|
"minute": ((datetime.time !== null) ? datetime.time.minute : 0).toFixed(0).padStart(2, "0"),
|
|
"second": ((datetime.time !== null) ? datetime.time.second : 0).toFixed(0).padStart(2, "0"),
|
|
"shift": (datetime.timezone_shift.toFixed(0).padStart(2, "0") + ":00"),
|
|
}
|
|
);
|
|
return (new Date(iso_string));
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export type type_pit = int;
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_to_date_object(
|
|
pit : type_pit
|
|
) : Date
|
|
{
|
|
return (new Date(pit * 1000));
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_from_date_object(
|
|
date_object : Date
|
|
) : type_pit
|
|
{
|
|
return Math.round(date_object.getTime() / 1000);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_now(
|
|
) : type_pit
|
|
{
|
|
return pit_from_date_object(new Date(Date.now()));
|
|
}
|
|
|
|
|
|
/**
|
|
* @todo timezone
|
|
*/
|
|
export function pit_to_datetime(
|
|
pit : type_pit,
|
|
options : {
|
|
timezone_shift ?: int
|
|
} = {}
|
|
) : type_datetime
|
|
{
|
|
options = Object.assign(
|
|
{
|
|
"timezone_shift": 0,
|
|
},
|
|
options
|
|
);
|
|
const date_object : Date = pit_to_date_object(pit);
|
|
return datetime_from_date_object(
|
|
date_object,
|
|
{
|
|
"timezone_shift": (options.timezone_shift as int),
|
|
}
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_from_datetime(
|
|
datetime : type_datetime
|
|
) : type_pit
|
|
{
|
|
return lib_plankton.call.convey(
|
|
datetime,
|
|
[
|
|
datetime_to_date_object,
|
|
pit_from_date_object,
|
|
]
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_is_before(
|
|
pit : type_pit,
|
|
reference : type_pit
|
|
) : boolean
|
|
{
|
|
return (pit < reference);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_is_after(
|
|
pit : type_pit,
|
|
reference : type_pit
|
|
) : boolean
|
|
{
|
|
return (pit > reference);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_is_between(
|
|
pit : type_pit,
|
|
reference_left : type_pit,
|
|
reference_right : type_pit
|
|
) : boolean
|
|
{
|
|
return (
|
|
pit_is_after(pit, reference_left)
|
|
&&
|
|
pit_is_before(pit, reference_right)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_shift_hour(
|
|
pit : type_pit,
|
|
increment : int
|
|
) : type_pit
|
|
{
|
|
return (pit + (60 * 60 * increment));
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_shift_day(
|
|
pit : type_pit,
|
|
increment : int
|
|
) : type_pit
|
|
{
|
|
return (pit + (60 * 60 * 24 * increment));
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_shift_week(
|
|
pit : type_pit,
|
|
increment : int
|
|
) : type_pit
|
|
{
|
|
return (pit + (60 * 60 * 24 * 7 * increment));
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_shift_year(
|
|
pit : type_pit,
|
|
increment : int
|
|
) : type_pit
|
|
{
|
|
return (pit + (60 * 60 * 24 * 365 * increment));
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_trunc_minute(
|
|
pit : type_pit
|
|
) : type_pit
|
|
{
|
|
const datetime_input : type_datetime = pit_to_datetime(pit);
|
|
const datetime_output : type_datetime = {
|
|
"timezone_shift": 0,
|
|
"date": {
|
|
"year": datetime_input.date.year,
|
|
"month": datetime_input.date.month,
|
|
"day": datetime_input.date.day,
|
|
},
|
|
"time": {
|
|
"hour": (
|
|
(datetime_input.time === null)
|
|
?
|
|
0
|
|
:
|
|
datetime_input.time.hour
|
|
),
|
|
"minute": (
|
|
(datetime_input.time === null)
|
|
?
|
|
0
|
|
:
|
|
datetime_input.time.minute
|
|
),
|
|
"second": 0,
|
|
},
|
|
};
|
|
return pit_from_datetime(datetime_output);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_trunc_hour(
|
|
pit : type_pit
|
|
) : type_pit
|
|
{
|
|
const datetime_input : type_datetime = pit_to_datetime(pit);
|
|
const datetime_output : type_datetime = {
|
|
"timezone_shift": 0,
|
|
"date": {
|
|
"year": datetime_input.date.year,
|
|
"month": datetime_input.date.month,
|
|
"day": datetime_input.date.day,
|
|
},
|
|
"time": {
|
|
"hour": (
|
|
(datetime_input.time === null)
|
|
?
|
|
0
|
|
:
|
|
datetime_input.time.hour
|
|
),
|
|
"minute": 0,
|
|
"second": 0,
|
|
},
|
|
};
|
|
return pit_from_datetime(datetime_output);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_trunc_day(
|
|
pit : type_pit
|
|
) : type_pit
|
|
{
|
|
const datetime_input : type_datetime = pit_to_datetime(pit);
|
|
const datetime_output : type_datetime = {
|
|
"timezone_shift": 0,
|
|
"date": {
|
|
"year": datetime_input.date.year,
|
|
"month": datetime_input.date.month,
|
|
"day": datetime_input.date.day,
|
|
},
|
|
"time": {
|
|
"hour": 0,
|
|
"minute": 0,
|
|
"second": 0,
|
|
},
|
|
};
|
|
return pit_from_datetime(datetime_output);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
export function pit_trunc_week(
|
|
pit : type_pit
|
|
) : type_pit
|
|
{
|
|
const date_object : Date = pit_to_date_object(pit);
|
|
return lib_plankton.call.convey(
|
|
date_object.getDay(),
|
|
[
|
|
(x : int) => ((x === 0) ? 7 : x),
|
|
(x : int) => (x - 1),
|
|
(x : int) => pit_shift_day(pit, (-x)),
|
|
pit_trunc_day
|
|
]
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_trunc_month(
|
|
pit : type_pit
|
|
) : type_pit
|
|
{
|
|
const datetime_input : type_datetime = pit_to_datetime(pit);
|
|
const datetime_output : type_datetime = {
|
|
"timezone_shift": 0,
|
|
"date": {
|
|
"year": datetime_input.date.year,
|
|
"month": datetime_input.date.month,
|
|
"day": 1,
|
|
},
|
|
"time": {
|
|
"hour": 0,
|
|
"minute": 0,
|
|
"second": 0,
|
|
},
|
|
};
|
|
return pit_from_datetime(datetime_output);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
function pit_trunc_year(
|
|
pit : type_pit
|
|
) : type_pit
|
|
{
|
|
const datetime_input : type_datetime = pit_to_datetime(pit);
|
|
const datetime_output : type_datetime = {
|
|
"timezone_shift": 0,
|
|
"date": {
|
|
"year": datetime_input.date.year,
|
|
"month": 1,
|
|
"day": 1,
|
|
},
|
|
"time": {
|
|
"hour": 0,
|
|
"minute": 0,
|
|
"second": 0,
|
|
},
|
|
};
|
|
return pit_from_datetime(datetime_output);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param year year according to specified timezone shift
|
|
* @param week week according to specified timezone shift
|
|
* @return the begin of the week (monday, 00:00)
|
|
*/
|
|
export function pit_from_year_and_week(
|
|
year : int,
|
|
week : int,
|
|
options : {
|
|
timezone_shift ?: int;
|
|
} = {}
|
|
) : type_pit
|
|
{
|
|
options = Object.assign(
|
|
{
|
|
"timezone_shift": 0,
|
|
},
|
|
options
|
|
);
|
|
return lib_plankton.call.convey(
|
|
{
|
|
"timezone_shift": (options.timezone_shift as int),
|
|
"date": {
|
|
"year": year,
|
|
"month": 1,
|
|
"day": 1,
|
|
},
|
|
"time": {
|
|
"hour": 0,
|
|
"minute": 0,
|
|
"second": 0
|
|
}
|
|
},
|
|
[
|
|
pit_from_datetime,
|
|
(x : type_pit) => pit_shift_week(x, (week - 1)),
|
|
pit_trunc_week,
|
|
]
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* @todo timezone
|
|
*/
|
|
function ical_datetime_to_own_datetime(
|
|
ical_datetime : lib_plankton.ical.type_datetime
|
|
) : type_datetime
|
|
{
|
|
return {
|
|
"timezone_shift": 0,
|
|
"date": {
|
|
"year": ical_datetime.date.year,
|
|
"month": ical_datetime.date.month,
|
|
"day": ical_datetime.date.day,
|
|
},
|
|
"time": (
|
|
(ical_datetime.time === null)
|
|
?
|
|
null
|
|
:
|
|
{
|
|
"hour": ical_datetime.time.hour,
|
|
"minute": ical_datetime.time.minute,
|
|
"second": ical_datetime.time.second,
|
|
}
|
|
)
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
* @todo timezone
|
|
*/
|
|
export function ical_dt_to_own_datetime(
|
|
ical_dt: lib_plankton.ical.type_dt
|
|
) : type_datetime
|
|
{
|
|
return {
|
|
"timezone_shift": 0,
|
|
"date": ical_dt.value.date,
|
|
"time": (
|
|
(ical_dt.value.time === null)
|
|
?
|
|
null
|
|
:
|
|
{
|
|
"hour": ical_dt.value.time.hour,
|
|
"minute": ical_dt.value.time.minute,
|
|
"second": ical_dt.value.time.second,
|
|
}
|
|
)
|
|
};
|
|
}
|
|
|
|
}
|