Browse Source

Add MediaWiki system message embed content
close #231

Markus-Rost 3 years ago
parent
commit
6cf13f0262
7 changed files with 106 additions and 18 deletions
  1. 0 3
      bot.js
  2. 25 12
      dashboard/src/index.js
  3. 1 1
      dashboard/verification.js
  4. 73 2
      functions/parse_page.js
  5. 2 0
      i18n/de.json
  6. 2 0
      i18n/en.json
  7. 3 0
      util/globals.js

+ 0 - 3
bot.js

@@ -1,6 +1,5 @@
 import './util/globals.js';
 import {readdir} from 'fs';
-import {inspect} from 'util';
 import Discord from 'discord.js';
 import db from './util/database.js';
 import Lang from './util/i18n.js';
@@ -8,8 +7,6 @@ import Wiki from './util/wiki.js';
 import newMessage from './util/newMessage.js';
 import {breakOnTimeoutPause, allowDelete} from './util/functions.js';
 
-inspect.defaultOptions = {compact: false, breakLength: Infinity};
-
 const client = new Discord.Client( {
 	makeCache: Discord.Options.cacheWithLimits( {
 		MessageManager: {

+ 25 - 12
dashboard/src/index.js

@@ -431,19 +431,32 @@ if ( usergroup ) {
 		}
 	} );
 
-	function fillUsergroupList({query: {allmessages: wikiUsergroupList = []} = {}} = {}) {
+	function fillUsergroupList({query: {allmessages: wikiUsergroupList = [], usergroups: wikiUsergroupListPermissions = []} = {}} = {}) {
 		if ( !wikiUsergroupList.length ) return;
-		usergrouplist.replaceChildren(...wikiUsergroupList.filter( wikigroup => {
-			if ( wikigroup.name === 'group-all' ) return false;
-			if ( wikigroup.name === 'group-membership-link-with-expiry' ) return false;
-			if ( wikigroup.name.endsWith( '.css' ) || wikigroup.name.endsWith( '.js' ) ) return false;
-			if ( wikigroup.name.endsWith( '-member' ) && wikiUsergroupList.some( wikigroupmember => {
-				return wikigroupmember.name === wikigroup.name.replace( /-member$/, '' );
-			} ) ) return false;
-			return true;
-		} ).map( wikigroup => {
-			return new Option(wikigroup['*'], wikigroup.name.replace( /^group-/, '' ));
-		} ).sort( (a, b) => {
+		usergrouplist.replaceChildren(...[
+			...wikiUsergroupList.filter( wikigroup => {
+				if ( wikigroup.name === 'group-all' ) return false;
+				if ( wikigroup.name === 'group-membership-link-with-expiry' ) return false;
+				if ( wikigroup.name.endsWith( '.css' ) || wikigroup.name.endsWith( '.js' ) ) return false;
+				if ( wikigroup.name.endsWith( '-member' ) && wikiUsergroupList.some( wikigroupmember => {
+					return wikigroupmember.name === wikigroup.name.replace( /-member$/, '' );
+				} ) ) return false;
+				return true;
+			} ).map( wikigroup => {
+				return new Option(wikigroup['*'], wikigroup.name.replace( /^group-/, '' ));
+			} ),
+			...wikiUsergroupListPermissions.map( wikigroup => wikigroup.name ).filter( function(wikigroup) {
+				if ( wikigroup === '*' ) return false;
+				if ( wikiUsergroupList.some( wikigroupmember => {
+					if ( 'group-' + wikigroup === wikigroupmember.name ) return true;
+					if ( 'group-' + wikigroup + '-member' === wikigroupmember.name ) return true;
+					return false;
+				} ) ) return false;
+				return true;
+			} ).map( wikigroup => {
+				return new Option(wikigroup, wikigroup);
+			} )
+		].sort( (a, b) => {
 			if ( a.value < b.value ) return -1;
 			if ( a.value > b.value ) return 1;
 			return 0;

+ 1 - 1
dashboard/verification.js

@@ -197,7 +197,7 @@ function createForm($, header, dashboardLang, settings, guildChannels, guildRole
 		usergroup.find('#wb-settings-usergroup-multiple').attr('style', 'display: none;');
 	}
 	fields.push(usergroup);
-	$('<script>').attr('src', wiki + 'api.php?action=query&meta=allmessages&amprefix=group-&amincludelocal=true&amenableparser=true&amlang=' + dashboardLang.lang + '&format=json&callback=fillUsergroupList').attr('defer', '').insertAfter('script#indexjs');
+	$('<script>').attr('src', wiki + 'api.php?action=query&meta=allmessages|siteinfo&amprefix=group-&amincludelocal=true&amenableparser=true&amlang=' + dashboardLang.lang + '&siprop=usergroups&format=json&callback=fillUsergroupList').attr('defer', '').insertAfter('script#indexjs');
 	let editcount = $('<div>').append(fieldset.editcount);
 	editcount.find('label').text(dashboardLang.get('verification.form.editcount'));
 	editcount.find('#wb-settings-editcount').val(settings.editcount);

+ 73 - 2
functions/parse_page.js

@@ -81,9 +81,12 @@ const removeClassesExceptions = [
  * @param {import('../util/wiki.js').default} wiki - The wiki for the page.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {Object} querypage - The details of the page.
+ * @param {Number} querypage.ns - The namespace of the page.
  * @param {String} querypage.title - The title of the page.
  * @param {String} querypage.contentmodel - The content model of the page.
+ * @param {String} querypage.pagelanguage - The language of the page.
  * @param {String} [querypage.missing] - If the page doesn't exist.
+ * @param {String} [querypage.known] - If the page is known.
  * @param {Object} [querypage.pageprops] - The properties of the page.
  * @param {String} [querypage.pageprops.infoboxes] - The JSON data for portable infoboxes on the page.
  * @param {String} [querypage.pageprops.disambiguation] - The disambiguation property of the page.
@@ -94,9 +97,9 @@ const removeClassesExceptions = [
  * @param {String} [pagelink] - The link to the page.
  * @returns {Promise<import('discord.js').Message>} The edited message.
  */
-export default function parse_page(lang, msg, content, embed, wiki, reaction, {title, contentmodel, missing, pageprops: {infoboxes, disambiguation} = {}, uselang = lang.lang, noRedirect = false}, thumbnail = '', fragment = '', pagelink = '') {
+export default function parse_page(lang, msg, content, embed, wiki, reaction, {ns, title, contentmodel, pagelanguage, missing, known, pageprops: {infoboxes, disambiguation} = {}, uselang = lang.lang, noRedirect = false}, thumbnail = '', fragment = '', pagelink = '') {
 	if ( reaction ) reaction.removeEmoji();
-	if ( !msg?.showEmbed?.() || missing !== undefined || !embed || embed.description ) {
+	if ( !msg?.showEmbed?.() || ( missing !== undefined && ( ns !== 8 || known === undefined ) ) || !embed || embed.description ) {
 		if ( missing !== undefined && embed ) {
 			if ( embed.backupField && embed.length < 4750 && embed.fields.length < 25 ) {
 				embed.spliceFields( 0, 0, embed.backupField );
@@ -112,6 +115,74 @@ export default function parse_page(lang, msg, content, embed, wiki, reaction, {t
 		embeds: [new MessageEmbed(embed).setDescription( '<a:loading:641343250661113886> **' + lang.get('search.loading') + '**' )]
 	} ).then( message => {
 		if ( !message ) return;
+		if ( ns === 8 ) {
+			title = title.split(':').slice(1).join(':');
+			if ( title.endsWith( '/' + pagelanguage ) ) title = title.substring(0, title.length - ( pagelanguage.length + 1 ));
+			return got.get( wiki + 'api.php?action=query&meta=allmessages&amprop=default&amincludelocal=true&amlang=' + encodeURIComponent( pagelanguage ) + '&ammessages=' + encodeURIComponent( title ) + '&format=json', {
+				timeout: {
+					request: 10_000
+				}
+			} ).then( response => {
+				var body = response.body;
+				if ( body && body.warnings ) log_warning(body.warnings);
+				if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query?.allmessages?.[0] ) {
+					console.log( '- ' + response.statusCode + ': Error while getting the system message: ' + body?.error?.info );
+					if ( embed.backupField && embed.length < 4750 && embed.fields.length < 25 ) {
+						embed.spliceFields( 0, 0, embed.backupField );
+					}
+					if ( embed.backupDescription && embed.length < 5000 ) {
+						embed.setDescription( embed.backupDescription );
+					}
+					return;
+				}
+				if ( !embed.description && embed.length < 4000 ) {
+					var description = body.query.allmessages[0]['*'];
+					var regex = /^L(\d+)(?:-L?(\d+))?$/.exec(fragment);
+					if ( regex ) {
+						let descArray = description.split('\n').slice(regex[1] - 1, ( regex[2] || regex[1] ));
+						if ( descArray.length ) {
+							description = descArray.join('\n').replace( /^\n+/, '' ).replace( /\n+$/, '' );
+							if ( description ) {
+								if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
+								description = '```' + ( contentModels[contentmodel] || '' ) + '\n' + description + '\n```';
+								embed.setDescription( description );
+							}
+						}
+					}
+					else {
+						let defaultDescription = body.query.allmessages[0].default;
+						if ( description.trim() ) {
+							description = description.replace( /^\n+/, '' ).replace( /\n+$/, '' );
+							if ( description.length > 500 ) description = description.substring(0, 500) + '\u2026';
+							description = '```' + ( contentModels[contentmodel] || '' ) + '\n' + description + '\n```';
+							embed.setDescription( description );
+						}
+						else if ( embed.backupDescription ) {
+							embed.setDescription( embed.backupDescription );
+						}
+						if ( defaultDescription?.trim() ) {
+							defaultDescription = defaultDescription.replace( /^\n+/, '' ).replace( /\n+$/, '' );
+							if ( defaultDescription.length > 250 ) defaultDescription = defaultDescription.substring(0, 250) + '\u2026';
+							defaultDescription = '```' + ( contentModels[contentmodel] || '' ) + '\n' + defaultDescription + '\n```';
+							embed.addField( lang.get('search.messagedefault'), defaultDescription );
+						}
+						else if ( body.query.allmessages[0].defaultmissing !== undefined ) {
+							embed.addField( lang.get('search.messagedefault'), lang.get('search.messagedefaultnone') );
+						}
+					}
+				}
+			}, error => {
+				console.log( '- Error while getting the system message: ' + error );
+				if ( embed.backupField && embed.length < 4750 && embed.fields.length < 25 ) {
+					embed.spliceFields( 0, 0, embed.backupField );
+				}
+				if ( embed.backupDescription && embed.length < 5000 ) {
+					embed.setDescription( embed.backupDescription );
+				}
+			} ).then( () => {
+				return message.edit( {content, embeds: [embed]} ).catch(log_error);
+			} );
+		}
 		if ( !parsedContentModels.includes( contentmodel ) ) return got.get( wiki + 'api.php?action=query&prop=revisions&rvprop=content&rvslots=main&converttitles=true&titles=%1F' + encodeURIComponent( title ) + '&format=json', {
 			timeout: {
 				request: 10_000

+ 2 - 0
i18n/de.json

@@ -591,6 +591,8 @@
         "infosearch": "Nicht das richtige Ergebnis? Nutze $1 für einen direkten Link oder $2 für eine Liste mit allen Treffern.",
         "loading": "Lade Seitenbeschreibung…",
         "media": "Zur Dateibeschreibungsseite",
+        "messagedefault": "Standardwert:",
+        "messagedefaultnone": "*keiner*",
         "results": "$1 {{PLURAL:$2|Ergebnis|Ergebnisse}} insgesamt",
         "special": "Inhalt der Spezialseite:"
     },

+ 2 - 0
i18n/en.json

@@ -591,6 +591,8 @@
         "infosearch": "Not the correct result? Use $1 for a direct link or $2 for a list of all hits.",
         "loading": "Loading page description…",
         "media": "To the file description page",
+        "messagedefault": "Default:",
+        "messagedefaultnone": "*none*",
         "results": "$1 total {{PLURAL:$2|result|results}}",
         "special": "Content of this special page:"
     },

+ 3 - 0
util/globals.js

@@ -1,3 +1,6 @@
+import {inspect} from 'util';
+inspect.defaultOptions = {compact: false, breakLength: Infinity};
+
 /**
  * If debug logging is enabled.
  * @type {Boolean}