Allow silent scheduled closes. Make close time format stricter (no whitespace).

master
Dragory 2019-03-06 21:15:09 +02:00
parent cd3da4c4ec
commit 188f7543ee
4 changed files with 60 additions and 20 deletions

View File

@ -0,0 +1,11 @@
exports.up = async function(knex, Promise) {
await knex.schema.table('threads', table => {
table.integer('scheduled_close_silent').nullable();
});
};
exports.down = async function(knex, Promise) {
await knex.schema.table('threads', table => {
table.dropColumn('scheduled_close_silent');
});
};

View File

@ -19,6 +19,7 @@ const {THREAD_MESSAGE_TYPE, THREAD_STATUS} = require('./constants');
* @property {String} scheduled_close_at
* @property {String} scheduled_close_id
* @property {String} scheduled_close_name
* @property {Number} scheduled_close_silent
* @property {String} alert_id
* @property {String} created_at
*/
@ -326,11 +327,16 @@ class Thread {
/**
* @returns {Promise<void>}
*/
async close(noSystemMessage = false) {
if (! noSystemMessage) {
async close(suppressSystemMessage = false, silent = false) {
if (! suppressSystemMessage) {
console.log(`Closing thread ${this.id}`);
if (silent) {
await this.postSystemMessage('Closing thread silently...');
} else {
await this.postSystemMessage('Closing thread...');
}
}
// Update DB status
await knex('threads')
@ -352,13 +358,14 @@ class Thread {
* @param {Eris~User} user
* @returns {Promise<void>}
*/
async scheduleClose(time, user) {
async scheduleClose(time, user, silent) {
await knex('threads')
.where('id', this.id)
.update({
scheduled_close_at: time,
scheduled_close_id: user.id,
scheduled_close_name: user.username
scheduled_close_name: user.username,
scheduled_close_silent: silent
});
}
@ -371,7 +378,8 @@ class Thread {
.update({
scheduled_close_at: null,
scheduled_close_id: null,
scheduled_close_name: null
scheduled_close_name: null,
scheduled_close_silent: null
});
}

View File

@ -14,8 +14,11 @@ module.exports = bot => {
async function applyScheduledCloses() {
const threadsToBeClosed = await threads.getThreadsThatShouldBeClosed();
for (const thread of threadsToBeClosed) {
if(config.closeMessage) await thread.postToUser(config.closeMessage).catch(() => {});
await thread.close();
if (config.closeMessage && ! thread.scheduled_close_silent) {
await thread.postToUser(config.closeMessage).catch(() => {});
}
await thread.close(false, thread.scheduled_close_silent);
const logUrl = await thread.getLogUrl();
utils.postLog(utils.trimAll(`
@ -41,7 +44,8 @@ module.exports = bot => {
bot.registerCommand('close', async (msg, args) => {
let thread, closedBy;
let sendCloseMessage = !! config.closeMessage;
let hasCloseMessage = !! config.closeMessage;
let silentClose = false;
if (msg.channel instanceof Eris.PrivateChannel) {
// User is closing the thread by themselves (if enabled)
@ -67,7 +71,6 @@ module.exports = bot => {
thread = await threads.findOpenThreadByChannelId(msg.channel.id);
if (! thread) return;
// Timed close
if (args.length) {
if (args.includes('cancel') || args.includes('c')) {
// Cancel timed close
@ -77,30 +80,46 @@ module.exports = bot => {
}
return;
} else if (args.includes('silent') || args.includes('s')) {
sendCloseMessage = false;
} else {
}
// Silent close (= no close message)
if (args.includes('silent') || args.includes('s')) {
silentClose = true;
}
// Timed close
const delayStringArg = args.find(arg => utils.delayStringRegex.test(arg));
if (delayStringArg) {
// Set a timed close
const delay = utils.convertDelayStringToMS(args.join(' '));
const delay = utils.convertDelayStringToMS(delayStringArg);
if (delay === 0 || delay === null) {
thread.postSystemMessage(`Invalid delay specified. Format: "1h30m"`);
return;
}
const closeAt = moment.utc().add(delay, 'ms');
await thread.scheduleClose(closeAt.format('YYYY-MM-DD HH:mm:ss'), msg.author);
thread.postSystemMessage(`Thread is now scheduled to be closed in ${humanizeDelay(delay)}. Use \`${config.prefix}close cancel\` to cancel.`);
await thread.scheduleClose(closeAt.format('YYYY-MM-DD HH:mm:ss'), msg.author, silentClose ? 1 : 0);
let response;
if (silentClose) {
response = `Thread is now scheduled to be closed silently in ${humanizeDelay(delay)}. Use \`${config.prefix}close cancel\` to cancel.`;
} else {
response = `Thread is now scheduled to be closed in ${humanizeDelay(delay)}. Use \`${config.prefix}close cancel\` to cancel.`;
}
thread.postSystemMessage(response);
return;
}
}
// Regular close
await thread.close();
await thread.close(false, silentClose);
closedBy = msg.author.username;
}
if (sendCloseMessage) {
// Send close message (unless suppressed with a silent close)
if (hasCloseMessage && ! silentClose) {
await thread.postToUser(config.closeMessage).catch(() => {});
}

View File

@ -220,19 +220,20 @@ function trimAll(str) {
.join('\n');
}
const delayStringRegex = /^([0-9]+)(?:([dhms])[a-z]*)?/i;
/**
* Turns a "delay string" such as "1h30m" to milliseconds
* @param {String} str
* @returns {Number}
*/
function convertDelayStringToMS(str) {
const regex = /^([0-9]+)\s*([dhms])?[a-z]*\s*/;
let match;
let ms = 0;
str = str.trim();
while (str !== '' && (match = str.match(regex)) !== null) {
while (str !== '' && (match = str.match(delayStringRegex)) !== null) {
if (match[2] === 'd') ms += match[1] * 1000 * 60 * 60 * 24;
else if (match[2] === 'h') ms += match[1] * 1000 * 60 * 60;
else if (match[2] === 's') ms += match[1] * 1000;
@ -312,6 +313,7 @@ module.exports = {
disableLinkPreviews,
getSelfUrl,
getMainRole,
delayStringRegex,
convertDelayStringToMS,
getInboxMention,
postSystemMessageWithFallback,