settings.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. import { load as cheerioLoad } from 'cheerio';
  2. import { MessageEmbed, Util, MessageActionRow, MessageButton } from 'discord.js';
  3. import { got } from '../util/functions.js';
  4. import Lang from '../util/i18n.js';
  5. import Wiki from '../util/wiki.js';
  6. import db from '../util/database.js';
  7. import { createRequire } from 'module';
  8. const require = createRequire(import.meta.url);
  9. const {defaultSettings} = require('../util/default.json');
  10. const allLangs = Lang.allLangs();
  11. /**
  12. * Processes the "settings" command.
  13. * @param {Lang} lang - The user language.
  14. * @param {import('discord.js').Message} msg - The Discord message.
  15. * @param {String[]} args - The command arguments.
  16. * @param {String} line - The command as plain text.
  17. * @param {Wiki} wiki - The wiki for the message.
  18. */
  19. function cmd_settings(lang, msg, args, line, wiki) {
  20. if ( !msg.isAdmin() ) return msg.reactEmoji('❌');
  21. db.query( 'SELECT channel, wiki, lang, role, inline, prefix FROM discord WHERE guild = $1 ORDER BY channel DESC NULLS LAST', [msg.guildId] ).then( ({rows}) => {
  22. var guild = rows.find( row => !row.channel );
  23. if ( !guild ) guild = Object.assign({
  24. role: null, inline: null,
  25. prefix: process.env.prefix
  26. }, defaultSettings);
  27. var prefix = guild.prefix;
  28. var inlinepage = ( lang.localNames.page || 'page' );
  29. var button = null;
  30. var components = [];
  31. if ( process.env.dashboard ) {
  32. button = new MessageButton().setLabel(lang.get('settings.button')).setEmoji('<:wikibot:588723255972593672>').setStyle('LINK').setURL(new URL(`/guild/${msg.guildId}/settings`, process.env.dashboard).href);
  33. components.push(new MessageActionRow().addComponents(button));
  34. }
  35. var text = lang.get('settings.missing', '`' + prefix + 'settings lang`', '`' + prefix + 'settings wiki`');
  36. if ( rows.length ) {
  37. text = lang.get('settings.current');
  38. if ( button ) text += `\n<${button.url}>`;
  39. text += '\n' + lang.get('settings.currentlang') + ' `' + allLangs.names[guild.lang] + '` - `' + prefix + 'settings lang`';
  40. if ( patreonGuildsPrefix.has(msg.guildId) ) text += '\n' + lang.get('settings.currentprefix') + ' `' + prefix + '` - `' + prefix + 'settings prefix`';
  41. text += '\n' + lang.get('settings.currentrole') + ' ' + ( guild.role ? `<@&${guild.role}>` : '@everyone' ) + ' - `' + prefix + 'settings role`';
  42. text += '\n' + lang.get('settings.currentinline') + ' ' + ( guild.inline ? '~~' : '' ) + '`[[' + inlinepage + ']]`' + ( guild.inline ? '~~' : '' ) + ' - `' + prefix + 'settings inline`';
  43. text += '\n' + lang.get('settings.currentwiki') + ' ' + guild.wiki + ' - `' + prefix + 'settings wiki`';
  44. text += '\n' + lang.get('settings.currentchannel') + ' `' + prefix + 'settings channel`\n';
  45. if ( rows.length === 1 ) text += lang.get('settings.nochannels');
  46. else text += rows.filter( row => row !== guild ).map( row => '<#' + row.channel.replace( /^#/, '' ) + '>: ' + ( patreonGuildsPrefix.has(msg.guildId) ? '`' + allLangs.names[row.lang] + '` - ' : '' ) + '<' + row.wiki + '>' + ( patreonGuildsPrefix.has(msg.guildId) ? ' - ' + ( row.role ? `<@&${row.role}>` : '@everyone' ) + ' - ' + ( row.inline ? '~~' : '' ) + '`[[' + inlinepage + ']]`' + ( row.inline ? '~~' : '' ) : '' ) ).join('\n');
  47. }
  48. if ( !args.length ) {
  49. return Util.splitMessage( text ).forEach( textpart => msg.replyMsg( {content: textpart, components}, true ) );
  50. }
  51. var channelId = ( msg.channel.isThread() ? msg.channel.parentId : msg.channelId );
  52. var prelang = '';
  53. args[0] = args[0].toLowerCase();
  54. if ( args[0] === 'channel' ) {
  55. prelang = 'channel ';
  56. if ( !rows.length ) return Util.splitMessage( text ).forEach( textpart => msg.replyMsg( {content: textpart, components}, true ) );
  57. var channel = rows.find( row => row.channel === channelId );
  58. if ( !channel ) channel = Object.assign({}, rows.find( row => {
  59. return ( row.channel === '#' + msg.channel.parentId );
  60. } ) || guild, {channel: channelId});
  61. text = lang.get('settings.channel current');
  62. button?.setURL(new URL(`/guild/${msg.guildId}/settings/${channelId}`, button.url).href);
  63. if ( button ) text += `\n<${button.url}>`;
  64. if ( patreonGuildsPrefix.has(msg.guildId) ) {
  65. text += '\n' + lang.get('settings.currentlang') + ' `' + allLangs.names[channel.lang] + '` - `' + prefix + 'settings channel lang`';
  66. text += '\n' + lang.get('settings.currentrole') + ' ' + ( channel.role ? `<@&${channel.role}>` : '@everyone' ) + ' - `' + prefix + 'settings channel role`';
  67. text += '\n' + lang.get('settings.currentinline') + ' ' + ( channel.inline ? '~~' : '' ) + '`[[' + inlinepage + ']]`' + ( channel.inline ? '~~' : '' ) + ' - `' + prefix + 'settings channel inline`';
  68. }
  69. text += '\n' + lang.get('settings.currentwiki') + ' ' + channel.wiki + ' - `' + prefix + 'settings channel wiki`';
  70. if ( !args[1] ) return msg.replyMsg( {content: text, components}, true );
  71. args[0] = args[1].toLowerCase();
  72. args[1] = args.slice(2).join(' ').toLowerCase().trim().replace( /^<\s*(.*)\s*>$/, '$1' );
  73. }
  74. else args[1] = args.slice(1).join(' ').toLowerCase().trim().replace( /^<\s*(.*)\s*>$/, '$1' );
  75. if ( args[0] === 'wiki' ) {
  76. prelang += 'wiki';
  77. var wikihelp = '\n' + lang.get('settings.wikihelp', prefix + 'settings ' + prelang);
  78. if ( !args[1] ) {
  79. if ( !rows.length ) return msg.replyMsg( {content: lang.get('settings.wikimissing') + wikihelp, components}, true );
  80. else return msg.replyMsg( {content: lang.get('settings.' + prelang) + ' ' + ( channel || guild ).wiki + wikihelp, components}, true );
  81. }
  82. if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, true );
  83. var wikinew = Wiki.fromInput(args[1]);
  84. if ( !wikinew ) {
  85. let wikisuggest = lang.get('settings.wikiinvalid') + wikihelp;
  86. //wikisuggest += '\n\n' + lang.get('settings.foundwikis') + '\n' + sites.map( site => site.wiki_display_name + ': `' + site.wiki_domain + '`' ).join('\n');
  87. return Util.splitMessage( wikisuggest ).forEach( textpart => msg.replyMsg( {content: textpart, components}, true ) );
  88. }
  89. return msg.reactEmoji('⏳', true).then( reaction => {
  90. got.get( wikinew + 'api.php?&action=query&meta=siteinfo&siprop=general&format=json', {
  91. responseType: 'text'
  92. } ).then( response => {
  93. try {
  94. response.body = JSON.parse(response.body);
  95. }
  96. catch (error) {
  97. if ( response.statusCode === 404 && typeof response.body === 'string' ) {
  98. let api = cheerioLoad(response.body)('head link[rel="EditURI"]').prop('href');
  99. if ( api ) {
  100. wikinew = new Wiki(api.split('api.php?')[0], wikinew);
  101. return got.get( wikinew + 'api.php?action=query&meta=siteinfo&siprop=general&format=json' );
  102. }
  103. }
  104. }
  105. return response;
  106. } ).then( response => {
  107. var body = response.body;
  108. if ( response.statusCode !== 200 || body?.batchcomplete === undefined || !body?.query?.general ) {
  109. console.log( '- ' + response.statusCode + ': Error while testing the wiki: ' + body?.error?.info );
  110. if ( reaction ) reaction.removeEmoji();
  111. if ( body?.error?.info === 'You need read permission to use this module.' ) {
  112. return msg.replyMsg( {content: lang.get('settings.wikiinvalid_private') + wikihelp, components}, true );
  113. }
  114. msg.reactEmoji('nowiki', true);
  115. return msg.replyMsg( {content: lang.get('settings.wikiinvalid') + wikihelp, components}, true );
  116. }
  117. wikinew.updateWiki(body.query.general);
  118. var embed;
  119. if ( !wikinew.isFandom() ) {
  120. var notice = [];
  121. if ( body.query.general.generator.replace( /^MediaWiki 1\.(\d\d).*$/, '$1' ) < 30 ) {
  122. console.log( '- This wiki is using ' + body.query.general.generator + '.' );
  123. notice.push({
  124. name: 'MediaWiki',
  125. value: lang.get('test.MediaWiki', '[MediaWiki 1.30](https://www.mediawiki.org/wiki/MediaWiki_1.30)', body.query.general.generator)
  126. });
  127. }
  128. if ( notice.length ) {
  129. embed = new MessageEmbed().setAuthor( {name: body.query.general.sitename} ).setTitle( lang.get('test.notice') ).addFields( notice );
  130. }
  131. }
  132. var sql = 'UPDATE discord SET wiki = $1 WHERE guild = $2 AND wiki = $3';
  133. var sqlargs = [wikinew.href, msg.guildId, guild.wiki];
  134. if ( !rows.length ) {
  135. sql = 'INSERT INTO discord(wiki, guild, main, lang) VALUES($1, $2, $2, $3)';
  136. sqlargs[2] = lang.lang;
  137. }
  138. else if ( channel ) {
  139. sql = 'UPDATE discord SET wiki = $1 WHERE guild = $2 AND channel = $3';
  140. sqlargs[2] = channelId;
  141. if ( !rows.includes( channel ) ) {
  142. if ( channel.wiki === wikinew.href ) {
  143. if ( reaction ) reaction.removeEmoji();
  144. return msg.replyMsg( {content: lang.get('settings.' + prelang + 'changed') + ' ' + channel.wiki + wikihelp, embeds: [embed], components}, true );
  145. }
  146. sql = 'INSERT INTO discord(wiki, guild, channel, lang, role, inline, prefix) VALUES($1, $2, $3, $4, $5, $6, $7)';
  147. sqlargs.push(guild.lang, guild.role, guild.inline, guild.prefix);
  148. }
  149. }
  150. return db.query( sql, sqlargs ).then( () => {
  151. console.log( '- Settings successfully updated.' );
  152. if ( channel ) channel.wiki = wikinew.href;
  153. else {
  154. rows.forEach( row => {
  155. if ( row.channel && row.wiki === guild.wiki ) row.wiki = wikinew.href;
  156. } );
  157. guild.wiki = wikinew.href;
  158. }
  159. if ( channel || !rows.some( row => row.channel === channelId ) ) wiki = new Wiki(wikinew);
  160. if ( reaction ) reaction.removeEmoji();
  161. msg.replyMsg( {content: lang.get('settings.' + prelang + 'changed') + ' ' + wikinew + wikihelp, embeds: [embed], components}, true );
  162. var channels = rows.filter( row => row.channel && row.lang === guild.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.role === guild.role && row.inline === guild.inline ).map( row => row.channel );
  163. if ( channels.length ) db.query( 'DELETE FROM discord WHERE channel IN (' + channels.map( (row, i) => '$' + ( i + 1 ) ).join(', ') + ')', channels ).then( () => {
  164. console.log( '- Settings successfully removed.' );
  165. }, dberror => {
  166. console.log( '- Error while removing the settings: ' + dberror );
  167. } );
  168. }, dberror => {
  169. console.log( '- Error while editing the settings: ' + dberror );
  170. msg.replyMsg( {content: lang.get('settings.save_failed'), embeds: [embed], components}, true );
  171. if ( reaction ) reaction.removeEmoji();
  172. } );
  173. }, ferror => {
  174. if ( reaction ) reaction.removeEmoji();
  175. if ( ferror.message?.startsWith( 'connect ECONNREFUSED ' ) || ferror.message?.startsWith( 'Hostname/IP does not match certificate\'s altnames: ' ) || ferror.message === 'certificate has expired' || ferror.message === 'self signed certificate' ) {
  176. console.log( '- Error while testing the wiki: No HTTPS' );
  177. return msg.replyMsg( {content: lang.get('settings.wikiinvalid_http') + wikihelp, components}, true );
  178. }
  179. console.log( '- Error while testing the wiki: ' + ferror );
  180. if ( ferror.message === `Timeout awaiting 'request' for ${got.defaults.options.timeout.request}ms` ) {
  181. return msg.replyMsg( {content: lang.get('settings.wikiinvalid_timeout') + wikihelp, components}, true );
  182. }
  183. msg.reactEmoji('nowiki', true);
  184. return msg.replyMsg( {content: lang.get('settings.wikiinvalid') + wikihelp, components}, true );
  185. } );
  186. } );
  187. }
  188. if ( args[0] === 'lang' || args[0] === 'language' ) {
  189. if ( channel && !patreonGuildsPrefix.has(msg.guildId) ) return msg.replyMsg( lang.get('general.patreon') + '\n<' + process.env.patreon + '>', true );
  190. prelang += 'lang';
  191. var langhelp = '\n' + lang.get('settings.langhelp', prefix + 'settings ' + prelang) + ' `' + Object.values(allLangs.names).join('`, `') + '`';
  192. if ( !args[1] ) {
  193. return msg.replyMsg( {content: lang.get('settings.' + prelang) + ' `' + allLangs.names[( channel || guild ).lang] + '`' + langhelp, files: ( msg.uploadFiles() ? [`./i18n/widgets/${( channel || guild ).lang}.png`] : [] ), components}, true );
  194. }
  195. if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, true );
  196. if ( !allLangs.map.hasOwnProperty(args[1]) ) {
  197. return msg.replyMsg( {content: lang.get('settings.langinvalid') + langhelp, components}, true );
  198. }
  199. var sql = 'UPDATE discord SET lang = $1 WHERE guild = $2 AND lang = $3';
  200. var sqlargs = [allLangs.map[args[1]], msg.guildId, guild.lang];
  201. if ( !rows.length ) {
  202. sql = 'INSERT INTO discord(lang, guild, main) VALUES($1, $2, $2)';
  203. sqlargs.pop();
  204. }
  205. else if ( channel ) {
  206. sql = 'UPDATE discord SET lang = $1 WHERE guild = $2 AND channel = $3';
  207. sqlargs[2] = channelId;
  208. if ( !rows.includes( channel ) ) {
  209. if ( channel.lang === allLangs.map[args[1]] ) {
  210. return msg.replyMsg( {content: lang.get('settings.' + prelang + 'changed') + ' `' + allLangs.names[channel.lang] + '`' + langhelp, files: ( msg.uploadFiles() ? [`./i18n/widgets/${channel.lang}.png`] : [] ), components}, true );
  211. }
  212. sql = 'INSERT INTO discord(lang, guild, channel, wiki, role, inline, prefix) VALUES($1, $2, $3, $4, $5, $6, $7)';
  213. sqlargs.push(guild.wiki, guild.role, guild.inline, guild.prefix);
  214. }
  215. }
  216. return db.query( sql, sqlargs ).then( () => {
  217. console.log( '- Settings successfully updated.' );
  218. if ( channel ) channel.lang = allLangs.map[args[1]];
  219. else {
  220. rows.forEach( row => {
  221. if ( row.channel && row.lang === guild.lang ) row.lang = allLangs.map[args[1]];
  222. } );
  223. guild.lang = allLangs.map[args[1]];
  224. if ( voiceGuildsLang.has(msg.guildId) ) voiceGuildsLang.set(msg.guildId, guild.lang);
  225. }
  226. if ( channel || !patreonGuildsPrefix.has(msg.guildId) || !rows.some( row => row.channel === channelId ) ) lang = new Lang(allLangs.map[args[1]]);
  227. msg.replyMsg( {content: lang.get('settings.' + prelang + 'changed') + ' `' + allLangs.names[allLangs.map[args[1]]] + '`\n' + lang.get('settings.langhelp', prefix + 'settings ' + prelang) + ' `' + Object.values(allLangs.names).join('`, `') + '`', files: ( msg.uploadFiles() ? [`./i18n/widgets/${allLangs.map[args[1]]}.png`] : [] ), components}, true );
  228. var channels = rows.filter( row => row.channel && row.lang === guild.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.role === guild.role && row.inline === guild.inline ).map( row => row.channel );
  229. if ( channels.length ) db.query( 'DELETE FROM discord WHERE channel IN (' + channels.map( (row, i) => '$' + ( i + 1 ) ).join(', ') + ')', channels ).then( () => {
  230. console.log( '- Settings successfully removed.' );
  231. }, dberror => {
  232. console.log( '- Error while removing the settings: ' + dberror );
  233. } );
  234. }, dberror => {
  235. console.log( '- Error while editing the settings: ' + dberror );
  236. msg.replyMsg( {content: lang.get('settings.save_failed'), components}, true );
  237. } );
  238. }
  239. if ( args[0] === 'role' ) {
  240. if ( channel && !patreonGuildsPrefix.has(msg.guildId) ) return msg.replyMsg( lang.get('general.patreon') + '\n<' + process.env.patreon + '>', true );
  241. prelang += 'role';
  242. var rolehelp = '\n' + lang.get('settings.rolehelp', prefix + 'settings ' + prelang);
  243. if ( !args[1] ) {
  244. return msg.replyMsg( {content: lang.get('settings.' + prelang) + ' ' + ( ( channel || guild ).role ? `<@&${( channel || guild ).role}>` : '@everyone' ) + rolehelp, components}, true );
  245. }
  246. if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, true );
  247. var role = null;
  248. if ( /^\d+$/.test(args[1]) ) role = msg.guild.roles.cache.get(args[1]);
  249. if ( !role ) role = msg.guild.roles.cache.find( gc => gc.name.toLowerCase() === args[1].replace( /^@/, '' ) );
  250. if ( !role && ['everyone', 'here', 'none', 'all'].includes( args[1].replace( /^@/, '' ) ) ) {
  251. role = msg.guild.roles.cache.get(msg.guildId);
  252. }
  253. if ( !role ) {
  254. return msg.replyMsg( {content: lang.get('settings.roleinvalid') + rolehelp, components}, true );
  255. }
  256. role = ( role.id === msg.guildId ? null : role.id );
  257. var sql = 'UPDATE discord SET role = $1 WHERE guild = $2';
  258. var sqlargs = [role, msg.guildId];
  259. if ( !rows.length ) {
  260. sql = 'INSERT INTO discord(role, guild, main, lang) VALUES($1, $2, $2, $3)';
  261. sqlargs.push(lang.lang);
  262. }
  263. else if ( channel ) {
  264. sql = 'UPDATE discord SET role = $1 WHERE guild = $2 AND channel = $3';
  265. sqlargs.push(channelId);
  266. if ( !rows.includes( channel ) ) {
  267. if ( channel.role === role ) {
  268. return msg.replyMsg( {content: lang.get('settings.' + prelang + 'changed') + ' ' + ( channel.role ? `<@&${channel.role}>` : '@everyone' ) + rolehelp, components}, true );
  269. }
  270. sql = 'INSERT INTO discord(role, guild, channel, wiki, lang, inline, prefix) VALUES($1, $2, $3, $4, $5, $6, $7)';
  271. sqlargs.push(guild.wiki, guild.lang, guild.inline, guild.prefix);
  272. }
  273. }
  274. else if ( guild.role ) {
  275. sql += ' AND role = $3';
  276. sqlargs.push(guild.role);
  277. }
  278. else sql += ' AND role IS NULL';
  279. return db.query( sql, sqlargs ).then( () => {
  280. console.log( '- Settings successfully updated.' );
  281. if ( channel ) channel.role = role;
  282. else {
  283. rows.forEach( row => {
  284. if ( row.channel && row.role === guild.role ) row.role = role;
  285. } );
  286. guild.role = role;
  287. }
  288. msg.replyMsg( {content: lang.get('settings.' + prelang + 'changed') + ' ' + ( role ? `<@&${role}>` : '@everyone' ) + rolehelp, components}, true );
  289. var channels = rows.filter( row => row.channel && row.lang === guild.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.role === guild.role && row.inline === guild.inline ).map( row => row.channel );
  290. if ( channels.length ) db.query( 'DELETE FROM discord WHERE channel IN (' + channels.map( (row, i) => '$' + ( i + 1 ) ).join(', ') + ')', channels ).then( () => {
  291. console.log( '- Settings successfully removed.' );
  292. }, dberror => {
  293. console.log( '- Error while removing the settings: ' + dberror );
  294. } );
  295. }, dberror => {
  296. console.log( '- Error while editing the settings: ' + dberror );
  297. msg.replyMsg( {content: lang.get('settings.save_failed'), components}, true );
  298. } );
  299. }
  300. if ( args[0] === 'prefix' && !channel ) {
  301. if ( !patreonGuildsPrefix.has(msg.guildId) ) {
  302. return msg.replyMsg( lang.get('general.patreon') + '\n<' + process.env.patreon + '>', true );
  303. }
  304. var prefixhelp = '\n' + lang.get('settings.prefixhelp', prefix + 'settings prefix');
  305. args[1] = args[1].replace( /(?<!\\)_$/, ' ' ).replace( /\\([_\W])/g, '$1' );
  306. if ( !args[1].trim() ) {
  307. return msg.replyMsg( {content: lang.get('settings.prefix') + ' `' + prefix + '`' + prefixhelp, components}, true );
  308. }
  309. if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, true );
  310. if ( args[1].includes( '`' ) || args[1].includes( '\\' ) || args[1].length > 100 ) {
  311. return msg.replyMsg( {content: lang.get('settings.prefixinvalid') + prefixhelp, components}, true );
  312. }
  313. if ( args[1] === 'reset' || args[1] === 'default' ) args[1] = process.env.prefix;
  314. var sql = 'UPDATE discord SET prefix = $1 WHERE guild = $2';
  315. var sqlargs = [args[1], msg.guildId];
  316. if ( !rows.length ) {
  317. sql = 'INSERT INTO discord(prefix, guild, main, lang) VALUES($1, $2, $2, $3)';
  318. sqlargs.push(lang.lang);
  319. }
  320. return db.query( sql, sqlargs ).then( () => {
  321. console.log( '- Settings successfully updated.' );
  322. guild.prefix = args[1];
  323. msg.client.shard.broadcastEval( (discordClient, evalData) => {
  324. patreonGuildsPrefix.set(evalData.guild, evalData.prefix);
  325. }, {context: {guild: msg.guildId, prefix: args[1]}} );
  326. msg.replyMsg( {content: lang.get('settings.prefixchanged') + ' `' + args[1] + '`\n' + lang.get('settings.prefixhelp', args[1] + 'settings prefix'), components}, true );
  327. }, dberror => {
  328. console.log( '- Error while editing the settings: ' + dberror );
  329. msg.replyMsg( {content: lang.get('settings.save_failed'), components}, true );
  330. } );
  331. }
  332. if ( args[0] === 'inline' ) {
  333. if ( channel && !patreonGuildsPrefix.has(msg.guildId) ) return msg.replyMsg( lang.get('general.patreon') + '\n<' + process.env.patreon + '>', true );
  334. prelang += 'inline';
  335. var toggle = 'inline ' + ( ( channel || guild ).inline ? 'disabled' : 'enabled' );
  336. var inlinehelp = '\n' + lang.get('settings.' + toggle + '.help', prefix + 'settings ' + prelang + ' toggle', inlinepage);
  337. if ( args[1] !== 'toggle' ) {
  338. return msg.replyMsg( {content: lang.get('settings.' + toggle + '.' + prelang) + inlinehelp, components}, true );
  339. }
  340. if ( process.env.READONLY ) return msg.replyMsg( lang.get('general.readonly') + '\n' + process.env.invite, true );
  341. var value = ( ( channel || guild ).inline ? null : 1 );
  342. var sql = 'UPDATE discord SET inline = $1 WHERE guild = $2';
  343. var sqlargs = [value, msg.guildId];
  344. if ( !rows.length ) {
  345. sql = 'INSERT INTO discord(inline, guild, main, lang) VALUES($1, $2, $2, $3)';
  346. sqlargs.push(lang.lang);
  347. }
  348. else if ( channel ) {
  349. sql = 'UPDATE discord SET inline = $1 WHERE guild = $2 AND channel = $3';
  350. sqlargs.push(channelId);
  351. if ( !rows.includes( channel ) ) {
  352. sql = 'INSERT INTO discord(inline, guild, channel, wiki, lang, role, prefix) VALUES($1, $2, $3, $4, $5, $6, $7)';
  353. sqlargs.push(guild.wiki, guild.lang, guild.role, guild.prefix);
  354. }
  355. }
  356. return db.query( sql, sqlargs ).then( () => {
  357. console.log( '- Settings successfully updated.' );
  358. if ( channel ) channel.inline = value;
  359. else {
  360. rows.forEach( row => {
  361. if ( row.channel && row.inline === guild.inline ) row.inline = value;
  362. } );
  363. guild.inline = value;
  364. }
  365. toggle = 'inline ' + ( ( channel || guild ).inline ? 'disabled' : 'enabled' );
  366. msg.replyMsg( {content: lang.get('settings.' + toggle + '.' + prelang + 'changed') + '\n' + lang.get('settings.' + toggle + '.help', prefix + 'settings ' + prelang + ' toggle', inlinepage), components}, true );
  367. var channels = rows.filter( row => row.channel && row.lang === guild.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.role === guild.role && row.inline === guild.inline ).map( row => row.channel );
  368. if ( channels.length ) db.query( 'DELETE FROM discord WHERE channel IN (' + channels.map( (row, i) => '$' + ( i + 1 ) ).join(', ') + ')', channels ).then( () => {
  369. console.log( '- Settings successfully removed.' );
  370. }, dberror => {
  371. console.log( '- Error while removing the settings: ' + dberror );
  372. } );
  373. }, dberror => {
  374. console.log( '- Error while editing the settings: ' + dberror );
  375. msg.replyMsg( {content: lang.get('settings.save_failed'), components}, true );
  376. } );
  377. }
  378. return Util.splitMessage( text ).forEach( textpart => msg.replyMsg( {content: textpart, components}, true ) );
  379. }, dberror => {
  380. console.log( '- Error while getting the settings: ' + dberror );
  381. msg.reactEmoji('error', true);
  382. } );
  383. }
  384. export default {
  385. name: 'settings',
  386. everyone: true,
  387. pause: true,
  388. owner: false,
  389. run: cmd_settings
  390. };