archivesrcbot

Archive enwn sources via IRC.
git clone http://git.hanabi.in/repos/archivesrcbot.git
Log | Files | Refs | LICENSE

index.js (2601B)


      1 // npm imports
      2 const fetch = require("node-fetch");
      3 const wikiapi = require("wikiapi");
      4 const irc = require("irc");
      5 
      6 // constants
      7 const {
      8   channels,
      9   maintainers,
     10   nick,
     11   password,
     12   server,
     13   wiki_api_endpoint,
     14 } = require("./config.json");
     15 
     16 const wiki = new wikiapi(wiki_api_endpoint);
     17 const ircClient = new irc.Client(server, nick, {
     18   channels,
     19   userName: "archivesrcbot",
     20   realName: "archivesrcbot",
     21   sasl: true,
     22   password,
     23   floodProtection: true,
     24   floodProtectionDelay: 1000,
     25 });
     26 
     27 // irc event-listeners
     28 ircClient.addListener("error", errorHandler);
     29 ircClient.addListener("message", normalMsg);
     30 ircClient.addListener("pm", pmHandler);
     31 
     32 // event listener functions
     33 function errorHandler(msg) {
     34   const err = JSON.stringify(msg);
     35   for (const maintainer of maintainers)
     36     ircClient.say(maintainer, `${nick} error: ${err}`);
     37 }
     38 
     39 async function normalMsg(sender, channel, msg) {
     40   if (msg.startsWith(`${nick} `) || msg.startsWith(`${nick}: `))
     41     await start_archiveing(msg, channel);
     42 }
     43 
     44 function pmHandler(sender, msg) {
     45   handleKill(sender, msg);
     46 }
     47 
     48 // helper fns
     49 async function archive_sources(headline = "", channel) {
     50   try {
     51     const page = await wiki.page(headline);
     52     if (!page.pageid) throw new Error("Page does not exist.");
     53     const sources = [];
     54     page.parse().each("template", function (token) {
     55       if (token.name == "Source") {
     56         const src = token.parameters.url;
     57         sources.push(src);
     58       }
     59     });
     60     ircClient.say(channel, `${sources.length} sources were found.`);
     61     sources.forEach(async (src) => await archiveURI(src, channel));
     62   } catch (err) {
     63     ircClient.say(channel, err);
     64   }
     65 }
     66 
     67 async function archiveURI(uri = "", channel) {
     68   try {
     69     ircClient.say(channel, `working on ${uri}.`);
     70     const final_url = "https://web.archive.org/save/" + uri;
     71     const res = await fetch(final_url);
     72     const { url, status } = res;
     73     if (!url) throw new Error("Missing URL");
     74     let sanitised_url = url.replace(
     75       /https:\/\/web.archive.org\/web\/\d+\//,
     76       ""
     77     );
     78     const msg = sanitised_url + " " + status;
     79     ircClient.say(channel, msg);
     80   } catch (err) {
     81     throw new Error(err);
     82   }
     83 }
     84 
     85 function getHeadline(str = "") {
     86   const regex = new RegExp(`${nick}:? (.*)`);
     87   return str.match(regex)[1];
     88 }
     89 
     90 function handleKill(sender, msg) {
     91   if (msg != "KILL") return;
     92   if (!maintainers.includes(sender)) return;
     93   process.abort();
     94 }
     95 
     96 async function start_archiveing(msg, channel) {
     97   try {
     98     const headline = getHeadline(msg);
     99     await archive_sources(headline, channel);
    100   } catch (err) {
    101     ircClient.say(channel, err);
    102   }
    103 }