ソースを参照

Move input_to_wiki function

Markus-Rost 4 年 前
コミット
5bb1d7e14b
4 ファイル変更60 行追加79 行削除
  1. 14 3
      cmds/eval.js
  2. 5 42
      cmds/rcscript.js
  3. 1 34
      cmds/settings.js
  4. 40 0
      util/wiki.js

+ 14 - 3
cmds/eval.js

@@ -1,6 +1,7 @@
 const util = require('util');
 util.inspect.defaultOptions = {compact:false,breakLength:Infinity};
 
+const cheerio = require('cheerio');
 const Discord = require('discord.js');
 const {limit: {verification: verificationLimit, rcgcdw: rcgcdwLimit}} = require('../util/default.json');
 const newMessage = require('../util/newMessage.js');
@@ -56,16 +57,26 @@ function database(sql, sqlargs = []) {
  * @param {Wiki} wiki - The wiki to check.
  */
 function checkWiki(wiki) {
-	wiki = new Wiki(wiki);
-	return got.get( wiki + 'api.php?action=query' + ( wiki.isFandom() ? '&meta=siteinfo&siprop=variables' : '' ) + '&list=recentchanges&rcshow=!bot&rctype=edit|new|log|categorize&rcprop=ids&rclimit=1&format=json' ).then( response => {
+	wiki = Wiki.fromInput(wiki);
+	return got.get( wiki + 'api.php?&action=query&meta=siteinfo&siprop=general' + ( wiki.isFandom() ? '|variables' : '' ) + '&list=recentchanges&rcshow=!bot&rctype=edit|new|log|categorize&rcprop=ids&rclimit=1&format=json' ).then( response => {
+		if ( response.statusCode === 404 && typeof response.body === 'string' ) {
+			let api = cheerio.load(response.body)('head link[rel="EditURI"]').prop('href');
+			if ( api ) {
+				wiki = new Wiki(api.split('api.php?')[0], wiki);
+				return got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general' + ( wiki.isFandom() ? '|variables' : '' ) + '&list=recentchanges&rcshow=!bot&rctype=edit|new|log|categorize&rcprop=ids&rclimit=1&format=json' );
+			}
+		}
+		return response;
+	} ).then( response => {
 		var body = response.body;
 		if ( response.statusCode !== 200 || !body?.query?.recentchanges ) {
 			return response.statusCode + ': Error while getting the recent changes: ' + body?.error?.info;
 		}
+		wiki.updateWiki(body.query.general);
 		var result = {
 			wiki: wiki.href,
 			rcid: ( body.query.recentchanges[0]?.rcid || 0 ),
-			wikiid: body.query.variables?.find?.( variable => variable?.id === 'wgCityId' )?.['*'],
+			wikiid: ( body.query.variables?.find?.( variable => variable?.id === 'wgCityId' )?.['*'] || null ),
 			postid: null
 		}
 		return Promise.all([

+ 5 - 42
cmds/rcscript.js

@@ -8,10 +8,6 @@ var db = require('../util/database.js');
 const fs = require('fs');
 const rcscriptExists = fs.existsSync('./RcGcDb/start.py');
 
-var allSites = [];
-const getAllSites = require('../util/allSites.js');
-getAllSites.then( sites => allSites = sites );
-
 const display_types = [
 	'compact',
 	'embed',
@@ -62,7 +58,7 @@ function cmd_rcscript(lang, msg, args, line, wiki) {
 			var input = args.slice(1).join(' ').toLowerCase().trim().replace( /^<\s*(.*?)\s*>$/, '$1' );
 			var wikinew = new Wiki(wiki);
 			if ( input ) {
-				wikinew = input_to_wiki(input.replace( /^(?:https?:)?\/\//, 'https://' ));
+				wikinew = Wiki.fromInput(input);
 				if ( !wikinew ) return msg.replyMsg( wikiinvalid, {}, true );
 			}
 			return msg.reactEmoji('⏳', true).then( reaction => got.get( wikinew + 'api.php?&action=query&meta=allmessages|siteinfo&ammessages=custom-RcGcDw|recentchanges&amenableparser=true&siprop=general' + ( wiki.isFandom() ? '|variables' : '' ) + '&titles=Special:RecentChanges&format=json' ).then( response => {
@@ -222,7 +218,7 @@ function cmd_rcscript(lang, msg, args, line, wiki) {
 				if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, {}, true );
 
 				var wikiinvalid = lang.get('settings.wikiinvalid') + '\n`' + cmd + ' wiki ' + lang.get('rcscript.new_wiki') + '`\n' + lang.get('rcscript.help_wiki');
-				var wikinew = input_to_wiki(args[1].replace( /^(?:https?:)?\/\//, 'https://' ));
+				var wikinew = Wiki.fromInput(args[1]);
 				if ( !wikinew ) return msg.replyMsg( wikiinvalid, {}, true );
 				return msg.reactEmoji('⏳', true).then( reaction => got.get( wikinew + 'api.php?&action=query&meta=allmessages|siteinfo&ammessages=custom-RcGcDw&amenableparser=true&siprop=general' + ( wiki.isFandom() ? '|variables' : '' ) + '&titles=Special:RecentChanges&format=json' ).then( response => {
 					if ( response.statusCode === 404 && typeof response.body === 'string' ) {
@@ -551,7 +547,7 @@ function blocklist(msg, args) {
 		if ( !args[1] ) return msg.replyMsg( '`' + prefix + 'rcscript block add <wiki> [<reason>]`', {}, true );
 		if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, {}, true );
 		let input = args[1].toLowerCase().replace( /^<(.*?)>$/, '$1' );
-		let wiki = input_to_wiki(input.replace( /^(?:https?:)?\/\//, 'https://' ));
+		let wiki = Wiki.fromInput(input);
 		if ( !wiki ) return msg.replyMsg( '`' + prefix + 'rcscript block add <wiki> [<reason>]`', {}, true );
 		let reason = ( args.slice(2).join(' ').trim() || null );
 		return db.run( 'INSERT INTO blocklist(wiki, reason) VALUES(?, ?)', [wiki.href, reason], function (error) {
@@ -588,7 +584,7 @@ function blocklist(msg, args) {
 	}
 	if ( args[0] === 'remove' ) {
 		let input = args.slice(1).join(' ').toLowerCase().trim().replace( /^<\s*(.*?)\s*>$/, '$1' );
-		let wiki = input_to_wiki(input.replace( /^(?:https?:)?\/\//, 'https://' ));
+		let wiki = Wiki.fromInput(input);
 		if ( !wiki ) return msg.replyMsg( '`' + prefix + 'rcscript block remove <wiki>`', {}, true );
 		if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, {}, true );
 		return db.run( 'DELETE FROM blocklist WHERE wiki = ?', [wiki.href], function (error) {
@@ -603,7 +599,7 @@ function blocklist(msg, args) {
 	}
 	if ( args.length ) {
 		let input = args.join(' ').toLowerCase().trim().replace( /^<\s*(.*?)\s*>$/, '$1' );
-		let wiki = input_to_wiki(input.replace( /^(?:https?:)?\/\//, 'https://' ));
+		let wiki = Wiki.fromInput(input);
 		if ( !wiki ) return msg.replyMsg( '`' + prefix + 'rcscript block <wiki>`\n`' + prefix + 'rcscript block add <wiki> [<reason>]`\n`' + prefix + 'rcscript block remove <wiki>`', {}, true );
 		return db.get( 'SELECT reason FROM blocklist WHERE wiki = ?', [wiki.href], function (error, row) {
 			if ( error ) {
@@ -626,39 +622,6 @@ function blocklist(msg, args) {
 	} );
 }
 
-/**
- * Turn user input into a wiki.
- * @param {String} input - The user input referring to a wiki.
- * @returns {Wiki}
- */
-function input_to_wiki(input) {
-	var regex = input.match( /^(?:https:\/\/)?([a-z\d-]{1,50}\.(?:gamepedia\.com|(?:fandom\.com|wikia\.org)(?:(?!\/(?:wiki|api)\/)\/[a-z-]{2,12})?))(?:\/|$)/ );
-	if ( regex ) return new Wiki('https://' + regex[1] + '/');
-	if ( input.startsWith( 'https://' ) ) {
-		let project = wikiProjects.find( project => input.split('/')[2].endsWith( project.name ) );
-		if ( project ) {
-			regex = input.match( new RegExp( project.regex + `(?:${project.articlePath}|${project.scriptPath}|/?$)` ) );
-			if ( regex ) return new Wiki('https://' + regex[1] + project.scriptPath);
-		}
-		let wiki = input.replace( /\/(?:api|load|index)\.php(?:|\?.*)$/, '/' );
-		if ( !wiki.endsWith( '/' ) ) wiki += '/';
-		return new Wiki(wiki);
-	}
-	let project = wikiProjects.find( project => input.split('/')[0].endsWith( project.name ) );
-	if ( project ) {
-		regex = input.match( new RegExp( project.regex + `(?:${project.articlePath}|${project.scriptPath}|/?$)` ) );
-		if ( regex ) return new Wiki('https://' + regex[1] + project.scriptPath);
-	}
-	if ( allSites.some( site => site.wiki_domain === input + '.gamepedia.com' ) ) {
-		return new Wiki('https://' + input + '.gamepedia.com/');
-	}
-	if ( /^(?:[a-z-]{2,12}\.)?[a-z\d-]{1,50}$/.test(input) ) {
-		if ( !input.includes( '.' ) ) return new Wiki('https://' + input + '.fandom.com/');
-		else return new Wiki('https://' + input.split('.')[1] + '.fandom.com/' + input.split('.')[0] + '/');
-	}
-	return;
-}
-
 module.exports = {
 	name: 'rcscript',
 	everyone: rcscriptExists,

+ 1 - 34
cmds/settings.js

@@ -84,7 +84,7 @@ function cmd_settings(lang, msg, args, line, wiki) {
 				[args[1], ...value] = args[1].split(/>? /);
 				if ( value.join(' ') === '--force' ) isForced = true;
 			}
-			var wikinew = input_to_wiki(args[1]);
+			var wikinew = Wiki.fromInput(args[1]);
 			if ( !wikinew ) {
 				var text = lang.get('settings.wikiinvalid') + wikihelp;
 				var sites = allSites.filter( site => site.wiki_display_name.toLowerCase().includes( args[1] ) );
@@ -355,39 +355,6 @@ function cmd_settings(lang, msg, args, line, wiki) {
 	} );
 }
 
-/**
- * Turn user input into a wiki.
- * @param {String} input - The user input referring to a wiki.
- * @returns {Wiki}
- */
-function input_to_wiki(input) {
-	var regex = input.match( /^(?:https:\/\/)?([a-z\d-]{1,50}\.(?:gamepedia\.com|(?:fandom\.com|wikia\.org)(?:(?!\/(?:wiki|api)\/)\/[a-z-]{2,12})?))(?:\/|$)/ );
-	if ( regex ) return new Wiki('https://' + regex[1] + '/');
-	if ( input.startsWith( 'https://' ) ) {
-		let project = wikiProjects.find( project => input.split('/')[2].endsWith( project.name ) );
-		if ( project ) {
-			regex = input.match( new RegExp( project.regex + `(?:${project.articlePath}|${project.scriptPath}|/?$)` ) );
-			if ( regex ) return new Wiki('https://' + regex[1] + project.scriptPath);
-		}
-		let wiki = input.replace( /\/(?:api|load|index)\.php(?:|\?.*)$/, '/' );
-		if ( !wiki.endsWith( '/' ) ) wiki += '/';
-		return new Wiki(wiki);
-	}
-	let project = wikiProjects.find( project => input.split('/')[0].endsWith( project.name ) );
-	if ( project ) {
-		regex = input.match( new RegExp( project.regex + `(?:${project.articlePath}|${project.scriptPath}|/?$)` ) );
-		if ( regex ) return new Wiki('https://' + regex[1] + project.scriptPath);
-	}
-	if ( allSites.some( site => site.wiki_domain === input + '.gamepedia.com' ) ) {
-		return new Wiki('https://' + input + '.gamepedia.com/');
-	}
-	if ( /^(?:[a-z-]{2,12}\.)?[a-z\d-]{1,50}$/.test(input) ) {
-		if ( !input.includes( '.' ) ) return new Wiki('https://' + input + '.fandom.com/');
-		else return new Wiki('https://' + input.split('.')[1] + '.fandom.com/' + input.split('.')[0] + '/');
-	}
-	return;
-}
-
 module.exports = {
 	name: 'settings',
 	everyone: true,

+ 40 - 0
util/wiki.js

@@ -1,6 +1,10 @@
 const util = require('util');
 const {defaultSettings, wikiProjects} = require('./default.json');
 
+var allSites = [];
+const getAllSites = require('../util/allSites.js');
+getAllSites.then( sites => allSites = sites );
+
 /**
  * A wiki.
  * @class Wiki
@@ -186,6 +190,42 @@ class Wiki extends URL {
 		} ).replace( /%3A/g, ':' ).replace( /%/g, '.' );
 	}
 
+	/**
+	 * Turn user input into a wiki.
+	 * @param {String} input - The user input referring to a wiki.
+	 * @returns {Wiki}
+	 * @static
+	 */
+	static fromInput(input = '') {
+		if ( input instanceof URL ) return new this(input);
+		input = input.replace( /^(?:https?:)?\/\//, 'https://' );
+		var regex = input.match( /^(?:https:\/\/)?([a-z\d-]{1,50}\.(?:gamepedia\.com|(?:fandom\.com|wikia\.org)(?:(?!\/(?:wiki|api)\/)\/[a-z-]{2,12})?))(?:\/|$)/ );
+		if ( regex ) return new this('https://' + regex[1] + '/');
+		if ( input.startsWith( 'https://' ) ) {
+			let project = wikiProjects.find( project => input.split('/')[2].endsWith( project.name ) );
+			if ( project ) {
+				regex = input.match( new RegExp( project.regex + `(?:${project.articlePath}|${project.scriptPath}|/?$)` ) );
+				if ( regex ) return new this('https://' + regex[1] + project.scriptPath);
+			}
+			let wiki = input.replace( /\/(?:api|load|index)\.php(?:|\?.*)$/, '/' );
+			if ( !wiki.endsWith( '/' ) ) wiki += '/';
+			return new this(wiki);
+		}
+		let project = wikiProjects.find( project => input.split('/')[0].endsWith( project.name ) );
+		if ( project ) {
+			regex = input.match( new RegExp( project.regex + `(?:${project.articlePath}|${project.scriptPath}|/?$)` ) );
+			if ( regex ) return new this('https://' + regex[1] + project.scriptPath);
+		}
+		if ( allSites.some( site => site.wiki_domain === input + '.gamepedia.com' ) ) {
+			return new this('https://' + input + '.gamepedia.com/');
+		}
+		if ( /^(?:[a-z-]{2,12}\.)?[a-z\d-]{1,50}$/.test(input) ) {
+			if ( !input.includes( '.' ) ) return new this('https://' + input + '.fandom.com/');
+			else return new this('https://' + input.split('.')[1] + '.fandom.com/' + input.split('.')[0] + '/');
+		}
+		return null;
+	}
+
 	[util.inspect.custom](depth, opts) {
 		if ( typeof depth === 'number' && depth < 0 ) return this;
 		const wiki = {