소스 검색

Log usage statistics

Markus-Rost 4 년 전
부모
커밋
a29f4fed3d
14개의 변경된 파일395개의 추가작업 그리고 340개의 파일을 삭제
  1. 3 1
      .env.example
  2. 1 0
      .gitignore
  3. 2 0
      cmds/test.js
  4. 3 0
      cmds/verify.js
  5. 86 85
      cmds/wiki/diff.js
  6. 2 0
      cmds/wiki/fandom/diff.js
  7. 7 0
      cmds/wiki/fandom/general.js
  8. 2 0
      cmds/wiki/fandom/overview.js
  9. 4 1
      cmds/wiki/fandom/random.js
  10. 7 0
      cmds/wiki/general.js
  11. 216 215
      cmds/wiki/overview.js
  12. 40 38
      cmds/wiki/random.js
  13. 19 0
      util/logging.js
  14. 3 0
      util/newMessage.js

+ 3 - 1
.env.example

@@ -19,4 +19,6 @@ channel="464098946894004224"
 # Invite link to the bot help Discord
 invite="https://discord.gg/v77RTk5"
 # Link to the patreon page for the bot
-patreon="https://www.patreon.com/WikiBot"
+patreon="https://www.patreon.com/WikiBot"
+# Path to a log file for usage statistics
+usagelog=""

+ 1 - 0
.gitignore

@@ -1,5 +1,6 @@
 node_modules/
 *.env
 *.db
+*.log
 *.code-workspace
 *.bat

+ 2 - 0
cmds/test.js

@@ -1,5 +1,6 @@
 const {MessageEmbed} = require('discord.js');
 const help_setup = require('../functions/helpsetup.js');
+const logging = require('../util/logging.js');
 
 const wsStatus = [
 	'READY',
@@ -82,6 +83,7 @@ function cmd_test(lang, msg, args, line, wiki) {
 				}
 				embed.addField( wiki, ping );
 			} ).finally( () => {
+				logging(wiki, 'test');
 				if ( msg.isOwner() ) return msg.client.shard.fetchClientValues('ws.status').then( values => {
 					return '```css\n' + values.map( (status, id) => '[' + id + ']: ' + ( wsStatus[status] || status ) ).join('\n') + '\n```';
 				}, error => {

+ 3 - 0
cmds/verify.js

@@ -1,5 +1,6 @@
 const cheerio = require('cheerio');
 const {MessageEmbed} = require('discord.js');
+const logging = require('../util/logging.js');
 const toTitle = require('../util/wiki.js').toTitle;
 var db = require('../util/database.js');
 
@@ -56,6 +57,7 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 					msg.reactEmoji('nowiki');
 				}
 				else if ( body?.error?.code === 'us400' ) { // special catch for Fandom
+					if ( !old_username ) logging(wiki, 'verification');
 					embed.setTitle( ( old_username || username ).escapeFormatting() ).setColor('#0000FF').setDescription( lang.get('verify.user_missing', ( old_username || username ).escapeFormatting()) );
 					msg.replyMsg( lang.get('verify.user_missing_reply', ( old_username || username ).escapeFormatting()), {embed}, false, false );
 				}
@@ -69,6 +71,7 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 				return;
 			}
 			wiki.updateWiki(body.query.general);
+			if ( !old_username ) logging(wiki, 'verification');
 			var queryuser = body.query.users[0];
 			embed.setAuthor( body.query.general.sitename );
 			if ( body.query.users.length !== 1 || queryuser.missing !== undefined || queryuser.invalid !== undefined ) {

+ 86 - 85
cmds/wiki/diff.js

@@ -1,4 +1,5 @@
 const {MessageEmbed} = require('discord.js');
+const logging = require('../../util/logging.js');
 const {timeoptions} = require('../../util/default.json');
 const {toFormatting, htmlToPlain} = require('../../util/functions.js');
 const diffParser = require('../../util/edit_diff.js');
@@ -168,110 +169,110 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 		}
 		else if ( body.query.pages && !body.query.pages['-1'] ) {
 			wiki.updateWiki(body.query.general);
+			logging(wiki, 'diff');
 			var pages = Object.values(body.query.pages);
 			if ( pages.length !== 1 ) {
 				msg.sendChannel( spoiler + '<' + wiki.toLink('Special:Diff/' + ( args[1] ? args[1] + '/' : '' ) + args[0]) + '>' + spoiler );
 				
 				if ( reaction ) reaction.removeEmoji();
+				return;
 			}
-			else {
-				var title = pages[0].title;
-				var revisions = pages[0].revisions.sort( (first, second) => Date.parse(second.timestamp) - Date.parse(first.timestamp) );
-				var diff = revisions[0].revid;
-				var oldid = ( revisions[1] ? revisions[1].revid : 0 );
-				var editor = [lang.get('diff.info.editor'), ( revisions[0].userhidden !== undefined ? lang.get('diff.hidden') : revisions[0].user )];
-				var timestamp = [lang.get('diff.info.timestamp'), new Date(revisions[0].timestamp).toLocaleString(lang.get('dateformat'), timeoptions)];
-				var difference = revisions[0].size - ( revisions[1] ? revisions[1].size : 0 );
-				var size = [lang.get('diff.info.size'), lang.get('diff.info.bytes', ( difference > 0 ? '+' : '' ) + difference)];
-				var comment = [lang.get('diff.info.comment'), ( revisions[0].commenthidden !== undefined ? lang.get('diff.hidden') : ( revisions[0].comment ? toFormatting(revisions[0].comment, msg.showEmbed(), wiki, title) : lang.get('diff.nocomment') ) )];
-				if ( revisions[0].tags.length ) var tags = [lang.get('diff.info.tags'), body.query.tags.filter( tag => revisions[0].tags.includes( tag.name ) ).map( tag => tag.displayname ).join(', ')];
+			var title = pages[0].title;
+			var revisions = pages[0].revisions.sort( (first, second) => Date.parse(second.timestamp) - Date.parse(first.timestamp) );
+			var diff = revisions[0].revid;
+			var oldid = ( revisions[1] ? revisions[1].revid : 0 );
+			var editor = [lang.get('diff.info.editor'), ( revisions[0].userhidden !== undefined ? lang.get('diff.hidden') : revisions[0].user )];
+			var timestamp = [lang.get('diff.info.timestamp'), new Date(revisions[0].timestamp).toLocaleString(lang.get('dateformat'), timeoptions)];
+			var difference = revisions[0].size - ( revisions[1] ? revisions[1].size : 0 );
+			var size = [lang.get('diff.info.size'), lang.get('diff.info.bytes', ( difference > 0 ? '+' : '' ) + difference)];
+			var comment = [lang.get('diff.info.comment'), ( revisions[0].commenthidden !== undefined ? lang.get('diff.hidden') : ( revisions[0].comment ? toFormatting(revisions[0].comment, msg.showEmbed(), wiki, title) : lang.get('diff.nocomment') ) )];
+			if ( revisions[0].tags.length ) var tags = [lang.get('diff.info.tags'), body.query.tags.filter( tag => revisions[0].tags.includes( tag.name ) ).map( tag => tag.displayname ).join(', ')];
+			
+			var pagelink = wiki.toLink(title, {diff,oldid});
+			if ( msg.showEmbed() ) {
+				var text = '<' + pagelink + '>';
+				var editorlink = '[' + editor[1] + '](' + wiki.toLink('User:' + editor[1], '', '', true) + ')';
+				if ( revisions[0].anon !== undefined ) {
+					editorlink = '[' + editor[1] + '](' + wiki.toLink('Special:Contributions/' + editor[1], '', '', true) + ')';
+				}
+				if ( editor[1] === lang.get('diff.hidden') ) editorlink = editor[1];
+				var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( ( title + '?diff=' + diff + '&oldid=' + oldid ).escapeFormatting() ).setURL( pagelink ).addField( editor[0], editorlink, true ).addField( size[0], size[1], true ).addField( comment[0], comment[1] ).setFooter( timestamp[1] );
+				if ( tags ) embed.addField( tags[0], htmlToPlain(tags[1]) );
 				
-				var pagelink = wiki.toLink(title, {diff,oldid});
-				if ( msg.showEmbed() ) {
-					var text = '<' + pagelink + '>';
-					var editorlink = '[' + editor[1] + '](' + wiki.toLink('User:' + editor[1], '', '', true) + ')';
-					if ( revisions[0].anon !== undefined ) {
-						editorlink = '[' + editor[1] + '](' + wiki.toLink('Special:Contributions/' + editor[1], '', '', true) + ')';
-					}
-					if ( editor[1] === lang.get('diff.hidden') ) editorlink = editor[1];
-					var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( ( title + '?diff=' + diff + '&oldid=' + oldid ).escapeFormatting() ).setURL( pagelink ).addField( editor[0], editorlink, true ).addField( size[0], size[1], true ).addField( comment[0], comment[1] ).setFooter( timestamp[1] );
-					if ( tags ) embed.addField( tags[0], htmlToPlain(tags[1]) );
-					
-					var more = '\n__' + lang.get('diff.info.more') + '__';
-					var whitespace = '__' + lang.get('diff.info.whitespace') + '__';
-					if ( !compare && oldid ) got.get( wiki + 'api.php?action=compare&prop=diff&fromrev=' + oldid + '&torev=' + diff + '&format=json' ).then( cpresponse => {
-						var cpbody = cpresponse.body;
-						if ( cpbody && cpbody.warnings ) log_warn(cpbody.warnings);
-						if ( cpresponse.statusCode !== 200 || !cpbody || !cpbody.compare || cpbody.compare['*'] === undefined ) {
-							var noerror = false;
-							if ( cpbody && cpbody.error ) {
-								switch ( cpbody.error.code ) {
-									case 'nosuchrevid':
-										noerror = true;
-										break;
-									case 'missingcontent':
-										noerror = true;
-										break;
-									default:
-										noerror = false;
-								}
-							}
-							if ( !noerror ) console.log( '- ' + cpresponse.statusCode + ': Error while getting the diff: ' + ( cpbody && cpbody.error && cpbody.error.info ) );
-						}
-						else if ( cpbody.compare.fromtexthidden === undefined && cpbody.compare.totexthidden === undefined && cpbody.compare.fromarchive === undefined && cpbody.compare.toarchive === undefined ) {
-							let edit_diff = diffParser( cpbody.compare['*'], more, whitespace )
-							if ( edit_diff[0].length ) {
-								embed.addField( lang.get('diff.info.removed'), edit_diff[0], true );
-							}
-							if ( edit_diff[1].length ) {
-								embed.addField( lang.get('diff.info.added'), edit_diff[1], true );
+				var more = '\n__' + lang.get('diff.info.more') + '__';
+				var whitespace = '__' + lang.get('diff.info.whitespace') + '__';
+				if ( !compare && oldid ) got.get( wiki + 'api.php?action=compare&prop=diff&fromrev=' + oldid + '&torev=' + diff + '&format=json' ).then( cpresponse => {
+					var cpbody = cpresponse.body;
+					if ( cpbody && cpbody.warnings ) log_warn(cpbody.warnings);
+					if ( cpresponse.statusCode !== 200 || !cpbody || !cpbody.compare || cpbody.compare['*'] === undefined ) {
+						var noerror = false;
+						if ( cpbody && cpbody.error ) {
+							switch ( cpbody.error.code ) {
+								case 'nosuchrevid':
+									noerror = true;
+									break;
+								case 'missingcontent':
+									noerror = true;
+									break;
+								default:
+									noerror = false;
 							}
 						}
-						else if ( cpbody.compare.fromtexthidden !== undefined ) {
-							embed.addField( lang.get('diff.info.removed'), '__' + lang.get('diff.hidden') + '__', true );
-						}
-						else if ( cpbody.compare.totexthidden !== undefined ) {
-							embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.hidden') + '__', true );
-						}
-					}, error => {
-						console.log( '- Error while getting the diff: ' + error );
-					} ).finally( () => {
-						msg.sendChannel( spoiler + text + spoiler, {embed} );
-						
-						if ( reaction ) reaction.removeEmoji();
-					} );
-					else {
-						if ( compare ) {
-							if ( compare[0].length ) embed.addField( lang.get('diff.info.removed'), compare[0], true );
-							if ( compare[1].length ) embed.addField( lang.get('diff.info.added'), compare[1], true );
+						if ( !noerror ) console.log( '- ' + cpresponse.statusCode + ': Error while getting the diff: ' + ( cpbody && cpbody.error && cpbody.error.info ) );
+					}
+					else if ( cpbody.compare.fromtexthidden === undefined && cpbody.compare.totexthidden === undefined && cpbody.compare.fromarchive === undefined && cpbody.compare.toarchive === undefined ) {
+						let edit_diff = diffParser( cpbody.compare['*'], more, whitespace )
+						if ( edit_diff[0].length ) {
+							embed.addField( lang.get('diff.info.removed'), edit_diff[0], true );
 						}
-						else if ( revisions[0]['*'] ) {
-							var content = revisions[0]['*'].escapeFormatting();
-							if ( content.trim().length ) {
-								if ( content.length <= 1000 ) content = '**' + content + '**';
-								else {
-									content = content.substring(0, 1000 - more.length);
-									content = '**' + content.substring(0, content.lastIndexOf('\n')) + '**' + more;
-								}
-								embed.addField( lang.get('diff.info.added'), content, true );
-							} else embed.addField( lang.get('diff.info.added'), whitespace, true );
+						if ( edit_diff[1].length ) {
+							embed.addField( lang.get('diff.info.added'), edit_diff[1], true );
 						}
-						
-						msg.sendChannel( spoiler + text + spoiler, {embed} );
-						
-						if ( reaction ) reaction.removeEmoji();
 					}
-				}
+					else if ( cpbody.compare.fromtexthidden !== undefined ) {
+						embed.addField( lang.get('diff.info.removed'), '__' + lang.get('diff.hidden') + '__', true );
+					}
+					else if ( cpbody.compare.totexthidden !== undefined ) {
+						embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.hidden') + '__', true );
+					}
+				}, error => {
+					console.log( '- Error while getting the diff: ' + error );
+				} ).finally( () => {
+					msg.sendChannel( spoiler + text + spoiler, {embed} );
+					
+					if ( reaction ) reaction.removeEmoji();
+				} );
 				else {
-					var embed = {};
-					var text = '<' + pagelink + '>\n\n' + editor.join(' ') + '\n' + timestamp.join(' ') + '\n' + size.join(' ') + '\n' + comment.join(' ');
-					if ( tags ) text += htmlToPlain( '\n' + tags.join(' ') );
+					if ( compare ) {
+						if ( compare[0].length ) embed.addField( lang.get('diff.info.removed'), compare[0], true );
+						if ( compare[1].length ) embed.addField( lang.get('diff.info.added'), compare[1], true );
+					}
+					else if ( revisions[0]['*'] ) {
+						var content = revisions[0]['*'].escapeFormatting();
+						if ( content.trim().length ) {
+							if ( content.length <= 1000 ) content = '**' + content + '**';
+							else {
+								content = content.substring(0, 1000 - more.length);
+								content = '**' + content.substring(0, content.lastIndexOf('\n')) + '**' + more;
+							}
+							embed.addField( lang.get('diff.info.added'), content, true );
+						} else embed.addField( lang.get('diff.info.added'), whitespace, true );
+					}
 					
 					msg.sendChannel( spoiler + text + spoiler, {embed} );
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
 			}
+			else {
+				var embed = {};
+				var text = '<' + pagelink + '>\n\n' + editor.join(' ') + '\n' + timestamp.join(' ') + '\n' + size.join(' ') + '\n' + comment.join(' ');
+				if ( tags ) text += htmlToPlain( '\n' + tags.join(' ') );
+				
+				msg.sendChannel( spoiler + text + spoiler, {embed} );
+				
+				if ( reaction ) reaction.removeEmoji();
+			}
 		}
 		else {
 			msg.reactEmoji('error');

+ 2 - 0
cmds/wiki/fandom/diff.js

@@ -1,4 +1,5 @@
 const {MessageEmbed} = require('discord.js');
+const logging = require('../../../util/logging.js');
 const {timeoptions} = require('../../../util/default.json');
 const {toFormatting, htmlToPlain} = require('../../../util/functions.js');
 const diffParser = require('../../../util/edit_diff.js');
@@ -155,6 +156,7 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 		}
 		else if ( body.query.pages && !body.query.pages['-1'] ) {
 			wiki.updateWiki(body.query.general);
+			logging(wiki, 'diff', 'legacy');
 			var pages = Object.values(body.query.pages);
 			if ( pages.length !== 1 ) {
 				msg.sendChannel( spoiler + '<' + wiki.toLink('Special:Diff/' + ( args[1] ? args[1] + '/' : '' ) + args[0]) + '>' + spoiler );

+ 7 - 0
cmds/wiki/fandom/general.js

@@ -1,5 +1,6 @@
 const htmlparser = require('htmlparser2');
 const {MessageEmbed} = require('discord.js');
+const logging = require('../../../util/logging.js');
 const {limit: {interwiki: interwikiLimit}, wikiProjects} = require('../../../util/default.json');
 const Wiki = require('../../../util/wiki.js');
 
@@ -88,12 +89,15 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 		}
 		wiki.updateWiki(body.query.general);
 		if ( aliasInvoke === 'search' ) {
+			logging(wiki, 'search', 'legacy');
 			return fn.search(lang, msg, full_title.split(' ').slice(1).join(' '), wiki, body.query, reaction, spoiler);
 		}
 		if ( aliasInvoke === 'discussion' && !querystring.toString() && !fragment ) {
+			logging(wiki, 'discussion', 'legacy');
 			return fn.discussion(lang, msg, wiki, args.join(' '), body.query.general.sitename, reaction, spoiler);
 		}
 		if ( body.query.pages ) {
+			logging(wiki, 'general', 'legacy');
 			var querypages = Object.values(body.query.pages);
 			var querypage = querypages[0];
 			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, '_' ) ) ) {
@@ -407,6 +411,7 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 				console.log( '- Aborted, paused.' );
 				return;
 			}
+			logging(wiki, 'interwiki', 'legacy');
 			var iw = new URL(body.query.interwiki[0].url.replace( /\\/g, '%5C' ).replace( /@(here|everyone)/g, '%40$1' ), wiki);
 			querystring.forEach( (value, name) => {
 				iw.searchParams.append(name, value);
@@ -446,6 +451,7 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 			if ( reaction ) reaction.removeEmoji();
 		}
 		else if ( body.query.redirects ) {
+			logging(wiki, 'general', 'legacy');
 			var pagelink = wiki.toLink(body.query.redirects[0].to, querystring, ( fragment || body.query.redirects[0].tofragment || '' ));
 			var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( body.query.redirects[0].to.escapeFormatting() ).setURL( pagelink ).setThumbnail( wiki.toLink('Special:FilePath/Wiki-wordmark.png') );
 			
@@ -454,6 +460,7 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 			if ( reaction ) reaction.removeEmoji();;
 		}
 		else {
+			logging(wiki, 'general', 'legacy');
 			var pagelink = wiki.toLink(body.query.general.mainpage, querystring, fragment);
 			var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( body.query.general.mainpage.escapeFormatting() ).setURL( pagelink ).setThumbnail( wiki.toLink('Special:FilePath/Wiki-wordmark.png') );
 			

+ 2 - 0
cmds/wiki/fandom/overview.js

@@ -1,4 +1,5 @@
 const {MessageEmbed} = require('discord.js');
+const logging = require('../../../util/logging.js');
 const {timeoptions} = require('../../../util/default.json');
 
 var allSites = [];
@@ -32,6 +33,7 @@ function fandom_overview(lang, msg, wiki, reaction, spoiler) {
 		}
 		else got.get( 'https://community.fandom.com/api/v1/Wikis/Details?ids=' + body.query.wikidesc.id + '&format=json&cache=' + Date.now() ).then( ovresponse => {
 			wiki.updateWiki(body.query.general);
+			logging(wiki, 'overview', 'legacy');
 			var ovbody = ovresponse.body;
 			if ( ovresponse.statusCode !== 200 || !ovbody || ovbody.exception || !ovbody.items || !ovbody.items[body.query.wikidesc.id] ) {
 				console.log( '- ' + ovresponse.statusCode + ': Error while getting the wiki details: ' + ( ovbody && ovbody.exception && ovbody.exception.details ) );

+ 4 - 1
cmds/wiki/fandom/random.js

@@ -1,5 +1,6 @@
 const htmlparser = require('htmlparser2');
 const {MessageEmbed} = require('discord.js');
+const logging = require('../../../util/logging.js');
 
 /**
  * Sends a random Fandom page.
@@ -26,8 +27,10 @@ function fandom_random(lang, msg, wiki, reaction, spoiler) {
 			if ( reaction ) reaction.removeEmoji();
 		}
 		else {
+			wiki.updateWiki(body.query.general);
+			logging(wiki, 'random', 'legacy');
 			var querypage = Object.values(body.query.pages)[0];
-			var pagelink = wiki.updateWiki(body.query.general).toLink(querypage.title);
+			var pagelink = wiki.toLink(querypage.title);
 			var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
 			if ( querypage.title === body.query.general.mainpage && body.query.allmessages[0]['*'] ) {
 				embed.setDescription( body.query.allmessages[0]['*'] );

+ 7 - 0
cmds/wiki/general.js

@@ -1,5 +1,6 @@
 const {MessageEmbed} = require('discord.js');
 const parse_page = require('../../functions/parse_page.js');
+const logging = require('../../util/logging.js');
 const {parse_infobox, htmlToPlain, htmlToDiscord} = require('../../util/functions.js');
 const extract_desc = require('../../util/extract_desc.js');
 const {limit: {interwiki: interwikiLimit}, wikiProjects} = require('../../util/default.json');
@@ -60,6 +61,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 	var args = title.split(' ').slice(1);
 	
 	if ( !msg.notMinecraft && wiki.href === lang.get('minecraft.link') && ( aliasInvoke in minecraft || invoke.startsWith( '/' ) ) ) {
+		logging(wiki, 'minecraft');
 		minecraft.WIKI = this;
 		if ( aliasInvoke in minecraft ) minecraft[aliasInvoke](lang, msg, args, title, cmd, querystring, fragment, reaction, spoiler);
 		else minecraft.SYNTAX(lang, msg, invoke.substring(1), args, title, cmd, querystring, fragment, reaction, spoiler);
@@ -107,15 +109,18 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 		}
 		wiki.updateWiki(body.query.general);
 		if ( aliasInvoke === 'search' ) {
+			logging(wiki, 'search');
 			return fn.search(lang, msg, full_title.split(' ').slice(1).join(' '), wiki, body.query, reaction, spoiler);
 		}
 		if ( aliasInvoke === 'diff' && args.join('') && !querystring.toString() && !fragment ) {
 			return fn.diff(lang, msg, args, wiki, reaction, spoiler);
 		}
 		if ( aliasInvoke === 'discussion' && wiki.isFandom(false) && !querystring.toString() && !fragment ) {
+			logging(wiki, 'discussion');
 			return fn.discussion(lang, msg, wiki, args.join(' '), body.query.general.sitename, reaction, spoiler);
 		}
 		if ( body.query.pages ) {
+			logging(wiki, 'general');
 			var querypages = Object.values(body.query.pages);
 			var querypage = querypages[0];
 			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, '_' ) ) ) {
@@ -373,6 +378,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 				console.log( '- Aborted, paused.' );
 				return;
 			}
+			logging(wiki, 'interwiki');
 			var iw = new URL(body.query.interwiki[0].url.replace( /\\/g, '%5C' ).replace( /@(here|everyone)/g, '%40$1' ), wiki);
 			querystring.forEach( (value, name) => {
 				iw.searchParams.append(name, value);
@@ -412,6 +418,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 			if ( reaction ) reaction.removeEmoji();
 		}
 		else {
+			logging(wiki, 'general');
 			var pagelink = wiki.toLink(body.query.general.mainpage, querystring, fragment);
 			var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( body.query.general.mainpage.escapeFormatting() ).setURL( pagelink ).setThumbnail( new URL(body.query.general.logo, wiki).href );
 			got.get( wiki + 'api.php?action=query' + ( noRedirect ? '' : '&redirects=true' ) + '&prop=pageprops|extracts&ppprop=description|displaytitle|infoboxes&explaintext=true&exsectionformat=raw&exlimit=1&titles=' + encodeURIComponent( body.query.general.mainpage ) + '&format=json' ).then( mpresponse => {

+ 216 - 215
cmds/wiki/overview.js

@@ -1,5 +1,6 @@
 const {MessageEmbed} = require('discord.js');
 const fandom_overview = require('./fandom/overview.js').run;
+const logging = require('../../util/logging.js');
 const {timeoptions} = require('../../util/default.json');
 const {toFormatting, toPlaintext} = require('../../util/functions.js');
 
@@ -34,237 +35,237 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 			}
 			
 			if ( reaction ) reaction.removeEmoji();
+			return;
 		}
-		else {
-			wiki.updateWiki(body.query.general);
-			var version = [lang.get('overview.version'), body.query.general.generator];
-			var creation_date = null;
-			var created = [lang.get('overview.created'), lang.get('overview.unknown')];
-			if ( body.query.logevents?.[0]?.timestamp ) {
-				creation_date = new Date(body.query.logevents[0].timestamp);
-				created[1] = creation_date.toLocaleString(lang.get('dateformat'), timeoptions);
-			}
-			var language = [lang.get('overview.lang'), body.query.languages.find( language => {
-				return language.code === body.query.general.lang;
-			} )['*']];
-			var rtl = [lang.get('overview.rtl'), ( body.query.general.rtl !== undefined ? lang.get('overview.yes') : undefined )];
-			var articles = [lang.get('overview.articles'), body.query.statistics.articles];
-			var pages = [lang.get('overview.pages'), body.query.statistics.pages];
-			var edits = [lang.get('overview.edits'), body.query.statistics.edits];
-			var users = [lang.get('overview.users'), body.query.statistics.activeusers];
-			var license = [lang.get('overview.license'), lang.get('overview.unknown')];
-			if ( body.query.rightsinfo.url ) {
-				let licenseurl = body.query.rightsinfo.url
-				if ( /^(?:https?:\/)?\//.test(licenseurl) ) licenseurl = new URL(licenseurl, wiki).href;
-				else licenseurl = wiki.toLink(licenseurl, '', '', true);
-				
-				if ( body.query.rightsinfo.text ) {
-					let licensetext = body.query.rightsinfo.text;
-					if ( msg.showEmbed() ) {
-						license[1] = '[' + toPlaintext(licensetext, true) + '](' + licenseurl + ')';
-					}
-					else license[1] = toPlaintext(licensetext, true) + ' (<' + licenseurl + '>)';
+		wiki.updateWiki(body.query.general);
+		logging(wiki, 'overview');
+		var version = [lang.get('overview.version'), body.query.general.generator];
+		var creation_date = null;
+		var created = [lang.get('overview.created'), lang.get('overview.unknown')];
+		if ( body.query.logevents?.[0]?.timestamp ) {
+			creation_date = new Date(body.query.logevents[0].timestamp);
+			created[1] = creation_date.toLocaleString(lang.get('dateformat'), timeoptions);
+		}
+		var language = [lang.get('overview.lang'), body.query.languages.find( language => {
+			return language.code === body.query.general.lang;
+		} )['*']];
+		var rtl = [lang.get('overview.rtl'), ( body.query.general.rtl !== undefined ? lang.get('overview.yes') : undefined )];
+		var articles = [lang.get('overview.articles'), body.query.statistics.articles];
+		var pages = [lang.get('overview.pages'), body.query.statistics.pages];
+		var edits = [lang.get('overview.edits'), body.query.statistics.edits];
+		var users = [lang.get('overview.users'), body.query.statistics.activeusers];
+		var license = [lang.get('overview.license'), lang.get('overview.unknown')];
+		if ( body.query.rightsinfo.url ) {
+			let licenseurl = body.query.rightsinfo.url
+			if ( /^(?:https?:\/)?\//.test(licenseurl) ) licenseurl = new URL(licenseurl, wiki).href;
+			else licenseurl = wiki.toLink(licenseurl, '', '', true);
+			
+			if ( body.query.rightsinfo.text ) {
+				let licensetext = body.query.rightsinfo.text;
+				if ( msg.showEmbed() ) {
+					license[1] = '[' + toPlaintext(licensetext, true) + '](' + licenseurl + ')';
 				}
-				else license[1] = '<' + licenseurl + '>';
+				else license[1] = toPlaintext(licensetext, true) + ' (<' + licenseurl + '>)';
 			}
-			else if ( body.query.rightsinfo.text ) {
-				license[1] = toFormatting(body.query.rightsinfo.text, msg.showEmbed(), wiki, '', true);
+			else license[1] = '<' + licenseurl + '>';
+		}
+		else if ( body.query.rightsinfo.text ) {
+			license[1] = toFormatting(body.query.rightsinfo.text, msg.showEmbed(), wiki, '', true);
+		}
+		var misermode = [lang.get('overview.misermode'), lang.get('overview.' + ( body.query.general.misermode !== undefined ? 'yes' : 'no' ))];
+		var readonly = [lang.get('overview.readonly')];
+		if ( body.query.general.readonly !== undefined ) {
+			if ( body.query.general.readonlyreason ) {
+				let readonlyreason = body.query.general.readonlyreason;
+				readonly.push(toFormatting(readonlyreason, msg.showEmbed(), wiki, '', true));
 			}
-			var misermode = [lang.get('overview.misermode'), lang.get('overview.' + ( body.query.general.misermode !== undefined ? 'yes' : 'no' ))];
-			var readonly = [lang.get('overview.readonly')];
-			if ( body.query.general.readonly !== undefined ) {
-				if ( body.query.general.readonlyreason ) {
-					let readonlyreason = body.query.general.readonlyreason;
-					readonly.push(toFormatting(readonlyreason, msg.showEmbed(), wiki, '', true));
-				}
-				else readonly = ['\u200b', '**' + lang.get('overview.readonly') + '**'];
+			else readonly = ['\u200b', '**' + lang.get('overview.readonly') + '**'];
+		}
+		
+		var title = body.query.pages['-1'].title;
+		var pagelink = wiki.toLink(title);
+		
+		if ( msg.showEmbed() ) {
+			var text = '<' + pagelink + '>';
+			var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( title.escapeFormatting() ).setURL( pagelink ).setThumbnail( new URL(body.query.general.logo, wiki).href );
+		}
+		else {
+			var embed = {};
+			var text = '<' + pagelink + '>\n';
+		}
+		
+		var wikiid = body.query.variables?.find?.( variable => variable?.id === 'wgCityId' )?.['*'];
+		if ( wiki.isFandom() && wikiid ) {
+			var vertical = [lang.get('overview.vertical')];
+			var topic = [lang.get('overview.topic')];
+			var official = [lang.get('overview.official')];
+			var posts = [lang.get('overview.posts')];
+			var walls = [lang.get('overview.walls')];
+			var comments = [lang.get('overview.comments')];
+			var manager = [lang.get('overview.manager'), body.query.allmessages[0]['*']];
+			var founder = [lang.get('overview.founder')];
+			var crossover = [lang.get('overview.crossover')];
+			if ( body.query.allmessages[1]['*'] ) {
+				crossover[1] = '<https://' + body.query.allmessages[1]['*'] + '.gamepedia.com/>';
 			}
-			
-			var title = body.query.pages['-1'].title;
-			var pagelink = wiki.toLink(title);
-			
-			if ( msg.showEmbed() ) {
-				var text = '<' + pagelink + '>';
-				var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( title.escapeFormatting() ).setURL( pagelink ).setThumbnail( new URL(body.query.general.logo, wiki).href );
+			else if ( body.query.allmessages[2]['*'] ) {
+				let merge = body.query.allmessages[2]['*'].split('/');
+				crossover[1] = '<https://' + merge[0] + '.fandom.com/' + ( merge[1] ? merge[1] + '/' : '' ) + '>';
 			}
-			else {
-				var embed = {};
-				var text = '<' + pagelink + '>\n';
+			var description = [lang.get('overview.description')];
+			var image = [lang.get('overview.image')];
+			if ( allSites.some( site => site.wiki_domain === wiki.hostname ) ) {
+				let site = allSites.find( site => site.wiki_domain === wiki.hostname );
+				
+				manager[1] = ( site.wiki_managers[0] || lang.get('overview.none') );
+				official[1] = lang.get('overview.' + ( site.official_wiki ? 'yes' : 'no' ));
+				if ( site.created && creation_date > new Date(parseInt(site.created + '000', 10)) ) {
+					creation_date = new Date(parseInt(site.created + '000', 10));
+					created[1] = creation_date.toLocaleString(lang.get('dateformat'), timeoptions);
+				}
+				if ( site.wiki_crossover ) crossover[1] = '<https://' + site.wiki_crossover + '/>';
+				if ( site.wiki_description ) {
+					description[1] = site.wiki_description.escapeFormatting();
+					if ( description[1].length > 1000 ) {
+						description[1] = description[1].substring(0, 1000) + '\u2026';
+					}
+				}
+				if ( site.wiki_image ) image[1] = new URL(site.wiki_image, wiki).href;
 			}
-			
-			var wikiid = body.query.variables?.find?.( variable => variable?.id === 'wgCityId' )?.['*'];
-			if ( wiki.isFandom() && wikiid ) {
-				var vertical = [lang.get('overview.vertical')];
-				var topic = [lang.get('overview.topic')];
-				var official = [lang.get('overview.official')];
-				var posts = [lang.get('overview.posts')];
-				var walls = [lang.get('overview.walls')];
-				var comments = [lang.get('overview.comments')];
-				var manager = [lang.get('overview.manager'), body.query.allmessages[0]['*']];
-				var founder = [lang.get('overview.founder')];
-				var crossover = [lang.get('overview.crossover')];
-				if ( body.query.allmessages[1]['*'] ) {
-					crossover[1] = '<https://' + body.query.allmessages[1]['*'] + '.gamepedia.com/>';
+			return got.get( 'https://community.fandom.com/api/v1/Wikis/Details?ids=' + wikiid + '&format=json&cache=' + Date.now() ).then( ovresponse => {
+				var ovbody = ovresponse.body;
+				if ( ovresponse.statusCode !== 200 || !ovbody || ovbody.exception || !ovbody.items || !ovbody.items[wikiid] ) {
+					console.log( '- ' + ovresponse.statusCode + ': Error while getting the wiki details: ' + ( ovbody && ovbody.exception && ovbody.exception.details ) );
+					return;
 				}
-				else if ( body.query.allmessages[2]['*'] ) {
-					let merge = body.query.allmessages[2]['*'].split('/');
-					crossover[1] = '<https://' + merge[0] + '.fandom.com/' + ( merge[1] ? merge[1] + '/' : '' ) + '>';
+				var site = ovbody.items[wikiid];
+				
+				vertical[1] = site.hub;
+				topic[1] = site.topic;
+				founder[1] = site.founding_user_id;
+				if ( site.creation_date && creation_date > new Date(site.creation_date) ) {
+					creation_date = new Date(site.creation_date);
+					created[1] = creation_date.toLocaleString(lang.get('dateformat'), timeoptions);
 				}
-				var description = [lang.get('overview.description')];
-				var image = [lang.get('overview.image')];
-				if ( allSites.some( site => site.wiki_domain === wiki.hostname ) ) {
-					let site = allSites.find( site => site.wiki_domain === wiki.hostname );
-					
-					manager[1] = ( site.wiki_managers[0] || lang.get('overview.none') );
-					official[1] = lang.get('overview.' + ( site.official_wiki ? 'yes' : 'no' ));
-					if ( site.created && creation_date > new Date(parseInt(site.created + '000', 10)) ) {
-						creation_date = new Date(parseInt(site.created + '000', 10));
-						created[1] = creation_date.toLocaleString(lang.get('dateformat'), timeoptions);
-					}
-					if ( site.wiki_crossover ) crossover[1] = '<https://' + site.wiki_crossover + '/>';
-					if ( site.wiki_description ) {
-						description[1] = site.wiki_description.escapeFormatting();
-						if ( description[1].length > 1000 ) {
-							description[1] = description[1].substring(0, 1000) + '\u2026';
-						}
+				if ( site.desc ) {
+					description[1] = site.desc.escapeFormatting();
+					if ( description[1].length > 1000 ) {
+						description[1] = description[1].substring(0, 1000) + '\u2026';
 					}
-					if ( site.wiki_image ) image[1] = new URL(site.wiki_image, wiki).href;
 				}
-				return got.get( 'https://community.fandom.com/api/v1/Wikis/Details?ids=' + wikiid + '&format=json&cache=' + Date.now() ).then( ovresponse => {
-					var ovbody = ovresponse.body;
-					if ( ovresponse.statusCode !== 200 || !ovbody || ovbody.exception || !ovbody.items || !ovbody.items[wikiid] ) {
-						console.log( '- ' + ovresponse.statusCode + ': Error while getting the wiki details: ' + ( ovbody && ovbody.exception && ovbody.exception.details ) );
-						return;
-					}
-					var site = ovbody.items[wikiid];
-					
-					vertical[1] = site.hub;
-					topic[1] = site.topic;
-					founder[1] = site.founding_user_id;
-					if ( site.creation_date && creation_date > new Date(site.creation_date) ) {
-						creation_date = new Date(site.creation_date);
-						created[1] = creation_date.toLocaleString(lang.get('dateformat'), timeoptions);
-					}
-					if ( site.desc ) {
-						description[1] = site.desc.escapeFormatting();
-						if ( description[1].length > 1000 ) {
-							description[1] = description[1].substring(0, 1000) + '\u2026';
-						}
-					}
-					if ( site.image ) image[1] = new URL(site.image, wiki).href;
-					
-					return Promise.all([
-						( founder[1] > 0 ? got.get( wiki + 'api.php?action=query&list=users&usprop=&ususerids=' + founder[1] + '&format=json' ).then( usresponse => {
-							var usbody = usresponse.body;
-							if ( usbody && usbody.warnings ) log_warn(usbody.warnings);
-							if ( usresponse.statusCode !== 200 || !usbody || !usbody.query || !usbody.query.users || !usbody.query.users[0] ) {
-								console.log( '- ' + usresponse.statusCode + ': Error while getting the wiki founder: ' + ( usbody && usbody.error && usbody.error.info ) );
-								founder[1] = 'ID: ' + founder[1];
-							}
-							else {
-								var user = usbody.query.users[0].name;
-								if ( msg.showEmbed() ) founder[1] = '[' + user + '](' + wiki.toLink('User:' + user, '', '', true) + ')';
-								else founder[1] = user;
-							}
-						}, error => {
-							console.log( '- Error while getting the wiki founder: ' + error );
+				if ( site.image ) image[1] = new URL(site.image, wiki).href;
+				
+				return Promise.all([
+					( founder[1] > 0 ? got.get( wiki + 'api.php?action=query&list=users&usprop=&ususerids=' + founder[1] + '&format=json' ).then( usresponse => {
+						var usbody = usresponse.body;
+						if ( usbody && usbody.warnings ) log_warn(usbody.warnings);
+						if ( usresponse.statusCode !== 200 || !usbody || !usbody.query || !usbody.query.users || !usbody.query.users[0] ) {
+							console.log( '- ' + usresponse.statusCode + ': Error while getting the wiki founder: ' + ( usbody && usbody.error && usbody.error.info ) );
 							founder[1] = 'ID: ' + founder[1];
-						} ) : founder[1] = ( wiki.isGamepedia() ? null : lang.get('overview.none') ) ),
-						got.get( wiki + 'wikia.php?controller=DiscussionPost&method=getPosts&limit=1&format=json&cache=' + Date.now(), {
-							headers: {
-								Accept: 'application/hal+json'
-							}
-						} ).then( dsresponse => {
-							var dsbody = dsresponse.body;
-							if ( dsresponse.statusCode !== 200 || !dsbody || dsbody.title ) {
-								if ( dsbody?.title !== 'site doesn\'t exists' ) console.log( '- ' + dsresponse.statusCode + ': Error while getting discussions stats: ' + dsbody?.title );
-								return;
-							}
-							let counts = dsbody?._embedded?.count?.[0];
-							if ( counts?.FORUM || counts?.WALL || counts?.ARTICLE_COMMENT ) {
-								if ( counts?.FORUM ) posts.push(counts.FORUM);
-								if ( counts?.WALL ) walls.push(counts.WALL);
-								if ( counts?.ARTICLE_COMMENT ) comments.push(counts.ARTICLE_COMMENT);
-							}
-							else if ( counts?.total ) posts.push(counts.total);
-						}, error => {
-							console.log( '- Error while getting discussions stats: ' + error );
-						} )
-					]);
-				}, error => {
-					console.log( '- Error while getting the wiki details: ' + error );
-					return;
-				} ).finally( () => {
-					if ( msg.showEmbed() ) {
-						if ( vertical[1] ) embed.addField( vertical[0], vertical[1], true );
-						if ( topic[1] ) embed.addField( topic[0], topic[1], true );
-						if ( official[1] ) embed.addField( official[0], official[1], true );
-						embed.addField( version[0], version[1], true ).addField( language[0], language[1], true );
-						if ( rtl[1] ) embed.addField( rtl[0], rtl[1], true );
-						embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true );
-						if ( posts[1] ) embed.addField( posts[0], posts[1], true );
-						if ( walls[1] ) embed.addField( walls[0], walls[1], true );
-						if ( comments[1] ) embed.addField( comments[0], comments[1], true );
-						embed.addField( users[0], users[1], true );
-						if ( manager[1] ) embed.addField( manager[0], '[' + manager[1] + '](' + wiki.toLink('User:' + manager[1], '', '', true) + ') ([' + lang.get('overview.talk') + '](' + wiki.toLink('User talk:' + manager[1], '', '', true) + '))', true );
-						if ( founder[1] ) embed.addField( founder[0], founder[1], true );
-						if ( crossover[1] ) {
-							let crossoverSite = allSites.find( site => '<https://' + site.wiki_domain + '/>' === crossover[1] );
-							if ( crossoverSite ) embed.addField( crossover[0], '[' + crossoverSite.wiki_display_name + '](' + crossover[1] + ')', true );
-							else embed.addField( crossover[0], crossover[1], true );
 						}
-						embed.addField( license[0], license[1], true ).addField( misermode[0], misermode[1], true ).setFooter( lang.get('overview.inaccurate') + ( wikiid ? ' • ' + lang.get('overview.wikiid') + ' ' + wikiid : '' ) );
-						if ( description[1] ) embed.addField( description[0], description[1] );
-						if ( image[1] ) embed.addField( image[0], image[1] ).setImage( image[1] );
-						if ( readonly[1] ) embed.addField( readonly[0], readonly[1] );
-					}
-					else {
-						if ( vertical[1] ) text += '\n' + vertical.join(' ');
-						if ( topic[1] ) text += '\n' + topic.join(' ');
-						if ( official[1] ) text += '\n' + official.join(' ');
-						text += '\n' + version.join(' ') + '\n' + language.join(' ');
-						if ( rtl[1] ) text += '\n' + rtl.join(' ');
-						text += '\n' + created.join(' ') + '\n' + articles.join(' ') + '\n' + pages.join(' ') + '\n' + edits.join(' ');
-						if ( posts[1] ) text += '\n' + posts.join(' ');
-						if ( walls[1] ) text += '\n' + walls.join(' ');
-						if ( comments[1] ) text += '\n' + comments.join(' ');
-						text += '\n' + users.join(' ');
-						if ( manager[1] ) text += '\n' + manager.join(' ');
-						if ( founder[1] ) text += '\n' + founder.join(' ');
-						if ( crossover[1] ) text += '\n' + crossover.join(' ');
-						text += '\n' + license.join(' ') + '\n' + misermode.join(' ');
-						if ( description[1] ) text += '\n' + description.join(' ');
-						if ( image[1] ) {
-							text += '\n' + image.join(' ');
-							if ( msg.uploadFiles() ) embed.files = [{attachment:image[1],name:( spoiler ? 'SPOILER ' : '' ) + body.query.general.sitename + image[1].substring(image[1].lastIndexOf('.'))}];
+						else {
+							var user = usbody.query.users[0].name;
+							if ( msg.showEmbed() ) founder[1] = '[' + user + '](' + wiki.toLink('User:' + user, '', '', true) + ')';
+							else founder[1] = user;
 						}
-						if ( readonly[1] ) text += '\n\n' + ( readonly[0] === '\u200b' ? readonly[1] : readonly.join('\n') );
-						text += '\n\n*' + lang.get('overview.inaccurate') + '*';
+					}, error => {
+						console.log( '- Error while getting the wiki founder: ' + error );
+						founder[1] = 'ID: ' + founder[1];
+					} ) : founder[1] = ( wiki.isGamepedia() ? null : lang.get('overview.none') ) ),
+					got.get( wiki + 'wikia.php?controller=DiscussionPost&method=getPosts&limit=1&format=json&cache=' + Date.now(), {
+						headers: {
+							Accept: 'application/hal+json'
+						}
+					} ).then( dsresponse => {
+						var dsbody = dsresponse.body;
+						if ( dsresponse.statusCode !== 200 || !dsbody || dsbody.title ) {
+							if ( dsbody?.title !== 'site doesn\'t exists' ) console.log( '- ' + dsresponse.statusCode + ': Error while getting discussions stats: ' + dsbody?.title );
+							return;
+						}
+						let counts = dsbody?._embedded?.count?.[0];
+						if ( counts?.FORUM || counts?.WALL || counts?.ARTICLE_COMMENT ) {
+							if ( counts?.FORUM ) posts.push(counts.FORUM);
+							if ( counts?.WALL ) walls.push(counts.WALL);
+							if ( counts?.ARTICLE_COMMENT ) comments.push(counts.ARTICLE_COMMENT);
+						}
+						else if ( counts?.total ) posts.push(counts.total);
+					}, error => {
+						console.log( '- Error while getting discussions stats: ' + error );
+					} )
+				]);
+			}, error => {
+				console.log( '- Error while getting the wiki details: ' + error );
+				return;
+			} ).finally( () => {
+				if ( msg.showEmbed() ) {
+					if ( vertical[1] ) embed.addField( vertical[0], vertical[1], true );
+					if ( topic[1] ) embed.addField( topic[0], topic[1], true );
+					if ( official[1] ) embed.addField( official[0], official[1], true );
+					embed.addField( version[0], version[1], true ).addField( language[0], language[1], true );
+					if ( rtl[1] ) embed.addField( rtl[0], rtl[1], true );
+					embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true );
+					if ( posts[1] ) embed.addField( posts[0], posts[1], true );
+					if ( walls[1] ) embed.addField( walls[0], walls[1], true );
+					if ( comments[1] ) embed.addField( comments[0], comments[1], true );
+					embed.addField( users[0], users[1], true );
+					if ( manager[1] ) embed.addField( manager[0], '[' + manager[1] + '](' + wiki.toLink('User:' + manager[1], '', '', true) + ') ([' + lang.get('overview.talk') + '](' + wiki.toLink('User talk:' + manager[1], '', '', true) + '))', true );
+					if ( founder[1] ) embed.addField( founder[0], founder[1], true );
+					if ( crossover[1] ) {
+						let crossoverSite = allSites.find( site => '<https://' + site.wiki_domain + '/>' === crossover[1] );
+						if ( crossoverSite ) embed.addField( crossover[0], '[' + crossoverSite.wiki_display_name + '](' + crossover[1] + ')', true );
+						else embed.addField( crossover[0], crossover[1], true );
 					}
-					
-					msg.sendChannel( spoiler + text + spoiler, {embed} );
-					
-					if ( reaction ) reaction.removeEmoji();
-				} );
-			}
-			if ( msg.showEmbed() ) {
-				embed.addField( version[0], version[1], true ).addField( language[0], language[1], true );
-				if ( rtl[1] ) embed.addField( rtl[0], rtl[1], true );
-				embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).addField( license[0], license[1], true ).addField( misermode[0], misermode[1], true ).setFooter( lang.get('overview.inaccurate') );
-				if ( readonly[1] ) embed.addField( readonly[0], readonly[1] );
-			}
-			else {
-				text += '\n' + version.join(' ') + '\n' + language.join(' ');
-				if ( rtl[1] ) text += '\n' + rtl.join(' ');
-				text += '\n' + created.join(' ') + '\n' + articles.join(' ') + '\n' + pages.join(' ') + '\n' + edits.join(' ') + '\n' + users.join(' ') + '\n' + license.join(' ') + '\n' + misermode.join(' ');
-				if ( readonly[1] ) text += '\n\n' + ( readonly[0] === '\u200b' ? readonly[1] : readonly.join('\n') );
-				text += '\n\n*' + lang.get('overview.inaccurate') + '*';
-			}
-			
-			msg.sendChannel( spoiler + text + spoiler, {embed} );
-			
-			if ( reaction ) reaction.removeEmoji();
+					embed.addField( license[0], license[1], true ).addField( misermode[0], misermode[1], true ).setFooter( lang.get('overview.inaccurate') + ( wikiid ? ' • ' + lang.get('overview.wikiid') + ' ' + wikiid : '' ) );
+					if ( description[1] ) embed.addField( description[0], description[1] );
+					if ( image[1] ) embed.addField( image[0], image[1] ).setImage( image[1] );
+					if ( readonly[1] ) embed.addField( readonly[0], readonly[1] );
+				}
+				else {
+					if ( vertical[1] ) text += '\n' + vertical.join(' ');
+					if ( topic[1] ) text += '\n' + topic.join(' ');
+					if ( official[1] ) text += '\n' + official.join(' ');
+					text += '\n' + version.join(' ') + '\n' + language.join(' ');
+					if ( rtl[1] ) text += '\n' + rtl.join(' ');
+					text += '\n' + created.join(' ') + '\n' + articles.join(' ') + '\n' + pages.join(' ') + '\n' + edits.join(' ');
+					if ( posts[1] ) text += '\n' + posts.join(' ');
+					if ( walls[1] ) text += '\n' + walls.join(' ');
+					if ( comments[1] ) text += '\n' + comments.join(' ');
+					text += '\n' + users.join(' ');
+					if ( manager[1] ) text += '\n' + manager.join(' ');
+					if ( founder[1] ) text += '\n' + founder.join(' ');
+					if ( crossover[1] ) text += '\n' + crossover.join(' ');
+					text += '\n' + license.join(' ') + '\n' + misermode.join(' ');
+					if ( description[1] ) text += '\n' + description.join(' ');
+					if ( image[1] ) {
+						text += '\n' + image.join(' ');
+						if ( msg.uploadFiles() ) embed.files = [{attachment:image[1],name:( spoiler ? 'SPOILER ' : '' ) + body.query.general.sitename + image[1].substring(image[1].lastIndexOf('.'))}];
+					}
+					if ( readonly[1] ) text += '\n\n' + ( readonly[0] === '\u200b' ? readonly[1] : readonly.join('\n') );
+					text += '\n\n*' + lang.get('overview.inaccurate') + '*';
+				}
+				
+				msg.sendChannel( spoiler + text + spoiler, {embed} );
+				
+				if ( reaction ) reaction.removeEmoji();
+			} );
+		}
+		if ( msg.showEmbed() ) {
+			embed.addField( version[0], version[1], true ).addField( language[0], language[1], true );
+			if ( rtl[1] ) embed.addField( rtl[0], rtl[1], true );
+			embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).addField( license[0], license[1], true ).addField( misermode[0], misermode[1], true ).setFooter( lang.get('overview.inaccurate') );
+			if ( readonly[1] ) embed.addField( readonly[0], readonly[1] );
+		}
+		else {
+			text += '\n' + version.join(' ') + '\n' + language.join(' ');
+			if ( rtl[1] ) text += '\n' + rtl.join(' ');
+			text += '\n' + created.join(' ') + '\n' + articles.join(' ') + '\n' + pages.join(' ') + '\n' + edits.join(' ') + '\n' + users.join(' ') + '\n' + license.join(' ') + '\n' + misermode.join(' ');
+			if ( readonly[1] ) text += '\n\n' + ( readonly[0] === '\u200b' ? readonly[1] : readonly.join('\n') );
+			text += '\n\n*' + lang.get('overview.inaccurate') + '*';
 		}
+		
+		msg.sendChannel( spoiler + text + spoiler, {embed} );
+		
+		if ( reaction ) reaction.removeEmoji();
 	}, error => {
 		if ( wiki.noWiki(error.message) ) {
 			console.log( '- This wiki doesn\'t exist!' );

+ 40 - 38
cmds/wiki/random.js

@@ -1,6 +1,7 @@
 const {MessageEmbed} = require('discord.js');
 const fandom_random = require('./fandom/random.js').run;
 const parse_page = require('../../functions/parse_page.js');
+const logging = require('../../util/logging.js');
 const {parse_infobox, htmlToPlain, htmlToDiscord} = require('../../util/functions.js');
 const extract_desc = require('../../util/extract_desc.js');
 
@@ -28,48 +29,49 @@ function gamepedia_random(lang, msg, wiki, reaction, spoiler) {
 				console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
 				msg.sendChannelError( spoiler + '<' + wiki.toLink('Special:Random') + '>' + spoiler );
 			}
+			return;
 		}
-		else {
-			var querypage = Object.values(body.query.pages)[0];
-			var pagelink = wiki.updateWiki(body.query.general).toLink(querypage.title);
-			var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
-			if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
-				var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
-				if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
-				embed.setTitle( displaytitle );
-			}
-			if ( querypage.pageprops && querypage.pageprops.description ) {
-				var description = htmlToPlain( querypage.pageprops.description );
-				if ( description.length > 1000 ) description = description.substring(0, 1000) + '\u2026';
-				embed.backupDescription = description;
-			}
-			else if ( querypage.extract ) {
-				var extract = extract_desc(querypage.extract);
-				embed.backupDescription = extract[0];
-			}
-			if ( querypage.title === body.query.general.mainpage ) {
-				embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
-			}
-			else if ( querypage.pageimage && querypage.original ) {
-				embed.setThumbnail( querypage.original.source );
-			}
-			else if ( querypage.pageprops && querypage.pageprops.page_image_free ) {
-				embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
+		wiki.updateWiki(body.query.general);
+		logging(wiki, 'random');
+		var querypage = Object.values(body.query.pages)[0];
+		var pagelink = wiki.toLink(querypage.title);
+		var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
+		if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
+			var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
+			if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
+			embed.setTitle( displaytitle );
+		}
+		if ( querypage.pageprops && querypage.pageprops.description ) {
+			var description = htmlToPlain( querypage.pageprops.description );
+			if ( description.length > 1000 ) description = description.substring(0, 1000) + '\u2026';
+			embed.backupDescription = description;
+		}
+		else if ( querypage.extract ) {
+			var extract = extract_desc(querypage.extract);
+			embed.backupDescription = extract[0];
+		}
+		if ( querypage.title === body.query.general.mainpage ) {
+			embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
+		}
+		else if ( querypage.pageimage && querypage.original ) {
+			embed.setThumbnail( querypage.original.source );
+		}
+		else if ( querypage.pageprops && querypage.pageprops.page_image_free ) {
+			embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
+		}
+		else embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
+		
+		if ( !embed.fields.length && querypage.pageprops && querypage.pageprops.infoboxes ) {
+			try {
+				var infobox = JSON.parse(querypage.pageprops.infoboxes)?.[0];
+				parse_infobox(infobox, embed, new URL(body.query.general.logo, wiki).href, wiki.articleURL.href);
 			}
-			else embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
-			
-			if ( !embed.fields.length && querypage.pageprops && querypage.pageprops.infoboxes ) {
-				try {
-					var infobox = JSON.parse(querypage.pageprops.infoboxes)?.[0];
-					parse_infobox(infobox, embed, new URL(body.query.general.logo, wiki).href, wiki.articleURL.href);
-				}
-				catch ( error ) {
-					console.log( '- Failed to parse the infobox: ' + error );
-				}
+			catch ( error ) {
+				console.log( '- Failed to parse the infobox: ' + error );
 			}
-			
-			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 )) );
 		}
+		
+		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 )) );
 	}, error => {
 		if ( wiki.noWiki(error.message) ) {
 			console.log( '- This wiki doesn\'t exist!' );

+ 19 - 0
util/logging.js

@@ -0,0 +1,19 @@
+if ( !process.env.usagelog ) {
+	module.exports = function() {};
+	return;
+}
+
+const fs = require('fs');
+const usageLog = fs.createWriteStream(process.env.usagelog, {flags:'a'});
+
+/**
+ * Log wikis by usage.
+ * @param {import('./wiki.js')} wiki - The wiki.
+ * @param {String[]} notes - The notes about the usage.
+ * @returns {Boolean}
+ */
+function logging(wiki, ...notes) {
+	return usageLog.write( `${new Date().toISOString()} ${wiki.href} ${notes.join(' ')}\n`, 'utf8' );
+}
+
+module.exports = logging;

+ 3 - 0
util/newMessage.js

@@ -1,4 +1,5 @@
 const {Util} = require('discord.js');
+const logging = require('./logging.js');
 const {limit: {command: commandLimit}, defaultSettings, wikiProjects} = require('./default.json');
 const Wiki = require('./wiki.js');
 const check_wiki = {
@@ -164,6 +165,7 @@ function newMessage(msg, lang, wiki = defaultSettings.wiki, prefix = process.env
 				return;
 			}
 			wiki.updateWiki(body.query.general);
+			logging(wiki, 'inline');
 			if ( body.query.normalized ) {
 				body.query.normalized.forEach( title => links.filter( link => link.title === title.from ).forEach( link => link.title = title.to ) );
 			}
@@ -231,6 +233,7 @@ function newMessage(msg, lang, wiki = defaultSettings.wiki, prefix = process.env
 					if ( embed.template || !body.query.variables || !body.query.variables.some( variable => variable.toUpperCase() === embed.title ) ) missing.push(embed);
 				} ) );
 				if ( missing.length ) {
+					logging(wiki, 'inline', 'template');
 					msg.sendChannel( missing.map( embed => embed.spoiler + '<' + ( embed.template || wiki.toLink(embed.title, 'action=edit&redlink=1') ) + '>' + embed.spoiler ).join('\n'), {split:true} );
 				}
 			}