mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-24 05:05:20 -04:00

the #shared alias used by Nuxt cannot be easily disabled and to prevent breackage with jiti, we make use of it
110 lines
3.8 KiB
TypeScript
110 lines
3.8 KiB
TypeScript
import './setup.ts';
|
||
|
||
import fs from 'fs';
|
||
|
||
import * as Sentry from '@sentry/node';
|
||
import { createEvents } from 'ics';
|
||
import { JSDOM } from 'jsdom';
|
||
|
||
import mailer from './mailer.ts';
|
||
|
||
import { Day } from '#shared/calendar/helpers.ts';
|
||
import type { MiastamaszerujaceEvent } from '#shared/calendar/helpers.ts';
|
||
import { loadTranslator } from '~~/server/data.ts';
|
||
|
||
const __dirname = new URL('.', import.meta.url).pathname;
|
||
|
||
const year = Day.today().year;
|
||
|
||
const fetchEvents = async (): Promise<MiastamaszerujaceEvent[]> => {
|
||
const events: MiastamaszerujaceEvent[] = [];
|
||
|
||
// issue with third-party cert: Verification error: unable to verify the first certificate
|
||
// browser and curl accepts the certificate, but node seems more picky
|
||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||
const html = await (await fetch('https://miastamaszerujace.pl/')).text();
|
||
const dom = new JSDOM(html
|
||
// manual fixes for irregular HTML
|
||
.replace(new RegExp('ref=newsfeed</a><br /><b>', 'g'), '</a></p><p><b>')
|
||
.replace(new RegExp('<span style="font-weight: 400;">(.*?)</span>', 'g'), '$1'));
|
||
const eventNodes = dom.window.document.querySelectorAll('[data-id="d4c3075"] p, [data-id="9cc25f4"] p');
|
||
for (const p of eventNodes) {
|
||
if (p.textContent!.includes('Daty kolejnych') ||
|
||
p.textContent!.includes('Marsz organizowany przez grupę współpracującą') ||
|
||
p.textContent!.includes('Opublikowane do tej pory')
|
||
) {
|
||
continue;
|
||
}
|
||
|
||
const [day, month] = p.querySelector('b,strong')!.textContent!.trim().split('/');
|
||
const date = new Day(year, parseInt(month), parseInt(day));
|
||
|
||
const name = [...p.childNodes]
|
||
.filter((c) => c.nodeType === 3 /* text node */ || c.nodeName === 'A')
|
||
.map((c) => c.textContent!.trim())
|
||
.filter((t) => !!t)
|
||
.join(' ')
|
||
.replace(/^– /, '')
|
||
;
|
||
|
||
let link = null;
|
||
try {
|
||
link = new URL(p.querySelector('a')!.getAttribute('href')!);
|
||
link.hash = '';
|
||
link.search = '';
|
||
} catch (e) { void 0; }
|
||
|
||
events.push({
|
||
name,
|
||
date,
|
||
link: link ? link.toString() : null,
|
||
});
|
||
}
|
||
|
||
return events;
|
||
};
|
||
|
||
(async (): Promise<void> => {
|
||
const events = await fetchEvents();
|
||
console.log(events);
|
||
|
||
const dir = `${__dirname}/../calendar/pl`;
|
||
const path = `${dir}/miastamaszerujace-${year}.json`;
|
||
const previous = fs.existsSync(path) ? JSON.parse(fs.readFileSync(path).toString('utf-8')) : [];
|
||
if (JSON.stringify(events) !== JSON.stringify(previous)) {
|
||
console.log('wykryto zmiany, wysyłam maila');
|
||
await mailer('kontakt@zaimki.pl', 'miastamaszerujace', await loadTranslator('_'), {
|
||
before: JSON.stringify(previous, null, 4),
|
||
after: JSON.stringify(events, null, 4),
|
||
maxwidth: '100%',
|
||
});
|
||
}
|
||
if (previous.length > events.length) {
|
||
console.error('stopping execution, number of events decreased');
|
||
return;
|
||
}
|
||
console.log(`Saving to ${path}`);
|
||
fs.writeFileSync(path, JSON.stringify(events, null, 4));
|
||
|
||
createEvents(
|
||
events.map((e, i) => {
|
||
return {
|
||
title: e.name,
|
||
start: [e.date.year, e.date.month, e.date.day],
|
||
end: [e.date.year, e.date.month, e.date.day],
|
||
calName: `Marsze Równości ${year}`,
|
||
sequence: i,
|
||
};
|
||
}),
|
||
(error, value) => {
|
||
if (error) {
|
||
Sentry.captureException(error);
|
||
return;
|
||
}
|
||
|
||
console.log(`Saving to ${dir}/miastamaszerujace.ics`);
|
||
fs.writeFileSync(`${dir}/miastamaszerujace.ics`, value);
|
||
},
|
||
);
|
||
})();
|