fandom.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. const htmlparser = require('htmlparser2');
  2. const {MessageEmbed} = require('discord.js');
  3. const {limit: {interwiki: interwikiLimit}, wikiProjects} = require('../../util/default.json');
  4. const Wiki = require('../../util/wiki.js');
  5. const fs = require('fs');
  6. var fn = {
  7. special_page: require('../../functions/special_page.js'),
  8. discussion: require('../../functions/discussion.js')
  9. };
  10. fs.readdir( './cmds/wiki/fandom', (error, files) => {
  11. if ( error ) return error;
  12. files.filter( file => file.endsWith('.js') ).forEach( file => {
  13. var command = require('./fandom/' + file);
  14. fn[command.name] = command.run;
  15. } );
  16. } );
  17. /**
  18. * Checks a Fandom wiki.
  19. * @param {import('../../util/i18n.js')} lang - The user language.
  20. * @param {import('discord.js').Message} msg - The Discord message.
  21. * @param {String} title - The page title.
  22. * @param {Wiki} wiki - The wiki for the page.
  23. * @param {String} cmd - The command at this point.
  24. * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  25. * @param {String} [spoiler] - If the response is in a spoiler.
  26. * @param {URLSearchParams} [querystring] - The querystring for the link.
  27. * @param {String} [fragment] - The section for the link.
  28. * @param {String} [interwiki] - The fallback interwiki link.
  29. * @param {Number} [selfcall] - The amount of followed interwiki links.
  30. */
  31. function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '', querystring = new URLSearchParams(), fragment = '', interwiki = '', selfcall = 0) {
  32. var full_title = title;
  33. if ( title.includes( '#' ) ) {
  34. fragment = title.split('#').slice(1).join('#');
  35. title = title.split('#')[0];
  36. }
  37. if ( /\?\w+=/.test(title) ) {
  38. var querystart = title.search(/\?\w+=/);
  39. querystring = new URLSearchParams(querystring + '&' + title.substring(querystart + 1));
  40. title = title.substring(0, querystart);
  41. }
  42. if ( title.length > 250 ) {
  43. title = title.substring(0, 250);
  44. msg.reactEmoji('⚠️');
  45. }
  46. var invoke = title.split(' ')[0].toLowerCase();
  47. var aliasInvoke = ( lang.aliases[invoke] || invoke );
  48. var args = title.split(' ').slice(1);
  49. if ( aliasInvoke === 'random' && !args.join('') && !querystring.toString() && !fragment ) {
  50. return fn.random(lang, msg, wiki, reaction, spoiler);
  51. }
  52. if ( aliasInvoke === 'overview' && !args.join('') && !querystring.toString() && !fragment ) {
  53. return fn.overview(lang, msg, wiki, reaction, spoiler);
  54. }
  55. if ( aliasInvoke === 'test' && !args.join('') && !querystring.toString() && !fragment ) {
  56. this.test(lang, msg, args, '', wiki);
  57. if ( reaction ) reaction.removeEmoji();
  58. return;
  59. }
  60. if ( aliasInvoke === 'page' ) {
  61. msg.sendChannel( spoiler + '<' + wiki.toLink(args.join('_'), querystring, fragment) + '>' + spoiler );
  62. if ( reaction ) reaction.removeEmoji();
  63. return;
  64. }
  65. if ( aliasInvoke === 'diff' && args.join('') && !querystring.toString() && !fragment ) {
  66. return fn.diff(lang, msg, args, wiki, reaction, spoiler);
  67. }
  68. var noRedirect = ( querystring.getAll('redirect').pop() === 'no' || ( querystring.has('action') && querystring.getAll('action').pop() !== 'view' ) );
  69. got.get( wiki + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=description&amenableparser=true&siprop=general|namespaces|specialpagealiases|wikidesc&iwurl=true' + ( noRedirect ? '' : '&redirects=true' ) + '&prop=imageinfo|categoryinfo&converttitles=true&titles=' + encodeURIComponent( title.replace( /\|/g, '\ufffd' ) ) + '&format=json' ).then( response => {
  70. var body = response.body;
  71. if ( body && body.warnings ) log_warn(body.warnings);
  72. if ( response.statusCode !== 200 || !body || !body.query ) {
  73. if ( interwiki ) msg.sendChannel( spoiler + ' ' + interwiki + ' ' + spoiler );
  74. else if ( wiki.noWiki(response.url) || response.statusCode === 410 ) {
  75. console.log( '- This wiki doesn\'t exist!' );
  76. msg.reactEmoji('nowiki');
  77. }
  78. else {
  79. console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
  80. msg.sendChannelError( spoiler + '<' + wiki.toLink(( querystring.toString() || fragment || !title ? title : 'Special:Search' ), ( querystring.toString() || fragment || !title ? querystring : {search:title} ), fragment) + '>' + spoiler );
  81. }
  82. if ( reaction ) reaction.removeEmoji();
  83. return;
  84. }
  85. wiki.updateWiki(body.query.general);
  86. if ( body.query.general.generator.startsWith( 'MediaWiki 1.3' ) ) {
  87. return this.gamepedia(lang, msg, title, wiki, cmd, reaction, spoiler, querystring, fragment, selfcall);
  88. }
  89. if ( aliasInvoke === 'search' ) {
  90. return fn.search(lang, msg, full_title.split(' ').slice(1).join(' '), wiki, body.query, reaction, spoiler);
  91. }
  92. if ( aliasInvoke === 'discussion' && !querystring.toString() && !fragment ) {
  93. return fn.discussion(lang, msg, wiki, args.join(' '), body.query, reaction, spoiler);
  94. }
  95. if ( body.query.pages ) {
  96. var querypages = Object.values(body.query.pages);
  97. var querypage = querypages[0];
  98. if ( body.query.redirects && body.query.redirects[0].from.split(':')[0] === body.query.namespaces['-1']['*'] && body.query.specialpagealiases.filter( sp => ['Mypage','Mytalk','MyLanguage'].includes( sp.realname ) ).map( sp => sp.aliases[0] ).includes( body.query.redirects[0].from.split(':').slice(1).join(':').split('/')[0].replace( / /g, '_' ) ) ) {
  99. querypage.title = body.query.redirects[0].from;
  100. delete body.query.redirects[0].tofragment;
  101. delete querypage.missing;
  102. querypage.ns = -1;
  103. querypage.special = '';
  104. }
  105. var contribs = body.query.namespaces['-1']['*'] + ':' + body.query.specialpagealiases.find( sp => sp.realname === 'Contributions' ).aliases[0] + '/';
  106. if ( querypage.ns === 2 && ( !querypage.title.includes( '/' ) || /^[^:]+:(?:(?:\d{1,3}\.){3}\d{1,3}\/\d{2}|(?:[\dA-F]{1,4}:){7}[\dA-F]{1,4}\/\d{2,3})$/.test(querypage.title) ) ) {
  107. var userparts = querypage.title.split(':');
  108. querypage.noRedirect = noRedirect;
  109. fn.user(lang, msg, userparts[0] + ':', userparts.slice(1).join(':'), wiki, querystring, fragment, querypage, contribs, reaction, spoiler);
  110. }
  111. else if ( querypage.ns === -1 && querypage.title.startsWith( contribs ) && querypage.title.length > contribs.length ) {
  112. var username = querypage.title.split('/').slice(1).join('/');
  113. got.get( wiki + 'api.php?action=query&titles=User:' + encodeURIComponent( username ) + '&format=json' ).then( uresponse => {
  114. var ubody = uresponse.body;
  115. if ( uresponse.statusCode !== 200 || !ubody || !ubody.query ) {
  116. console.log( '- ' + uresponse.statusCode + ': Error while getting the user: ' + ( ubody && ubody.error && ubody.error.info ) );
  117. msg.sendChannelError( spoiler + '<' + wiki.toLink(contribs + username, querystring, fragment) + '>' + spoiler );
  118. if ( reaction ) reaction.removeEmoji();
  119. }
  120. else {
  121. querypage = Object.values(ubody.query.pages)[0];
  122. if ( querypage.ns === 2 ) {
  123. username = querypage.title.split(':').slice(1).join(':');
  124. querypage.title = contribs + username;
  125. delete querypage.missing;
  126. querypage.ns = -1;
  127. querypage.special = '';
  128. querypage.noRedirect = noRedirect;
  129. fn.user(lang, msg, contribs, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler);
  130. }
  131. else {
  132. msg.reactEmoji('error');
  133. if ( reaction ) reaction.removeEmoji();
  134. }
  135. }
  136. }, error => {
  137. console.log( '- Error while getting the user: ' + error );
  138. msg.sendChannelError( spoiler + '<' + wiki.toLink(contribs + username, querystring, fragment) + '>' + spoiler );
  139. if ( reaction ) reaction.removeEmoji();
  140. } );
  141. }
  142. else if ( querypage.ns === 1201 && querypage.missing !== undefined ) {
  143. var thread = querypage.title.split(':');
  144. got.get( wiki + 'api.php?action=query&prop=revisions&rvprop=user&rvdir=newer&rvlimit=1&pageids=' + thread.slice(1).join(':') + '&format=json' ).then( thresponse => {
  145. var thbody = thresponse.body;
  146. if ( thresponse.statusCode !== 200 || !thbody || !thbody.query || !thbody.query.pages ) {
  147. console.log( '- ' + thresponse.statusCode + ': Error while getting the thread: ' + ( thbody && thbody.error && thbody.error.info ) );
  148. msg.sendChannelError( spoiler + '<' + wiki.toLink(querypage.title, querystring, fragment) + '>' + spoiler );
  149. if ( reaction ) reaction.removeEmoji();
  150. }
  151. else {
  152. querypage = thbody.query.pages[thread.slice(1).join(':')];
  153. if ( querypage.missing !== undefined ) {
  154. msg.reactEmoji('🤷');
  155. if ( reaction ) reaction.removeEmoji();
  156. }
  157. else {
  158. var pagelink = wiki.toLink(thread.join(':'), querystring, fragment);
  159. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( thread.join(':').escapeFormatting() ).setURL( pagelink ).setFooter( querypage.revisions[0].user );
  160. got.get( wiki.toDescLink(querypage.title), {
  161. responseType: 'text'
  162. } ).then( descresponse => {
  163. var descbody = descresponse.body;
  164. if ( descresponse.statusCode !== 200 || !descbody ) {
  165. console.log( '- ' + descresponse.statusCode + ': Error while getting the description.' );
  166. } else {
  167. var thumbnail = wiki.toLink('Special:FilePath/Wiki-wordmark.png');
  168. var parser = new htmlparser.Parser( {
  169. onopentag: (tagname, attribs) => {
  170. if ( tagname === 'meta' && attribs.property === 'og:description' ) {
  171. var description = attribs.content.escapeFormatting();
  172. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  173. embed.setDescription( description );
  174. }
  175. if ( tagname === 'meta' && attribs.property === 'og:image' ) {
  176. thumbnail = attribs.content;
  177. }
  178. }
  179. }, {decodeEntities:true} );
  180. parser.write( descbody );
  181. parser.end();
  182. embed.setThumbnail( thumbnail );
  183. }
  184. }, error => {
  185. console.log( '- Error while getting the description: ' + error );
  186. } ).finally( () => {
  187. msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
  188. if ( reaction ) reaction.removeEmoji();
  189. } );
  190. }
  191. }
  192. }, error => {
  193. console.log( '- Error while getting the thread: ' + error );
  194. msg.sendChannelError( spoiler + '<' + wiki.toLink(querypage.title, querystring, fragment) + '>' + spoiler );
  195. if ( reaction ) reaction.removeEmoji();
  196. } );
  197. }
  198. else if ( ( querypage.missing !== undefined && querypage.known === undefined && !( noRedirect || querypage.categoryinfo ) ) || querypage.invalid !== undefined ) {
  199. got.get( wiki + 'api/v1/Search/List?minArticleQuality=0&namespaces=4,12,14,' + Object.values(body.query.namespaces).filter( ns => ns.content !== undefined ).map( ns => ns.id ).join(',') + '&limit=1&query=' + encodeURIComponent( title ) + '&format=json&cache=' + Date.now() ).then( wsresponse => {
  200. var wsbody = wsresponse.body;
  201. if ( wsresponse.statusCode !== 200 || !wsbody || wsbody.exception || !wsbody.total || !wsbody.items || !wsbody.items.length ) {
  202. if ( wsbody && ( !wsbody.total || ( wsbody.items && !wsbody.items.length ) || ( wsbody.exception && wsbody.exception.code === 404 ) ) ) msg.reactEmoji('🤷');
  203. else {
  204. console.log( '- ' + wsresponse.statusCode + ': Error while getting the search results: ' + ( wsbody && wsbody.exception && wsbody.exception.details ) );
  205. msg.sendChannelError( spoiler + '<' + wiki.toLink('Special:Search', {search:title}) + '>' + spoiler );
  206. }
  207. if ( reaction ) reaction.removeEmoji();
  208. }
  209. else {
  210. querypage = wsbody.items[0];
  211. if ( querypage.ns && !querypage.title.startsWith( body.query.namespaces[querypage.ns]['*'] + ':' ) ) {
  212. querypage.title = body.query.namespaces[querypage.ns]['*'] + ':' + querypage.title;
  213. }
  214. var text = '';
  215. var prefix = ( msg.channel.type === 'text' && patreons[msg.guild.id] || process.env.prefix );
  216. var linksuffix = ( querystring.toString() ? '?' + querystring : '' ) + ( fragment ? '#' + fragment : '' );
  217. if ( title.replace( /[_-]/g, ' ' ).toLowerCase() === querypage.title.replace( /-/g, ' ' ).toLowerCase() ) {
  218. text = '';
  219. }
  220. else if ( wsbody.total === 1 ) {
  221. text = '\n' + lang.get('search.infopage', '`' + prefix + cmd + ( lang.localNames.page || 'page' ) + ' ' + title + linksuffix + '`');
  222. }
  223. else {
  224. text = '\n' + lang.get('search.infosearch', '`' + prefix + cmd + ( lang.localNames.page || 'page' ) + ' ' + title + linksuffix + '`', '`' + prefix + cmd + ( lang.localNames.search || 'search' ) + ' ' + title + linksuffix + '`');
  225. }
  226. got.get( wiki + 'api.php?action=query&prop=imageinfo|categoryinfo&titles=' + encodeURIComponent( querypage.title ) + '&format=json' ).then( srresponse => {
  227. var srbody = srresponse.body;
  228. if ( srbody && srbody.warnings ) log_warn(srbody.warnings);
  229. if ( srresponse.statusCode !== 200 || !srbody || !srbody.query || !srbody.query.pages ) {
  230. console.log( '- ' + srresponse.statusCode + ': Error while getting the search results: ' + ( srbody && srbody.error && srbody.error.info ) );
  231. msg.sendChannelError( spoiler + '<' + wiki.toLink(querypage.title, querystring, fragment) + '>' + spoiler );
  232. if ( reaction ) reaction.removeEmoji();
  233. }
  234. else {
  235. querypage = Object.values(srbody.query.pages)[0];
  236. var pagelink = wiki.toLink(querypage.title, querystring, fragment);
  237. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
  238. if ( querypage.imageinfo ) {
  239. var filename = querypage.title.replace( body.query.namespaces['6']['*'] + ':', '' );
  240. var pageimage = wiki.toLink('Special:FilePath/' + filename, {version:Date.now()});
  241. if ( msg.showEmbed() && /\.(?:png|jpg|jpeg|gif)$/.test(querypage.title.toLowerCase()) ) embed.setImage( pageimage );
  242. else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pageimage,name:( spoiler ? 'SPOILER ' : '' ) + filename}] );
  243. }
  244. if ( querypage.categoryinfo ) {
  245. var category = [lang.get('search.category.content')];
  246. if ( querypage.categoryinfo.size === 0 ) {
  247. category.push(lang.get('search.category.empty'));
  248. }
  249. if ( querypage.categoryinfo.pages > 0 ) {
  250. category.push(lang.get('search.category.pages', querypage.categoryinfo.pages));
  251. }
  252. if ( querypage.categoryinfo.files > 0 ) {
  253. category.push(lang.get('search.category.files', querypage.categoryinfo.files));
  254. }
  255. if ( querypage.categoryinfo.subcats > 0 ) {
  256. category.push(lang.get('search.category.subcats', querypage.categoryinfo.subcats));
  257. }
  258. if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
  259. else text += '\n\n' + category.join('\n');
  260. }
  261. if ( querypage.title === body.query.general.mainpage && body.query.allmessages[0]['*'] ) {
  262. embed.setDescription( body.query.allmessages[0]['*'] );
  263. embed.setThumbnail( wiki.toLink('Special:FilePath/Wiki-wordmark.png') );
  264. msg.sendChannel( spoiler + '<' + pagelink + '>' + text + spoiler, {embed} );
  265. if ( reaction ) reaction.removeEmoji();
  266. }
  267. else got.get( wiki.toDescLink(querypage.title), {
  268. responseType: 'text'
  269. } ).then( descresponse => {
  270. var descbody = descresponse.body;
  271. if ( descresponse.statusCode !== 200 || !descbody ) {
  272. console.log( '- ' + descresponse.statusCode + ': Error while getting the description.' );
  273. } else {
  274. var thumbnail = wiki.toLink('Special:FilePath/Wiki-wordmark.png');
  275. var parser = new htmlparser.Parser( {
  276. onopentag: (tagname, attribs) => {
  277. if ( tagname === 'meta' && attribs.property === 'og:description' ) {
  278. var description = attribs.content.escapeFormatting();
  279. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  280. embed.setDescription( description );
  281. }
  282. if ( tagname === 'meta' && attribs.property === 'og:image' && querypage.title !== body.query.general.mainpage ) {
  283. thumbnail = attribs.content;
  284. }
  285. }
  286. }, {decodeEntities:true} );
  287. parser.write( descbody );
  288. parser.end();
  289. if ( !querypage.imageinfo ) embed.setThumbnail( thumbnail );
  290. }
  291. }, error => {
  292. console.log( '- Error while getting the description: ' + error );
  293. } ).finally( () => {
  294. msg.sendChannel( spoiler + '<' + pagelink + '>' + text + spoiler, {embed} );
  295. if ( reaction ) reaction.removeEmoji();
  296. } );
  297. }
  298. }, error => {
  299. console.log( '- Error while getting the search results: ' + error );
  300. msg.sendChannelError( spoiler + '<' + wiki.toLink(querypage.title, querystring, fragment) + '>' + spoiler );
  301. if ( reaction ) reaction.removeEmoji();
  302. } );
  303. }
  304. }, error => {
  305. console.log( '- Error while getting the search results: ' + error );
  306. msg.sendChannelError( spoiler + '<' + wiki.toLink('Special:Search', {search:title}) + '>' + spoiler );
  307. if ( reaction ) reaction.removeEmoji();
  308. } );
  309. }
  310. else if ( querypage.ns === -1 ) {
  311. var pagelink = wiki.toLink(querypage.title, querystring, fragment);
  312. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink ).setThumbnail( wiki.toLink('Special:FilePath/Wiki-wordmark.png') );
  313. var specialpage = body.query.specialpagealiases.find( sp => body.query.namespaces['-1']['*'] + ':' + sp.aliases[0].replace( /\_/g, ' ' ) === querypage.title.split('/')[0] );
  314. specialpage = ( specialpage ? specialpage.realname : querypage.title.replace( body.query.namespaces['-1']['*'] + ':', '' ).split('/')[0] ).toLowerCase();
  315. fn.special_page(lang, msg, querypage.title, specialpage, embed, wiki, reaction, spoiler);
  316. }
  317. else {
  318. var pagelink = wiki.toLink(querypage.title, querystring, ( fragment || ( body.query.redirects && body.query.redirects[0].tofragment || '' ) ));
  319. var text = '';
  320. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
  321. if ( querypage.imageinfo ) {
  322. var filename = querypage.title.replace( body.query.namespaces['6']['*'] + ':', '' );
  323. var pageimage = wiki.toLink('Special:FilePath/' + filename, {version:Date.now()});
  324. if ( msg.showEmbed() && /\.(?:png|jpg|jpeg|gif)$/.test(querypage.title.toLowerCase()) ) embed.setImage( pageimage );
  325. else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pageimage,name:( spoiler ? 'SPOILER ' : '' ) + filename}] );
  326. }
  327. if ( querypage.categoryinfo ) {
  328. var category = [lang.get('search.category.content')];
  329. if ( querypage.categoryinfo.size === 0 ) {
  330. category.push(lang.get('search.category.empty'));
  331. }
  332. if ( querypage.categoryinfo.pages > 0 ) {
  333. category.push(lang.get('search.category.pages', querypage.categoryinfo.pages));
  334. }
  335. if ( querypage.categoryinfo.files > 0 ) {
  336. category.push(lang.get('search.category.files', querypage.categoryinfo.files));
  337. }
  338. if ( querypage.categoryinfo.subcats > 0 ) {
  339. category.push(lang.get('search.category.subcats', querypage.categoryinfo.subcats));
  340. }
  341. if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
  342. else text += '\n\n' + category.join('\n');
  343. }
  344. if ( querypage.title === body.query.general.mainpage && body.query.allmessages[0]['*'] ) {
  345. embed.setDescription( body.query.allmessages[0]['*'] );
  346. embed.setThumbnail( wiki.toLink('Special:FilePath/Wiki-wordmark.png') );
  347. msg.sendChannel( spoiler + '<' + pagelink + '>' + text + spoiler, {embed} );
  348. if ( reaction ) reaction.removeEmoji();
  349. }
  350. else got.get( wiki.toDescLink(querypage.title), {
  351. responseType: 'text'
  352. } ).then( descresponse => {
  353. var descbody = descresponse.body;
  354. if ( descresponse.statusCode !== 200 || !descbody ) {
  355. console.log( '- ' + descresponse.statusCode + ': Error while getting the description.' );
  356. } else {
  357. var thumbnail = wiki.toLink('Special:FilePath/Wiki-wordmark.png');
  358. var parser = new htmlparser.Parser( {
  359. onopentag: (tagname, attribs) => {
  360. if ( tagname === 'meta' && attribs.property === 'og:description' ) {
  361. var description = attribs.content.escapeFormatting();
  362. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  363. embed.setDescription( description );
  364. }
  365. if ( tagname === 'meta' && attribs.property === 'og:image' && querypage.title !== body.query.general.mainpage ) {
  366. thumbnail = attribs.content;
  367. }
  368. }
  369. }, {decodeEntities:true} );
  370. parser.write( descbody );
  371. parser.end();
  372. if ( !querypage.imageinfo ) embed.setThumbnail( thumbnail );
  373. }
  374. }, error => {
  375. console.log( '- Error while getting the description: ' + error );
  376. } ).finally( () => {
  377. msg.sendChannel( spoiler + '<' + pagelink + '>' + text + spoiler, {embed} );
  378. if ( reaction ) reaction.removeEmoji();
  379. } );
  380. }
  381. }
  382. else if ( body.query.interwiki ) {
  383. if ( msg.channel.type === 'text' && pause[msg.guild.id] ) {
  384. if ( reaction ) reaction.removeEmoji();
  385. console.log( '- Aborted, paused.' );
  386. return;
  387. }
  388. var iw = new URL(body.query.interwiki[0].url.replace( /\\/g, '%5C' ).replace( /@(here|everyone)/g, '%40$1' ), wiki);
  389. querystring.forEach( (value, name) => {
  390. iw.searchParams.append(name, value);
  391. } );
  392. if ( fragment ) iw.hash = Wiki.toSection(fragment);
  393. else fragment = iw.hash.substring(1);
  394. var maxselfcall = interwikiLimit[( msg?.guild?.id in patreons ? 'patreon' : 'default' )];
  395. if ( selfcall < maxselfcall && ['http:','https:'].includes( iw.protocol ) ) {
  396. selfcall++;
  397. if ( iw.hostname.endsWith( '.fandom.com' ) || iw.hostname.endsWith( '.wikia.org' ) ) {
  398. let regex = iw.pathname.match( /^(\/(?!wiki\/)[a-z-]{2,12})?(?:\/wiki\/|\/?$)/ );
  399. if ( regex ) {
  400. let path = ( regex[1] || '' );
  401. let iwtitle = decodeURIComponent( iw.pathname.replace( regex[0], '' ) ).replace( /_/g, ' ' );
  402. cmd = ( iw.hostname.endsWith( '.wikia.org' ) ? '??' : '?' ) + ( path ? path.substring(1) + '.' : '' ) + iw.hostname.replace( /\.(?:fandom\.com|wikia\.org)/, ' ' );
  403. return this.fandom(lang, msg, iwtitle, new Wiki(iw.origin + path + '/'), cmd, reaction, spoiler, iw.searchParams, fragment, iw.href, selfcall);
  404. }
  405. }
  406. if ( iw.hostname.endsWith( '.gamepedia.com' ) ) {
  407. let iwtitle = decodeURIComponent( iw.pathname.substring(1) ).replace( /_/g, ' ' );
  408. cmd = '!' + iw.hostname.replace( '.gamepedia.com', ' ' );
  409. if ( cmd !== '!www ' ) return this.gamepedia(lang, msg, iwtitle, new Wiki(iw.origin), cmd, reaction, spoiler, iw.searchParams, fragment, iw.href, selfcall);
  410. }
  411. let project = wikiProjects.find( project => iw.hostname.endsWith( project.name ) );
  412. if ( project ) {
  413. let regex = ( iw.host + iw.pathname ).match( new RegExp( '^' + project.regex + '(?:' + project.articlePath + '|/?$)' ) );
  414. if ( regex ) {
  415. let iwtitle = decodeURIComponent( iw.pathname.replace( regex[0], '' ) ).replace( /_/g, ' ' );
  416. cmd = '!!' + regex[1] + ' ';
  417. return this.gamepedia(lang, msg, iwtitle, new Wiki(iw.origin + project.scriptPath), cmd, reaction, spoiler, iw.searchParams, fragment, iw.href, selfcall);
  418. }
  419. }
  420. }
  421. msg.sendChannel( spoiler + ' ' + iw + ' ' + spoiler ).then( message => {
  422. if ( message && selfcall === maxselfcall ) message.reactEmoji('⚠️');
  423. } );
  424. if ( reaction ) reaction.removeEmoji();
  425. }
  426. else if ( body.query.redirects ) {
  427. var pagelink = wiki.toLink(body.query.redirects[0].to, querystring, ( fragment || body.query.redirects[0].tofragment || '' ));
  428. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( body.query.redirects[0].to.escapeFormatting() ).setURL( pagelink ).setThumbnail( wiki.toLink('Special:FilePath/Wiki-wordmark.png') );
  429. msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
  430. if ( reaction ) reaction.removeEmoji();;
  431. }
  432. else {
  433. var pagelink = wiki.toLink(body.query.general.mainpage, querystring, fragment);
  434. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( body.query.general.mainpage.escapeFormatting() ).setURL( pagelink ).setThumbnail( wiki.toLink('Special:FilePath/Wiki-wordmark.png') );
  435. if ( body.query.allmessages[0]['*'] ) {
  436. embed.setDescription( body.query.allmessages[0]['*'] );
  437. msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
  438. if ( reaction ) reaction.removeEmoji();
  439. }
  440. else got.get( wiki.toDescLink(body.query.general.mainpage), {
  441. responseType: 'text'
  442. } ).then( descresponse => {
  443. var descbody = descresponse.body;
  444. if ( descresponse.statusCode !== 200 || !descbody ) {
  445. console.log( '- ' + descresponse.statusCode + ': Error while getting the description.' );
  446. } else {
  447. var parser = new htmlparser.Parser( {
  448. onopentag: (tagname, attribs) => {
  449. if ( tagname === 'meta' && attribs.property === 'og:description' ) {
  450. var description = attribs.content.escapeFormatting();
  451. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  452. embed.setDescription( description );
  453. }
  454. }
  455. }, {decodeEntities:true} );
  456. parser.write( descbody );
  457. parser.end();
  458. }
  459. }, error => {
  460. console.log( '- Error while getting the description: ' + error );
  461. } ).finally( () => {
  462. msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
  463. if ( reaction ) reaction.removeEmoji();
  464. } );
  465. }
  466. }, error => {
  467. if ( interwiki ) msg.sendChannel( spoiler + ' ' + interwiki + ' ' + spoiler );
  468. else if ( wiki.noWiki(error.message) ) {
  469. console.log( '- This wiki doesn\'t exist!' );
  470. msg.reactEmoji('nowiki');
  471. }
  472. else {
  473. console.log( '- Error while getting the search results: ' + error );
  474. msg.sendChannelError( spoiler + '<' + wiki.toLink(( querystring.toString() || fragment || !title ? title : 'Special:Search' ), ( querystring.toString() || fragment || !title ? querystring : {search:title} ), fragment) + '>' + spoiler );
  475. }
  476. if ( reaction ) reaction.removeEmoji();
  477. } );
  478. }
  479. module.exports = fandom_check_wiki;