Add in date routes

This commit is contained in:
Eric Eastwood 2022-02-09 20:29:18 -06:00
parent a268086cfd
commit 2378ed72c7
4 changed files with 87 additions and 12 deletions

View File

@ -1,6 +1,8 @@
const assert = require('assert'); const assert = require('assert');
const path = require('path');
const fetch = require('node-fetch'); const fetch = require('node-fetch');
const urlJoin = require('./lib/url-join');
const { matrixServerUrl } = require('../config.json'); const { matrixServerUrl } = require('../config.json');
const secrets = require('../secrets.json'); const secrets = require('../secrets.json');
@ -10,7 +12,7 @@ assert(matrixAccessToken);
class HTTPResponseError extends Error { class HTTPResponseError extends Error {
constructor(response, responseText, ...args) { constructor(response, responseText, ...args) {
super( super(
`HTTP Error Response: ${response.status} ${response.statusText}: ${responseText}\n\tURL=${response.url}`, `HTTP Error Response: ${response.status} ${response.statusText}: ${responseText}\n URL=${response.url}`,
...args ...args
); );
this.response = response; this.response = response;
@ -40,7 +42,10 @@ async function fetchEndpoint(endpoint) {
} }
async function fetchEventsForTimestamp(roomId, ts) { async function fetchEventsForTimestamp(roomId, ts) {
const timestampToEventEndpoint = path.join( assert(roomId);
assert(ts);
const timestampToEventEndpoint = urlJoin(
matrixServerUrl, matrixServerUrl,
`_matrix/client/unstable/org.matrix.msc3030/rooms/${roomId}/timestamp_to_event?ts=${ts}&dir=f` `_matrix/client/unstable/org.matrix.msc3030/rooms/${roomId}/timestamp_to_event?ts=${ts}&dir=f`
); );
@ -50,14 +55,14 @@ async function fetchEventsForTimestamp(roomId, ts) {
const eventIdForTimestamp = timestampToEventResData.event_id; const eventIdForTimestamp = timestampToEventResData.event_id;
assert(eventIdForTimestamp); assert(eventIdForTimestamp);
const contextEndpoint = path.join( const contextEndpoint = urlJoin(
matrixServerUrl, matrixServerUrl,
`_matrix/client/r0/rooms/${roomId}/context/${eventIdForTimestamp}?limit=0` `_matrix/client/r0/rooms/${roomId}/context/${eventIdForTimestamp}?limit=0`
); );
const contextResData = await fetchEndpoint(contextEndpoint); const contextResData = await fetchEndpoint(contextEndpoint);
//console.log('contextResData', contextResData); //console.log('contextResData', contextResData);
const messagesEndpoint = path.join( const messagesEndpoint = urlJoin(
matrixServerUrl, matrixServerUrl,
`_matrix/client/r0/rooms/${roomId}/messages?from=${contextResData.start}&limit=50&filter={"lazy_load_members":true,"include_redundant_members":true}` `_matrix/client/r0/rooms/${roomId}/messages?from=${contextResData.start}&limit=50&filter={"lazy_load_members":true,"include_redundant_members":true}`
); );

9
server/lib/url-join.js Normal file
View File

@ -0,0 +1,9 @@
const path = require('path');
// via https://javascript.plainenglish.io/how-to-safely-concatenate-url-with-node-js-f6527b623d5
function urlJoin(baseUrl, ...pathParts) {
const fullUrl = new URL(path.join(...pathParts), baseUrl).toString();
return fullUrl;
}
module.exports = urlJoin;

View File

@ -1,9 +1,15 @@
const assert = require('assert');
const express = require('express'); const express = require('express');
const asyncHandler = require('./express-async-handler'); const asyncHandler = require('./lib/express-async-handler');
const urlJoin = require('./lib/url-join');
const fetchEventsForTimestamp = require('./fetch-events-for-timestamp'); const fetchEventsForTimestamp = require('./fetch-events-for-timestamp');
const renderHydrogenToString = require('./render-hydrogen-to-string'); const renderHydrogenToString = require('./render-hydrogen-to-string');
const config = require('../config.json');
const basePath = config.basePath;
assert(basePath);
const app = express(); const app = express();
app.get('/style.css', async function (req, res) { app.get('/style.css', async function (req, res) {
@ -12,20 +18,75 @@ app.get('/style.css', async function (req, res) {
}); });
app.get( app.get(
'/', '/:roomIdOrAlias/event/:eventId',
asyncHandler(async function (req, res) { asyncHandler(async function (req, res) {
const { events, stateEventMap } = await fetchEventsForTimestamp( res.send('todo');
'!HBehERstyQBxyJDLfR:my.synapse.server', })
new Date('2022-02-08').getTime() );
);
app.get(
'/:roomIdOrAlias/date/:yyyy(\\d{4})/:mm(\\d{2})/:dd(\\d{2})/:hourRange(\\d\\d?-\\d\\d?)?',
asyncHandler(async function (req, res) {
const roomIdOrAlias = req.params.roomIdOrAlias;
assert(roomIdOrAlias.startsWith('!') || roomIdOrAlias.startsWith('#'));
const yyyy = parseInt(req.params.yyyy, 10);
// Month is the only zero-based index in this group
const mm = parseInt(req.params.mm, 10) - 1;
const dd = parseInt(req.params.dd, 10);
const hourRange = req.params.hourRange;
let fromHour = 0;
let toHour = 0;
if (hourRange) {
const hourMatches = hourRange.match(/^(\d\d?)-(\d\d?)$/);
if (!hourMatches) {
throw new StatusError(404, 'Hour was unable to be parsed');
}
fromHour = parseInt(hourMatches[1], 10);
toHour = parseInt(hourMatches[2], 10);
if (Number.isNaN(fromHour) || fromHour < 0 || fromHour > 23) {
throw new StatusError(404, 'From hour can only be in range 0-23');
}
// Currently we force the range to always be 1 hour
// If the format isn't correct, redirect to the correct hour range
if (toHour !== fromHour + 1) {
res.redirect(
urlJoin(
basePath,
roomIdOrAlias,
'date',
req.params.yyyy,
req.params.mm,
req.params.dd,
`${fromHour}-${fromHour + 1}`
)
);
return;
}
}
const fromTimestamp = Date.UTC(yyyy, mm, dd, fromHour);
let toTimestamp = Date.UTC(yyyy, mm, dd + 1, fromHour);
if (hourRange) {
toTimestamp = Date.UTC(yyyy, mm, dd, toHour);
}
const { events, stateEventMap } = await fetchEventsForTimestamp(roomIdOrAlias, fromTimestamp);
const hydrogenHtmlOutput = await renderHydrogenToString(events, stateEventMap); const hydrogenHtmlOutput = await renderHydrogenToString(events, stateEventMap);
const styleUrl = urlJoin(basePath, 'style.css');
const pageHtml = ` const pageHtml = `
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<link href="style.css" rel="stylesheet"> <link href="${styleUrl}" rel="stylesheet">
</head> </head>
<body> <body>
${hydrogenHtmlOutput} ${hydrogenHtmlOutput}