2020-05-26 21:06:34 +03:00
|
|
|
const qs = require('qs');
|
|
|
|
const axios = require('axios');
|
|
|
|
const registrar = require('../registrar.js');
|
|
|
|
|
|
|
|
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
|
|
|
|
2020-05-27 01:36:34 +03:00
|
|
|
const editNoticeHTML = (client, roomId, event, html, plain) => client.sendMessage(roomId, {
|
2020-05-26 21:06:34 +03:00
|
|
|
body: ` * ${plain || html.replace(/<[^<]+?>/g, '')}`,
|
|
|
|
formatted_body: ` * ${html}`,
|
|
|
|
format: 'org.matrix.custom.html',
|
|
|
|
msgtype: 'm.notice',
|
|
|
|
'm.new_content': {
|
|
|
|
body: plain || html.replace(/<[^<]+?>/g, ''),
|
|
|
|
formatted_body: html,
|
|
|
|
format: 'org.matrix.custom.html',
|
|
|
|
msgtype: 'm.notice'
|
|
|
|
},
|
|
|
|
'm.relates_to': {
|
|
|
|
rel_type: 'm.replace',
|
2020-05-27 01:36:34 +03:00
|
|
|
event_id: event.event_id
|
2020-05-26 21:06:34 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const headers = ({ domain, userAgent }) => ({
|
|
|
|
'Host': `${domain}`,
|
|
|
|
'User-Agent': `${userAgent}`
|
|
|
|
});
|
|
|
|
|
2020-06-23 21:56:08 +03:00
|
|
|
const archive = async (instance, url, rearchive) => {
|
2020-05-26 21:06:34 +03:00
|
|
|
const form = await instance({ method: 'GET', url: '/' });
|
|
|
|
if (form.statusText !== 'OK') throw form;
|
|
|
|
const submitId = form.data.match(/name="submitid" value="([^"]+)/);
|
|
|
|
const submit = await instance({
|
|
|
|
method: 'POST',
|
|
|
|
url: '/submit/',
|
|
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
2020-06-23 21:56:08 +03:00
|
|
|
data: qs.stringify({ anyway: rearchive ? '1' : undefined, submitid: submitId ? submitId[1] : undefined, url })
|
2020-05-26 21:06:34 +03:00
|
|
|
});
|
|
|
|
if (submit.statusText !== 'OK') throw submit;
|
|
|
|
if (submit.request.path !== '/submit/')
|
2020-06-23 21:56:08 +03:00
|
|
|
return { id: submit.request.path, date: submit.headers['memento-datetime'] };
|
2020-05-26 21:06:34 +03:00
|
|
|
if (submit.headers.refresh)
|
|
|
|
return { refresh: submit.headers.refresh.split(';url=')[1] };
|
|
|
|
throw submit;
|
|
|
|
};
|
|
|
|
|
|
|
|
const reqStr = str => `<em>Sending archive request for <code>${str}</code></em>`;
|
|
|
|
const arc1Str = str => `<em>Archiving page <code>${str}</code></em>`;
|
2020-06-23 21:56:08 +03:00
|
|
|
const arc2Str = (str, date) => `<em>Archived page <code>${str}</code> [${date}]</em>`;
|
2020-05-26 21:06:34 +03:00
|
|
|
const arc3Str = str => `<em>Timed out <code>${str}</code></em>`;
|
|
|
|
|
2020-06-23 21:56:08 +03:00
|
|
|
const run = async (matrixClient, { roomId }, userInput, rearchive, registrar) => {
|
2020-05-26 21:06:34 +03:00
|
|
|
const config = registrar.config.archive;
|
|
|
|
const instance = axios.create({
|
|
|
|
baseURL: `https://${config.domain}`,
|
|
|
|
headers: headers(config),
|
|
|
|
transformResponse: [],
|
|
|
|
timeout: 10 * 1000
|
|
|
|
});
|
|
|
|
let reply = null;
|
|
|
|
try {
|
|
|
|
reply = await matrixClient.sendHtmlNotice(roomId, '', reqStr(userInput));
|
2020-06-23 21:56:08 +03:00
|
|
|
const { refresh, id, date } = await archive(instance, userInput, rearchive);
|
2020-05-26 21:06:34 +03:00
|
|
|
if (id)
|
2020-06-23 21:56:08 +03:00
|
|
|
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.domain}${id}`, date));
|
2020-05-26 21:06:34 +03:00
|
|
|
if (refresh) {
|
|
|
|
const path = refresh.split(`https://${config.domain}`);
|
|
|
|
if (!path[1]) throw refresh;
|
|
|
|
await editNoticeHTML(matrixClient, roomId, reply, arc1Str(refresh));
|
|
|
|
let tries = 30;
|
|
|
|
while (tries--) {
|
|
|
|
await sleep(10000);
|
2020-06-23 21:56:08 +03:00
|
|
|
const { request: { path: reqPath }, headers: { 'memento-datetime': date } } = await instance({ method: 'HEAD', url: path[1] })
|
2020-05-26 21:06:34 +03:00
|
|
|
.catch(e => ({ request: { path: path[1] } }));
|
|
|
|
if (reqPath !== path[1])
|
2020-06-23 21:56:08 +03:00
|
|
|
return await editNoticeHTML(matrixClient, roomId, reply, arc2Str(`${config.domain}${reqPath}`, date));
|
2020-05-26 21:06:34 +03:00
|
|
|
}
|
|
|
|
return await editNoticeHTML(matrixClient, roomId, reply, arc3Str(refresh));
|
|
|
|
}
|
|
|
|
throw 'sad';
|
|
|
|
} catch (e) {
|
|
|
|
const sad = `<strong>Sad!</strong><br /><code>${`${e}`.replace(/<[^<]+?>/g, '').substr(0, 100)}</code>`;
|
|
|
|
if (reply)
|
|
|
|
editNoticeHTML(matrixClient, roomId, reply, sad, 'sad').catch(() => {});
|
|
|
|
else
|
|
|
|
matrixClient.sendHtmlNotice(roomId, 'sad', sad).catch(() => {});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.runQuery = run;
|