PronounsPage/server/calendar.ts

103 lines
3.3 KiB
TypeScript

import './setup.ts';
import fs from 'fs';
import path from 'path';
import Pageres from 'pageres';
import type { Config } from '../locale/config.ts';
import dbConnection from './db.ts';
import localeDescriptions from '~/locale/locales.ts';
import { loadConfig } from '~/server/data.ts';
import { buildCalendar } from '~/src/calendar/calendar.ts';
import { getLocaleUrls } from '~/src/domain.ts';
const __dirname = new URL('.', import.meta.url).pathname;
const force = process.argv[2] === '-f' || process.argv[2] === '--force';
const shoot = async (url: string, filename: string): Promise<void> => {
const pr = new Pageres({
delay: 3,
scale: 2,
launchOptions: {
headless: 'new',
},
});
pr.source(url, ['1500x300']);
for (const buffer of await pr.run()) {
fs.mkdirSync(path.dirname(filename), { recursive: true });
console.log(filename);
fs.writeFileSync(filename, buffer);
}
};
const dumpNameDays = async (config: Config): Promise<void> => {
if (!config.names || !config.names.enabled || !config.names.namedays) {
return;
}
const db = await dbConnection();
const names = await db.all(`
SELECT n.name, n.namedays
FROM names n
WHERE n.namedays IS NOT NULL
AND approved = 1
AND deleted = 0
`);
const output: Record<string, string[]> = {};
for (const { name, namedays } of names) {
output[name] = namedays.split('|');
}
fs.writeFileSync(`${__dirname}/../locale/${config.locale}/names/namedays.json`, JSON.stringify(output));
};
const run = async (config: Config, baseUrl: string): Promise<void> => {
if (!config.calendar?.enabled) {
return;
}
const dir = `${__dirname}/../calendar/${config.locale}`;
const prevPath = `${dir}/generated.json`;
const prev = fs.existsSync(prevPath) ? JSON.parse(fs.readFileSync(prevPath, 'utf-8')) : {};
const localEvents = (await import(`../locale/${config.locale}/calendar/events.ts`)).default;
const current = await buildCalendar(localEvents, process.env.NUXT_PUBLIC_BASE_URL!).buildSummary();
const changedYears = new Set();
for (const day of Object.keys(current)) {
const year = day.substring(0, 4);
if (current[day] !== prev[day] || !fs.existsSync(`${dir}/${day}.png`) || force) {
await shoot(`${baseUrl}/${config.calendar.route}/${day}?layout=basic`, `${dir}/${day}.png`);
changedYears.add(year);
}
if (!fs.existsSync(`${dir}/${year}-overview.png`) || !fs.existsSync(`${dir}/${year}-labels.png`) || force) {
changedYears.add(year);
}
}
for (const year of changedYears) {
await shoot(
`${baseUrl}/${config.calendar.route}/${year}?layout=basic`,
`${dir}/${year}-overview.png`,
);
await shoot(
`${baseUrl}/${config.calendar.route}/${year}?layout=basic&labels=true`,
`${dir}/${year}-labels.png`,
);
}
fs.writeFileSync(prevPath, JSON.stringify(current, null, 4));
await dumpNameDays(config);
};
(async () => {
const localeUrls = getLocaleUrls(process.env.NUXT_PUBLIC_DOMAIN_BASE);
for (const localeDescription of localeDescriptions) {
const config = await loadConfig(localeDescription.code);
await run(config, localeUrls[config.locale]);
}
})();