enwnbot

Converts MediaWiki [[links]] and {{templates}} to links on IRC
git clone http://git.hanabi.in/repos/enwnbot.git
Log | Files | Refs | README | LICENSE

commit f2d88978eff130f615e7d3819e4215cb66698521
parent fcc56e7af3fcab78cfca8c6c4864dea83f5c1a17
Author: Agastya Chandrakant <acagastya@outlook.com>
Date:   Thu, 28 May 2020 12:15:12 +0530

Shortened URLs by default

Diffstat:
Mirc.js | 104+++++++++++++++++++++++++------------------------------------------------------
Autils.js | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 71 deletions(-)

diff --git a/irc.js b/irc.js @@ -1,5 +1,4 @@ const irc = require('irc'); -const fetch = require('node-fetch'); const { admins, @@ -9,10 +8,16 @@ const { report, RQAPI, server, - shortURL, - URL, } = require('./config'); +const { + fetchData, + fullUrl, + getFullLink, + getFullTemplate, + urlShortener, +} = require('./utils'); + const client = new irc.Client(server, botName, { channels, }); @@ -31,95 +36,52 @@ function err(msg) { ); } -function handleLink(link, channel) { - const len = link.length; - const trimmed = link.substr(2, len - 4); - let [main, anchor] = trimmed.split('#'); - main = main.replace(/ /g, '%20'); - if (anchor) anchor = anchor.replace(/ /g, '_'); - let final; - if (anchor) final = `${main}#${anchor}`; - else final = main; - client.say(channel, `${URL}${final}`); -} - -function handleTemplate(template, channel) { - const len = template.length; - const word = template - .substr(2, len - 4) - .split('|')[0] - .replace(/ /g, '%20'); - client.say(channel, `${URL}Template:${word}`); -} - -async function fetchData(URI) { - const res = {}; - try { - const data = await fetch(URI); - const parsed = await data.json(); - res.list = parsed.query.categorymembers; - } catch (error) { - res.error = true; - } - return res; -} - -async function urlShortener(URI) { - const req = `${shortURL}${URI}`; - const res = {}; - try { - const data = await fetch(req, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - }); - const parsed = await data.json(); - res.url = parsed.shortenurl.shorturl; - } catch (error) { - res.err = true; - } - return res; -} - -async function announceRQ(from, channel) { +async function announceRQ(sender, channel) { const data = await fetchData(RQAPI); if (data.error) client.say( channel, - `Error occurred, ${from}. Try this instead: "[[CAT:REV]]"` + `Error occurred, ${sender}. Try this instead: "[[CAT:REV]]"` ); else { const { list } = data; - if (!list.length) client.say(channel, `Review queue is empty, ${from}.`); + if (!list.length) client.say(channel, `Review queue is empty, ${sender}.`); else { client.say( channel, - `${list.length} articles to review, ${from}. They are:` + `${list.length} articles to review, ${sender}. They are:` ); - const urls = list.map(({ title }) => { - const fmtTitle = title.replace(/ /g, '%20'); - return `${URL}${fmtTitle}`; - }); - const shortUrls = await Promise.all(urls.map(urlShortener)); - shortUrls.forEach(({ url }) => { - client.say(channel, url); - }); + const urls = list.map(({ title }) => fullUrl(title)); + client.say(channel, '(Hold on a sec... Shortening the URLs.)'); + sayShortUrls(urls, channel); } } } -function groupChat(from, to, msg) { +async function sayShortUrls(urlList, channel) { + const shortUrls = await Promise.all(urlList.map(urlShortener)); + shortUrls.forEach(({ url }) => { + client.say(channel, url); + }); +} + +function groupChat(sender, channel, msg) { const lcMsg = msg.toLowerCase(); if (lcMsg.includes(`thanks ${botName}`)) - client.say(to, `You are welcome, ${from}.`); - if (msg.includes(`${botName} /RQ`)) announceRQ(from, to); + client.say(channel, `You are welcome, ${sender}.`); + if (msg.includes(`${botName} /RQ`)) announceRQ(sender, channel); const regex1 = /\[{2}(.*?)\]{2}/g; const regex2 = /\{{2}(.*?)\}{2}/g; const links = msg.match(regex1); const templates = msg.match(regex2); - links && links.forEach((link) => handleLink(link, to)); - templates && - !msg.endsWith('--nl') && - templates.forEach((template) => handleTemplate(template, to)); + if (links) { + const fullLinks = links.map(getFullLink); + sayShortUrls(fullLinks, channel); + } + if (!msg.endsWith('--nl') && templates) { + const fullLinks = templates.map(getFullTemplate); + sayShortUrls(fullLinks, channel); + } } client.addListener('error', err); diff --git a/utils.js b/utils.js @@ -0,0 +1,64 @@ +const fetch = require('node-fetch'); +const { shortURL, URL } = require('./config'); + +async function fetchData(URI) { + const res = {}; + try { + const data = await fetch(URI); + const parsed = await data.json(); + res.list = parsed.query.categorymembers; + } catch (error) { + res.error = true; + } + return res; +} + +function fullUrl(title) { + let [main, anchor] = title.split('#'); + main = main.replace(/ /g, '%20'); + if (anchor) anchor = anchor.replace(/ /g, '_'); + let final; + if (anchor) final = `${main}%23${anchor}`; + else final = main; + return `${URL}${final}`; +} + +function getFullLink(link) { + const len = link.length; + const trimmed = link.substr(2, len - 4); + const finalUrl = fullUrl(trimmed); + return finalUrl; +} + +function getFullTemplate(template) { + const len = template.length; + const word = template + .substr(2, len - 4) + .split('|')[0] + .replace(/ /g, '%20'); + return `${URL}Template:${word}`; +} + +async function urlShortener(URI) { + const req = `${shortURL}${URI}`; + const res = {}; + try { + const data = await fetch(req, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + }); + const parsed = await data.json(); + res.url = parsed.shortenurl.shorturl; + } catch (error) { + res.err = true; + } + return res; +} + +module.exports = { + fetchData, + fullUrl, + getFullLink, + getFullTemplate, + urlShortener, +};