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 path = require('path');
const fetch = require('node-fetch');
const urlJoin = require('./lib/url-join');
const { matrixServerUrl } = require('../config.json');
const secrets = require('../secrets.json');
@ -10,7 +12,7 @@ assert(matrixAccessToken);
class HTTPResponseError extends Error {
constructor(response, responseText, ...args) {
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
);
this.response = response;
@ -40,7 +42,10 @@ async function fetchEndpoint(endpoint) {
}
async function fetchEventsForTimestamp(roomId, ts) {
const timestampToEventEndpoint = path.join(
assert(roomId);
assert(ts);
const timestampToEventEndpoint = urlJoin(
matrixServerUrl,
`_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;
assert(eventIdForTimestamp);
const contextEndpoint = path.join(
const contextEndpoint = urlJoin(
matrixServerUrl,
`_matrix/client/r0/rooms/${roomId}/context/${eventIdForTimestamp}?limit=0`
);
const contextResData = await fetchEndpoint(contextEndpoint);
//console.log('contextResData', contextResData);
const messagesEndpoint = path.join(
const messagesEndpoint = urlJoin(
matrixServerUrl,
`_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 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 renderHydrogenToString = require('./render-hydrogen-to-string');
const config = require('../config.json');
const basePath = config.basePath;
assert(basePath);
const app = express();
app.get('/style.css', async function (req, res) {
@ -12,20 +18,75 @@ app.get('/style.css', async function (req, res) {
});
app.get(
'/',
'/:roomIdOrAlias/event/:eventId',
asyncHandler(async function (req, res) {
const { events, stateEventMap } = await fetchEventsForTimestamp(
'!HBehERstyQBxyJDLfR:my.synapse.server',
new Date('2022-02-08').getTime()
);
res.send('todo');
})
);
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 styleUrl = urlJoin(basePath, 'style.css');
const pageHtml = `
<!doctype html>
<html lang="en">
<head>
<link href="style.css" rel="stylesheet">
<link href="${styleUrl}" rel="stylesheet">
</head>
<body>
${hydrogenHtmlOutput}