random.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. const htmlparser = require('htmlparser2');
  2. const {MessageEmbed} = require('discord.js');
  3. const parse_page = require('../../../functions/parse_page.js');
  4. const extract_desc = require('../../../util/extract_desc.js');
  5. /**
  6. * Sends a random Gamepedia page.
  7. * @param {import('../../../util/i18n.js')} lang - The user language.
  8. * @param {import('discord.js').Message} msg - The Discord message.
  9. * @param {import('../../../util/wiki.js')} wiki - The wiki for the page.
  10. * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  11. * @param {String} spoiler - If the response is in a spoiler.
  12. */
  13. function gamepedia_random(lang, msg, wiki, reaction, spoiler) {
  14. got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&prop=pageimages|pageprops|extracts&piprop=original|name&ppprop=description|displaytitle|page_image_free&explaintext=true&exsectionformat=raw&exlimit=1&generator=random&grnnamespace=0&format=json' ).then( response => {
  15. var body = response.body;
  16. if ( body && body.warnings ) log_warn(body.warnings);
  17. if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query || !body.query.pages ) {
  18. if ( wiki.noWiki(response.url) || response.statusCode === 410 ) {
  19. console.log( '- This wiki doesn\'t exist!' );
  20. msg.reactEmoji('nowiki');
  21. }
  22. else {
  23. console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
  24. msg.sendChannelError( spoiler + '<' + wiki.toLink('Special:Random') + '>' + spoiler );
  25. }
  26. }
  27. else {
  28. var querypage = Object.values(body.query.pages)[0];
  29. var pagelink = wiki.updateWiki(body.query.general).toLink(querypage.title);
  30. var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
  31. if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
  32. var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
  33. if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
  34. embed.setTitle( displaytitle );
  35. }
  36. if ( querypage.pageprops && querypage.pageprops.description ) {
  37. var description = htmlToPlain( querypage.pageprops.description );
  38. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  39. embed.setDescription( description );
  40. }
  41. else if ( querypage.extract ) {
  42. var extract = extract_desc(querypage.extract);
  43. embed.setDescription( extract[0] );
  44. }
  45. if ( querypage.title === body.query.general.mainpage ) {
  46. embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
  47. }
  48. else if ( querypage.pageimage && querypage.original ) {
  49. embed.setThumbnail( querypage.original.source );
  50. }
  51. else if ( querypage.pageprops && querypage.pageprops.page_image_free ) {
  52. embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
  53. }
  54. else embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
  55. msg.sendChannel( '🎲 ' + spoiler + '<' + pagelink + '>' + spoiler, {embed} ).then( message => parse_page(message, querypage.title, embed, wiki, ( querypage.title === body.query.general.mainpage ? '' : new URL(body.query.general.logo, wiki).href )) );
  56. }
  57. }, error => {
  58. if ( wiki.noWiki(error.message) ) {
  59. console.log( '- This wiki doesn\'t exist!' );
  60. msg.reactEmoji('nowiki');
  61. }
  62. else {
  63. console.log( '- Error while getting the search results: ' + error );
  64. msg.sendChannelError( spoiler + '<' + wiki.toLink('Special:Random') + '>' + spoiler );
  65. }
  66. } ).finally( () => {
  67. if ( reaction ) reaction.removeEmoji();
  68. } );
  69. }
  70. /**
  71. * Change HTML text to plain text.
  72. * @param {String} html - The text in HTML.
  73. * @returns {String}
  74. */
  75. function htmlToPlain(html) {
  76. var text = '';
  77. var parser = new htmlparser.Parser( {
  78. ontext: (htmltext) => {
  79. text += htmltext.escapeFormatting();
  80. }
  81. }, {decodeEntities:true} );
  82. parser.write( html );
  83. parser.end();
  84. return text;
  85. };
  86. /**
  87. * Change HTML text to markdown text.
  88. * @param {String} html - The text in HTML.
  89. * @returns {String}
  90. */
  91. function htmlToDiscord(html) {
  92. var text = '';
  93. var parser = new htmlparser.Parser( {
  94. onopentag: (tagname, attribs) => {
  95. switch (tagname) {
  96. case 'b':
  97. text += '**';
  98. break;
  99. case 'i':
  100. text += '*';
  101. break;
  102. case 's':
  103. text += '~~';
  104. break;
  105. case 'u':
  106. text += '__';
  107. break;
  108. }
  109. },
  110. ontext: (htmltext) => {
  111. text += htmltext.escapeFormatting();
  112. },
  113. onclosetag: (tagname) => {
  114. switch (tagname) {
  115. case 'b':
  116. text += '**';
  117. break;
  118. case 'i':
  119. text += '*';
  120. break;
  121. case 's':
  122. text += '~~';
  123. break;
  124. case 'u':
  125. text += '__';
  126. break;
  127. }
  128. }
  129. }, {decodeEntities:true} );
  130. parser.write( html );
  131. parser.end();
  132. return text;
  133. };
  134. module.exports = {
  135. name: 'random',
  136. run: gamepedia_random
  137. };