gamepedia.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. const htmlparser = require('htmlparser2');
  2. const {MessageEmbed} = require('discord.js');
  3. const Lang = require('../../util/i18n.js');
  4. const extract_desc = require('../../util/extract_desc.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/gamepedia', (error, files) => {
  11. if ( error ) return error;
  12. files.filter( file => file.endsWith('.js') ).forEach( file => {
  13. var command = require('./gamepedia/' + file);
  14. fn[command.name] = command.run;
  15. } );
  16. } );
  17. var minecraft = {};
  18. fs.readdir( './cmds/minecraft', (error, files) => {
  19. if ( error ) return error;
  20. files.filter( file => file.endsWith('.js') ).forEach( file => {
  21. var command = require('../minecraft/' + file);
  22. minecraft[command.name] = command.run;
  23. } );
  24. } );
  25. function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '', querystring = '', fragment = '', selfcall = 0) {
  26. var full_title = title;
  27. if ( title.includes( '#' ) ) {
  28. fragment = title.split('#').slice(1).join('#');
  29. title = title.split('#')[0];
  30. }
  31. if ( /\?\w+=/.test(title) ) {
  32. var querystart = title.search(/\?\w+=/);
  33. querystring = title.substring(querystart + 1) + ( querystring ? '&' + querystring : '' );
  34. title = title.substring(0, querystart);
  35. }
  36. if ( title.length > 250 ) {
  37. title = title.substring(0, 250);
  38. msg.reactEmoji('⚠️');
  39. }
  40. var invoke = title.split(' ')[0].toLowerCase();
  41. var aliasInvoke = ( lang.get('aliases')[invoke] || invoke );
  42. var args = title.split(' ').slice(1);
  43. var mcaliasInvoke = ( lang.get('minecraft.aliases')[invoke] || invoke );
  44. if ( !msg.notMinecraft && wiki === lang.get('minecraft.link') && ( mcaliasInvoke in minecraft || invoke.startsWith( '/' ) ) ) {
  45. minecraft.WIKI = this;
  46. if ( mcaliasInvoke in minecraft ) minecraft[mcaliasInvoke](lang, msg, args, title, cmd, querystring, fragment, reaction, spoiler);
  47. else minecraft.SYNTAX(lang, msg, invoke.substring(1), args, title, cmd, querystring, fragment, reaction, spoiler);
  48. }
  49. else if ( aliasInvoke === 'random' && !args.join('') && !querystring && !fragment ) fn.random(lang, msg, wiki, reaction, spoiler);
  50. else if ( aliasInvoke === 'overview' && !args.join('') && !querystring && !fragment ) fn.overview(lang, msg, wiki, reaction, spoiler);
  51. else if ( aliasInvoke === 'page' ) {
  52. msg.sendChannel( spoiler + '<' + wiki.toLink(args.join('_'), querystring.toTitle(), fragment) + '>' + spoiler );
  53. if ( reaction ) reaction.removeEmoji();
  54. }
  55. else if ( aliasInvoke === 'diff' && args.join('') && !querystring && !fragment ) fn.diff(lang, msg, args, wiki, reaction, spoiler);
  56. else {
  57. var noRedirect = ( /(?:^|&)redirect=no(?:&|$)/.test(querystring) || /(?:^|&)action=(?!view(?:&|$))/.test(querystring) );
  58. got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|specialpagealiases&iwurl=true' + ( noRedirect ? '' : '&redirects=true' ) + '&prop=pageimages|categoryinfo|pageprops|extracts&piprop=original|name&ppprop=description|displaytitle&explaintext=true&exsectionformat=raw&exlimit=1&titles=' + encodeURIComponent( title ) + '&format=json', {
  59. responseType: 'json'
  60. } ).then( response => {
  61. var body = response.body;
  62. if ( body && body.warnings ) log_warn(body.warnings);
  63. if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query ) {
  64. if ( wiki.noWiki(response.url) || response.statusCode === 410 ) {
  65. console.log( '- This wiki doesn\'t exist!' );
  66. msg.reactEmoji('nowiki');
  67. }
  68. else {
  69. console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
  70. msg.sendChannelError( spoiler + '<' + wiki.toLink( ( querystring || fragment || !title ? title : 'Special:Search' ), ( querystring || fragment || !title ? querystring.toTitle() : 'search=' + title.toSearch() ), fragment) + '>' + spoiler );
  71. }
  72. if ( reaction ) reaction.removeEmoji();
  73. }
  74. else if ( aliasInvoke === 'search' ) {
  75. fn.search(lang, msg, full_title.split(' ').slice(1).join(' '), wiki, body.query, reaction, spoiler);
  76. }
  77. else if ( aliasInvoke === 'discussion' && wiki.isFandom() && !querystring && !fragment ) {
  78. fn.discussion(lang, msg, wiki, args.join(' '), body.query, reaction, spoiler);
  79. }
  80. else {
  81. if ( body.query.pages ) {
  82. var querypages = Object.values(body.query.pages);
  83. var querypage = querypages[0];
  84. 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, '_' ) ) ) {
  85. querypage.title = body.query.redirects[0].from;
  86. delete body.query.redirects[0].tofragment;
  87. delete querypage.missing;
  88. querypage.ns = -1;
  89. querypage.special = '';
  90. }
  91. if ( querypages.length !== 1 ) querypage = {
  92. title: title,
  93. invalidreason: 'The requested page title contains invalid characters: "|".',
  94. invalid: ''
  95. }
  96. var contribs = body.query.namespaces['-1']['*'] + ':' + body.query.specialpagealiases.find( sp => sp.realname === 'Contributions' ).aliases[0] + '/';
  97. if ( ( querypage.ns === 2 || querypage.ns === 202 || querypage.ns === 1200 ) && ( !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) ) ) {
  98. var userparts = querypage.title.split(':');
  99. querypage.noRedirect = noRedirect;
  100. fn.user(lang, msg, userparts[0].toTitle() + ':', userparts.slice(1).join(':'), wiki, querystring, fragment, querypage, contribs.toTitle(), reaction, spoiler);
  101. }
  102. else if ( querypage.ns === -1 && querypage.title.startsWith( contribs ) && querypage.title.length > contribs.length ) {
  103. var username = querypage.title.split('/').slice(1).join('/');
  104. got.get( wiki + 'api.php?action=query&titles=User:' + encodeURIComponent( username ) + '&format=json', {
  105. responseType: 'json'
  106. } ).then( uresponse => {
  107. var ubody = uresponse.body;
  108. if ( uresponse.statusCode !== 200 || !ubody || ubody.batchcomplete === undefined || !ubody.query ) {
  109. console.log( '- ' + uresponse.statusCode + ': Error while getting the user: ' + ( ubody && ubody.error && ubody.error.info ) );
  110. msg.sendChannelError( spoiler + '<' + wiki.toLink(contribs + username, querystring.toTitle(), fragment, body.query.general) + '>' + spoiler );
  111. if ( reaction ) reaction.removeEmoji();
  112. }
  113. else {
  114. querypage = Object.values(ubody.query.pages)[0];
  115. if ( querypage.ns === 2 ) {
  116. username = querypage.title.split(':').slice(1).join(':');
  117. querypage.title = contribs + username;
  118. delete querypage.missing;
  119. querypage.ns = -1;
  120. querypage.special = '';
  121. querypage.noRedirect = noRedirect;
  122. fn.user(lang, msg, contribs.toTitle(), username, wiki, querystring, fragment, querypage, contribs.toTitle(), reaction, spoiler);
  123. }
  124. else {
  125. msg.reactEmoji('error');
  126. if ( reaction ) reaction.removeEmoji();
  127. }
  128. }
  129. }, error => {
  130. console.log( '- Error while getting the user: ' + error );
  131. msg.sendChannelError( spoiler + '<' + wiki.toLink(contribs + username, querystring.toTitle(), fragment, body.query.general) + '>' + spoiler );
  132. if ( reaction ) reaction.removeEmoji();
  133. } );
  134. }
  135. else if ( ( querypage.missing !== undefined && querypage.known === undefined && !( noRedirect || querypage.categoryinfo ) ) || querypage.invalid !== undefined ) {
  136. got.get( wiki + 'api.php?action=query&prop=pageimages|categoryinfo|pageprops|extracts&piprop=original|name&ppprop=description|displaytitle&explaintext=true&exsectionformat=raw&exlimit=1&generator=search&gsrnamespace=4|12|14|' + Object.values(body.query.namespaces).filter( ns => ns.content !== undefined ).map( ns => ns.id ).join('|') + '&gsrlimit=1&gsrsearch=' + encodeURIComponent( title ) + '&format=json', {
  137. responseType: 'json'
  138. } ).then( srresponse => {
  139. var srbody = srresponse.body;
  140. if ( srbody && srbody.warnings ) log_warn(srbody.warnings);
  141. if ( srresponse.statusCode !== 200 || !srbody || srbody.batchcomplete === undefined ) {
  142. console.log( '- ' + srresponse.statusCode + ': Error while getting the search results: ' + ( srbody && srbody.error && srbody.error.info ) );
  143. msg.sendChannelError( spoiler + '<' + wiki.toLink('Special:Search', 'search=' + title.toSearch(), '', body.query.general) + '>' + spoiler );
  144. }
  145. else {
  146. if ( !srbody.query ) {
  147. msg.reactEmoji('🤷');
  148. }
  149. else {
  150. querypage = Object.values(srbody.query.pages)[0];
  151. var pagelink = wiki.toLink(querypage.title, querystring.toTitle(), fragment, body.query.general);
  152. var text = '';
  153. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
  154. if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
  155. var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
  156. if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
  157. embed.setTitle( displaytitle );
  158. }
  159. if ( querypage.extract ) {
  160. var extract = extract_desc(querypage.extract, fragment);
  161. embed.setDescription( extract[0] );
  162. if ( extract[2].length ) embed.addField( extract[1], extract[2] );
  163. }
  164. if ( querypage.pageprops && querypage.pageprops.description ) {
  165. var description = htmlToPlain( querypage.pageprops.description );
  166. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  167. embed.setDescription( description );
  168. }
  169. if ( querypage.pageimage && querypage.original && querypage.title !== body.query.general.mainpage ) {
  170. var pageimage = querypage.original.source;
  171. if ( querypage.ns === 6 ) {
  172. if ( msg.showEmbed() && /\.(?:png|jpg|jpeg|gif)$/.test(querypage.pageimage.toLowerCase()) ) embed.setImage( pageimage );
  173. else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pageimage,name:( spoiler ? 'SPOILER ' : '' ) + querypage.pageimage}] );
  174. } else embed.setThumbnail( pageimage );
  175. } else embed.setThumbnail( ( body.query.general.logo.startsWith( '//' ) ? 'https:' : '' ) + body.query.general.logo );
  176. var prefix = ( msg.channel.type === 'text' && patreons[msg.guild.id] || process.env.prefix );
  177. var linksuffix = ( querystring ? '?' + querystring : '' ) + ( fragment ? '#' + fragment : '' );
  178. if ( title.replace( /\-/g, ' ' ).toTitle().toLowerCase() === querypage.title.replace( /\-/g, ' ' ).toTitle().toLowerCase() ) {
  179. text = '';
  180. }
  181. else if ( !srbody.continue ) {
  182. text = '\n' + lang.get('search.infopage').replaceSave( '%s', '`' + prefix + cmd + lang.get('search.page') + ' ' + title + linksuffix + '`' );
  183. }
  184. else {
  185. text = '\n' + lang.get('search.infosearch').replaceSave( '%1$s', '`' + prefix + cmd + lang.get('search.page') + ' ' + title + linksuffix + '`' ).replaceSave( '%2$s', '`' + prefix + cmd + lang.get('search.search') + ' ' + title + linksuffix + '`' );
  186. }
  187. if ( querypage.categoryinfo ) {
  188. var langCat = new Lang(lang.lang, 'search.category');
  189. var category = [langCat.get('content')];
  190. if ( querypage.categoryinfo.size === 0 ) category.push(langCat.get('empty'));
  191. if ( querypage.categoryinfo.pages > 0 ) {
  192. let pages = querypage.categoryinfo.pages;
  193. let count = langCat.get('pages');
  194. category.push(( count[pages] || count['*' + pages % 100] || count['*' + pages % 10] || langCat.get('pages.default') ).replaceSave( '%s', pages ));
  195. }
  196. if ( querypage.categoryinfo.files > 0 ) {
  197. let files = querypage.categoryinfo.files;
  198. let count = langCat.get('files');
  199. category.push(( count[files] || count['*' + files % 100] || count['*' + files % 10] || langCat.get('files.default') ).replaceSave( '%s', files ));
  200. }
  201. if ( querypage.categoryinfo.subcats > 0 ) {
  202. let subcats = querypage.categoryinfo.subcats;
  203. let count = langCat.get('subcats');
  204. category.push(( count[subcats] || count['*' + subcats % 100] || count['*' + subcats % 10] || langCat.get('subcats.default') ).replaceSave( '%s', subcats ));
  205. }
  206. if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
  207. else text += '\n\n' + category.join('\n');
  208. }
  209. msg.sendChannel( spoiler + '<' + pagelink + '>' + text + spoiler, {embed} );
  210. }
  211. }
  212. }, error => {
  213. console.log( '- Error while getting the search results: ' + error );
  214. msg.sendChannelError( spoiler + '<' + wiki.toLink('Special:Search', 'search=' + title.toSearch(), '', body.query.general) + '>' + spoiler );
  215. } ).finally( () => {
  216. if ( reaction ) reaction.removeEmoji();
  217. } );
  218. }
  219. else if ( querypage.ns === -1 ) {
  220. var pagelink = wiki.toLink(querypage.title, querystring.toTitle(), fragment, body.query.general);
  221. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink ).setThumbnail( ( body.query.general.logo.startsWith( '//' ) ? 'https:' : '' ) + body.query.general.logo );
  222. var specialpage = body.query.specialpagealiases.find( sp => body.query.namespaces['-1']['*'] + ':' + sp.aliases[0].replace( /\_/g, ' ' ) === querypage.title.split('/')[0] );
  223. specialpage = ( specialpage ? specialpage.realname : querypage.title.replace( body.query.namespaces['-1']['*'] + ':', '' ).split('/')[0] ).toLowerCase();
  224. fn.special_page(lang, msg, querypage.title, specialpage, embed, wiki, reaction, spoiler);
  225. }
  226. else {
  227. var pagelink = wiki.toLink(querypage.title, querystring.toTitle(), ( fragment || ( body.query.redirects && body.query.redirects[0].tofragment ) || '' ), body.query.general);
  228. var text = '';
  229. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
  230. if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
  231. var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
  232. if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
  233. embed.setTitle( displaytitle );
  234. }
  235. if ( querypage.extract ) {
  236. var extract = extract_desc(querypage.extract, ( fragment || ( body.query.redirects && body.query.redirects[0].tofragment ) || '' ));
  237. embed.setDescription( extract[0] );
  238. if ( extract[2].length ) embed.addField( extract[1], extract[2] );
  239. }
  240. if ( querypage.pageprops && querypage.pageprops.description ) {
  241. var description = htmlToPlain( querypage.pageprops.description );
  242. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  243. embed.setDescription( description );
  244. }
  245. if ( querypage.pageimage && querypage.original && querypage.title !== body.query.general.mainpage ) {
  246. var pageimage = querypage.original.source;
  247. if ( querypage.ns === 6 ) {
  248. if ( msg.showEmbed() && /\.(?:png|jpg|jpeg|gif)$/.test(querypage.pageimage.toLowerCase()) ) embed.setImage( pageimage );
  249. else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pageimage,name:( spoiler ? 'SPOILER ' : '' ) + querypage.pageimage}] );
  250. } else embed.setThumbnail( pageimage );
  251. } else embed.setThumbnail( ( body.query.general.logo.startsWith( '//' ) ? 'https:' : '' ) + body.query.general.logo );
  252. if ( querypage.categoryinfo ) {
  253. var langCat = new Lang(lang.lang, 'search.category');
  254. var category = [langCat.get('content')];
  255. if ( querypage.categoryinfo.size === 0 ) category.push(langCat.get('empty'));
  256. if ( querypage.categoryinfo.pages > 0 ) {
  257. let pages = querypage.categoryinfo.pages;
  258. let count = langCat.get('pages');
  259. category.push(( count[pages] || count['*' + pages % 100] || count['*' + pages % 10] || langCat.get('pages.default') ).replaceSave( '%s', pages ));
  260. }
  261. if ( querypage.categoryinfo.files > 0 ) {
  262. let files = querypage.categoryinfo.files;
  263. let count = langCat.get('files');
  264. category.push(( count[files] || count['*' + files % 100] || count['*' + files % 10] || langCat.get('files.default') ).replaceSave( '%s', files ));
  265. }
  266. if ( querypage.categoryinfo.subcats > 0 ) {
  267. let subcats = querypage.categoryinfo.subcats;
  268. let count = langCat.get('subcats');
  269. category.push(( count[subcats] || count['*' + subcats % 100] || count['*' + subcats % 10] || langCat.get('subcats.default') ).replaceSave( '%s', subcats ));
  270. }
  271. if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
  272. else text += '\n\n' + category.join('\n');
  273. }
  274. msg.sendChannel( spoiler + '<' + pagelink + '>' + text + spoiler, {embed} );
  275. if ( reaction ) reaction.removeEmoji();
  276. }
  277. }
  278. else if ( body.query.interwiki ) {
  279. var inter = body.query.interwiki[0];
  280. var intertitle = inter.title.substring(inter.iw.length + 1);
  281. var regex = inter.url.match( /^(?:https?:)?\/\/([a-z\d-]{1,50})\.gamepedia\.com(?:\/|$)/ );
  282. var maxselfcall = ( msg.channel.type === 'text' && msg.guild.id in patreons ? 10 : 5 );
  283. if ( regex !== null && selfcall < maxselfcall ) {
  284. if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
  285. var iwtitle = decodeURIComponent( inter.url.replace( regex[0], '' ) ).replace( /\_/g, ' ' ).replaceSave( intertitle.replace( /\_/g, ' ' ), intertitle );
  286. selfcall++;
  287. this.gamepedia(lang, msg, iwtitle, 'https://' + regex[1] + '.gamepedia.com/', '!' + regex[1] + ' ', reaction, spoiler, querystring, fragment, selfcall);
  288. } else {
  289. if ( reaction ) reaction.removeEmoji();
  290. console.log( '- Aborted, paused.' );
  291. }
  292. } else {
  293. regex = inter.url.match( /^(?:https?:)?\/\/(([a-z\d-]{1,50})\.(?:fandom\.com|wikia\.org)(?:(?!\/wiki\/)\/([a-z-]{2,8}))?)(?:\/wiki\/|\/?$)/ );
  294. if ( regex !== null && selfcall < maxselfcall ) {
  295. if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
  296. var iwtitle = decodeURIComponent( inter.url.replace( regex[0], '' ) ).replace( /\_/g, ' ' ).replaceSave( intertitle.replace( /\_/g, ' ' ), intertitle );
  297. selfcall++;
  298. this.fandom(lang, msg, iwtitle, 'https://' + regex[1] + '/', '?' + ( regex[3] ? regex[3] + '.' : '' ) + regex[2] + ' ', reaction, spoiler, querystring, fragment, selfcall);
  299. } else {
  300. if ( reaction ) reaction.removeEmoji();
  301. console.log( '- Aborted, paused.' );
  302. }
  303. } else {
  304. regex = inter.url.match( /^(?:https?:)?\/\/([a-z\d-]{1,50}\.(?:wikipedia|mediawiki|wiktionary|wikimedia|wikibooks|wikisource|wikidata|wikiversity|wikiquote|wikinews|wikivoyage)\.org)(?:\/wiki\/|\/?$)/ );
  305. if ( regex !== null && selfcall < maxselfcall ) {
  306. if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
  307. var iwtitle = decodeURIComponent( inter.url.replace( regex[0], '' ) ).replace( /\_/g, ' ' ).replaceSave( intertitle.replace( /\_/g, ' ' ), intertitle );
  308. selfcall++;
  309. this.gamepedia(lang, msg, iwtitle, 'https://' + regex[1] + '/w/', cmd + inter.iw + ':', reaction, spoiler, querystring, fragment, selfcall);
  310. } else {
  311. if ( reaction ) reaction.removeEmoji();
  312. console.log( '- Aborted, paused.' );
  313. }
  314. } else {
  315. if ( fragment ) fragment = '#' + fragment.toSection();
  316. if ( inter.url.includes( '#' ) ) {
  317. if ( !fragment ) fragment = '#' + inter.url.split('#').slice(1).join('#');
  318. inter.url = inter.url.split('#')[0];
  319. }
  320. if ( querystring ) inter.url += ( inter.url.includes( '?' ) ? '&' : '?' ) + querystring.toTitle();
  321. msg.sendChannel( spoiler + ' ' + inter.url.replace( /@(here|everyone)/g, '%40$1' ) + fragment + ' ' + spoiler ).then( message => {
  322. if ( message && selfcall === maxselfcall ) message.reactEmoji('⚠️');
  323. } );
  324. if ( reaction ) reaction.removeEmoji();
  325. }
  326. }
  327. }
  328. }
  329. else if ( body.query.redirects ) {
  330. var pagelink = wiki.toLink(body.query.redirects[0].to, querystring.toTitle(), ( fragment || body.query.redirects[0].tofragment || '' ), body.query.general);
  331. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( body.query.redirects[0].to.escapeFormatting() ).setURL( pagelink ).setThumbnail( ( body.query.general.logo.startsWith( '//' ) ? 'https:' : '' ) + body.query.general.logo );
  332. msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
  333. if ( reaction ) reaction.removeEmoji();;
  334. }
  335. else {
  336. var pagelink = wiki.toLink(body.query.general.mainpage, querystring.toTitle(), fragment, body.query.general);
  337. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( body.query.general.mainpage.escapeFormatting() ).setURL( pagelink ).setThumbnail( ( body.query.general.logo.startsWith( '//' ) ? 'https:' : '' ) + body.query.general.logo );
  338. got.get( wiki + 'api.php?action=query' + ( noRedirect ? '' : '&redirects=true' ) + '&prop=pageprops|extracts&ppprop=description|displaytitle&explaintext=true&exsectionformat=raw&exlimit=1&titles=' + encodeURIComponent( body.query.general.mainpage ) + '&format=json', {
  339. responseType: 'json'
  340. } ).then( mpresponse => {
  341. var mpbody = mpresponse.body;
  342. if ( mpbody && mpbody.warnings ) log_warn(body.warnings);
  343. if ( mpresponse.statusCode !== 200 || !mpbody || mpbody.batchcomplete === undefined || !mpbody.query ) {
  344. console.log( '- ' + mpresponse.statusCode + ': Error while getting the main page: ' + ( mpbody && mpbody.error && mpbody.error.info ) );
  345. } else {
  346. var querypage = Object.values(mpbody.query.pages)[0];
  347. if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
  348. var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
  349. if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
  350. embed.setTitle( displaytitle );
  351. }
  352. if ( querypage.extract ) {
  353. var extract = extract_desc(querypage.extract, fragment);
  354. embed.setDescription( extract[0] );
  355. if ( extract[2].length ) embed.addField( extract[1], extract[2] );
  356. }
  357. if ( querypage.pageprops && querypage.pageprops.description ) {
  358. var description = htmlToPlain( querypage.pageprops.description );
  359. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  360. embed.setDescription( description );
  361. }
  362. }
  363. }, error => {
  364. console.log( '- Error while getting the main page: ' + error );
  365. } ).finally( () => {
  366. msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
  367. if ( reaction ) reaction.removeEmoji();
  368. } );
  369. }
  370. }
  371. }, error => {
  372. if ( wiki.noWiki(error.message) ) {
  373. console.log( '- This wiki doesn\'t exist!' );
  374. msg.reactEmoji('nowiki');
  375. }
  376. else {
  377. console.log( '- Error while getting the search results: ' + error );
  378. msg.sendChannelError( spoiler + '<' + wiki.toLink( ( querystring || fragment || !title ? title : 'Special:Search' ), ( querystring || fragment || !title ? querystring.toTitle() : 'search=' + title.toSearch() ), fragment) + '>' + spoiler );
  379. }
  380. if ( reaction ) reaction.removeEmoji();
  381. } );
  382. }
  383. }
  384. function htmlToPlain(html) {
  385. var text = '';
  386. var parser = new htmlparser.Parser( {
  387. ontext: (htmltext) => {
  388. text += htmltext.escapeFormatting();
  389. }
  390. }, {decodeEntities:true} );
  391. parser.write( html );
  392. parser.end();
  393. return text;
  394. };
  395. function htmlToDiscord(html) {
  396. var text = '';
  397. var parser = new htmlparser.Parser( {
  398. onopentag: (tagname, attribs) => {
  399. switch (tagname) {
  400. case 'b':
  401. text += '**';
  402. break;
  403. case 'i':
  404. text += '*';
  405. break;
  406. case 's':
  407. text += '~~';
  408. break;
  409. case 'u':
  410. text += '__';
  411. break;
  412. }
  413. },
  414. ontext: (htmltext) => {
  415. text += htmltext.escapeFormatting();
  416. },
  417. onclosetag: (tagname) => {
  418. switch (tagname) {
  419. case 'b':
  420. text += '**';
  421. break;
  422. case 'i':
  423. text += '*';
  424. break;
  425. case 's':
  426. text += '~~';
  427. break;
  428. case 'u':
  429. text += '__';
  430. break;
  431. }
  432. }
  433. }, {decodeEntities:true} );
  434. parser.write( html );
  435. parser.end();
  436. return text;
  437. };
  438. module.exports = gamepedia_check_wiki;