enwnbot

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

promUrlShortener.js (3778B)


      1 const TUrl = require('tinyurl');
      2 const { promisify } = require('util');
      3 const R = require('request').defaults({ jar: true });
      4 
      5 const { botAccount, botPass } = require('./config');
      6 
      7 const request = promisify(R);
      8 const get = promisify(R.get);
      9 const post = promisify(R.post);
     10 
     11 const url = 'https://meta.wikimedia.org/w/api.php';
     12 const globalState = {
     13   mainExecuted: false,
     14 };
     15 
     16 let logintoken;
     17 let csrfToken;
     18 
     19 async function getLoginToken() {
     20   const res = {};
     21   try {
     22     const data = await get({
     23       url,
     24       qs: {
     25         action: 'query',
     26         meta: 'tokens',
     27         type: 'login',
     28         format: 'json',
     29       },
     30     });
     31     const { body } = data;
     32     const parsed = JSON.parse(body);
     33     res.logintoken = parsed.query.tokens.logintoken;
     34   } catch (error) {
     35     console.log(error);
     36     res.error = error;
     37     globalState.error = true;
     38     globalState.fallback = true;
     39   }
     40   return res;
     41 }
     42 
     43 async function loginRequest(TOKEN) {
     44   const res = {};
     45   try {
     46     const data = await post({
     47       url,
     48       form: {
     49         action: 'login',
     50         lgname: botAccount,
     51         lgpassword: botPass,
     52         lgtoken: TOKEN,
     53         format: 'json',
     54       },
     55     });
     56     const { body } = data;
     57     const parsed = JSON.parse(body);
     58     const result = parsed.login.result;
     59     if (result != 'Success') {
     60       globalState.error = parsed.login.reason;
     61       res.error = parsed.login.reason;
     62     } else res.result = result;
     63   } catch (error) {
     64     console.log(error);
     65     globalState.error = error;
     66     res.error = error;
     67   }
     68   return res;
     69 }
     70 
     71 async function getCsrfToken() {
     72   const res = {};
     73   try {
     74     const data = await get({
     75       url,
     76       qs: {
     77         action: 'query',
     78         meta: 'tokens',
     79         format: 'json',
     80       },
     81     });
     82     const { body } = data;
     83     const parsed = JSON.parse(body);
     84     res.csrfToken = parsed.query.tokens.csrftoken;
     85   } catch (error) {
     86     res.error = error;
     87     globalState.useFallback = true;
     88   }
     89   return res;
     90 }
     91 
     92 async function main() {
     93   try {
     94     const maybeLoginToken = await getLoginToken();
     95     if (maybeLoginToken.error) globalState.useFallback = true;
     96     else {
     97       logintoken = maybeLoginToken.logintoken;
     98       const maybeSuccess = await loginRequest(logintoken);
     99       if (maybeSuccess.error) globalState.useFallback = true;
    100       else {
    101         const maybeCsrfToken = await getCsrfToken();
    102         if (maybeCsrfToken.error) globalState.useFallback = true;
    103         else csrfToken = maybeCsrfToken.csrfToken;
    104       }
    105     }
    106   } catch (error) {
    107     console.error(error);
    108     globalState.useFallback = true;
    109   }
    110   globalState.mainExecuted = true;
    111 }
    112 
    113 main();
    114 
    115 async function short(URI) {
    116   if (!globalState.mainExecuted) main();
    117   if (!URI)
    118     URI =
    119       'https://en.wikinews.org/wiki/Astronomer_tells_Wikinews_about_discovery_of_closest_black_hole_known_so_far';
    120   const res = {};
    121   if (!globalState.error && !globalState.useFallback) {
    122     try {
    123       const data = await post({
    124         url,
    125         form: {
    126           action: 'shortenurl',
    127           url: URI,
    128           format: 'json',
    129         },
    130       });
    131       const { body } = data;
    132       const parsed = JSON.parse(body);
    133       if (parsed.error) throw new Error('Rate limit');
    134       res.url = parsed.shortenurl.shorturl;
    135     } catch (error) {
    136       globalState.useFallback = true;
    137       globalState.error = error;
    138       res.error = error;
    139       res.url = await TUrl.shorten(URI);
    140     }
    141   } else {
    142     try {
    143       res.url = await TUrl.shorten(URI);
    144     } catch (error) {
    145       res.error = error;
    146       console.error(error);
    147     }
    148   }
    149   return res;
    150 }
    151 
    152 function fallback() {
    153   globalState.useFallback = true;
    154 }
    155 
    156 function reset() {
    157   globalState.mainExecuted = false;
    158   globalState.error = false;
    159   globalState.useFallback = false;
    160 }
    161 
    162 module.exports = { fallback, reset, short };