This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Zaimki/server/routes/calendar.js

146 lines
4.0 KiB
JavaScript

import { Router } from 'express';
import {handleErrorAsync, clearLinkedText} from '../../src/helpers';
import { createEvents } from 'ics';
import { calendar } from '../../src/calendar/calendar';
import {loadSuml} from "../loader";
import { Day } from '../../src/calendar/helpers';
// TODO caching? // import { caches } from "../../src/cache";
const translations = loadSuml('translations');
const renderEvents = (yearEvents, res) => {
const events = [];
let i = 1;
for (let year in yearEvents) {
if (!yearEvents.hasOwnProperty(year)) { continue; }
for (let event of yearEvents[year]) {
if (!event) { continue; }
const ics = event.toIcs(year, translations, clearLinkedText, i);
if (ics !== null) {
events.push(ics);
}
}
i++;
}
if (events.length === 0) {
return res.status(404).json({error: 'Not found'});
}
createEvents(
events,
(error, value) => {
if (error) {
console.error(error);
return res.status(500).json({error: 'Unexpected server error'});
}
res.header('Content-type', 'text/calendar');
res.send(value);
}
);
}
const getEventName = (name) => {
name = translations.calendar.events[name] || name;
name = name.replace(/{.*?=(.*?)}/g, '$1')
return name;
}
const buildMessage = (events, locale, day, link) => {
if (events.length === 0) {
return null;
}
let message = `[${locale.name}] ${day.toString()}\n\n${translations.calendar.banner}:\n`;
for (let event of events) {
message += ` - ${event}\n`;
}
message += `\n${link}`;
return message;
}
const eventsSummary = (day, locale) => {
const eventsRaw = calendar.getCurrentYear().eventsByDate[day.toString()];
const link = `${locale.url}/${encodeURIComponent(config.calendar.route)}/${day}`;
const image = `${locale.url}/calendar/${day}.png`;
let message = null;
let events = [];
if (eventsRaw !== undefined && eventsRaw.length > 0) {
for (let event of eventsRaw) {
events.push(getEventName(event.name));
delete event.daysMemoise;
}
}
let eventsForMessage = [...events];
while (true) {
message = buildMessage(eventsForMessage, locale, day, link);
if (message === null || message.length <= 280) {
break;
} else {
eventsForMessage = eventsForMessage.slice(0, eventsForMessage.length - 1);
}
}
return {
day: day.toString(),
link,
image,
message,
events,
eventsRaw: (eventsRaw || []),
}
}
const router = Router();
router.get('/calendar/today', handleErrorAsync(async (req, res) => {
return res.json(eventsSummary(
Day.today(),
req.locales[global.config.locale],
));
}));
router.get('/calendar/:year-:month-:day', handleErrorAsync(async (req, res) => {
return res.json(eventsSummary(
new Day(parseInt(req.params.year), parseInt(req.params.month), parseInt(req.params.day)),
req.locales[global.config.locale],
));
}));
const routeBase = `/queer-calendar-${global.config.locale}`;
router.get(routeBase + '.ics', handleErrorAsync(async (req, res) => {
let events = {};
for (let year of calendar.getAllYears()) {
events[year.year] = year.events;
}
renderEvents(events, res);
}));
router.get(routeBase + '-:year-:uuid.ics', handleErrorAsync(async (req, res) => {
const year = calendar.getYear(req.params.year);
if (!year) {
return res.status(404).json({error: 'Not found'});
}
renderEvents({[year.year]: [year.eventsByUuid[req.params.uuid]]}, res)
}));
router.get(routeBase + '-:year.ics', handleErrorAsync(async (req, res) => {
const year = calendar.getYear(req.params.year);
if (!year) {
return res.status(404).json({error: 'Not found'});
}
renderEvents({[year.year]: year.events}, res)
}));
export default router;