This commit is contained in:
Matthias Hochmeister
2026-03-16 14:41:08 +01:00
parent 5f329bb5c1
commit 215528a521
46 changed files with 462 additions and 251 deletions

View File

@@ -78,13 +78,23 @@ function formatIcalDate(date: Date): string {
/** Fold long iCal lines at 75 octets (RFC 5545 §3.1) */
function icalFold(line: string): string {
if (line.length <= 75) return line;
if (Buffer.byteLength(line, 'utf-8') <= 75) return line;
let folded = '';
while (line.length > 75) {
folded += line.slice(0, 75) + '\r\n ';
line = line.slice(75);
let currentLine = '';
let currentBytes = 0;
for (const char of line) {
const charBytes = Buffer.byteLength(char, 'utf-8');
if (currentBytes + charBytes > 75) {
folded += currentLine + '\r\n ';
currentLine = char;
currentBytes = 1 + charBytes; // continuation line leading space = 1 byte
} else {
currentLine += char;
currentBytes += charBytes;
}
}
folded += line;
folded += currentLine;
return folded;
}
@@ -241,7 +251,7 @@ class EventsService {
v.alle_gruppen, v.zielgruppen, v.abgesagt, v.anmeldung_erforderlich
FROM veranstaltungen v
LEFT JOIN veranstaltung_kategorien k ON k.id = v.kategorie_id
WHERE (v.datum_von BETWEEN $1 AND $2 OR v.datum_bis BETWEEN $1 AND $2)
WHERE (v.datum_von BETWEEN $1 AND $2 OR v.datum_bis BETWEEN $1 AND $2 OR (v.datum_von <= $1 AND v.datum_bis >= $2))
AND (
v.alle_gruppen = TRUE
OR v.zielgruppen && $3
@@ -388,6 +398,7 @@ class EventsService {
const effectiveLimit = limitDate < maxDate ? limitDate : maxDate;
let current = new Date(startDate);
const originalDay = startDate.getDate();
while (dates.length < 100) {
// Advance to next occurrence
@@ -400,10 +411,15 @@ class EventsService {
current = new Date(current);
current.setDate(current.getDate() + 14);
break;
case 'monatlich_datum':
case 'monatlich_datum': {
current = new Date(current);
current.setMonth(current.getMonth() + 1);
const targetMonth = current.getMonth() + 1;
current.setDate(1);
current.setMonth(targetMonth);
const lastDay = new Date(current.getFullYear(), current.getMonth() + 1, 0).getDate();
current.setDate(Math.min(originalDay, lastDay));
break;
}
case 'monatlich_erster_wochentag': {
const targetWeekday = config.wochentag ?? 0; // 0=Mon
current = new Date(current);