146 lines
4.0 KiB
JavaScript
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;
|