random.js 4.5 KB

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