modmail/structure/JsonCache.js

126 lines
4.1 KiB
JavaScript
Raw Normal View History

2021-06-20 13:11:21 +02:00
const fs = require('fs');
2021-10-22 09:35:04 +02:00
const CacheHandler = require('./abstractions/CacheHandler');
2021-06-20 13:11:21 +02:00
2021-10-22 09:35:04 +02:00
class JsonCache extends CacheHandler {
2021-06-20 13:11:21 +02:00
2021-10-22 09:35:04 +02:00
constructor (client) {
super(client);
2021-06-20 13:11:21 +02:00
const opts = client._options;
this.logger = client.logger;
this.saveInterval = opts.saveInterval;
this._ready = false;
2021-07-19 21:30:31 +02:00
// Data that gets stored to persistent cache
2021-06-20 13:11:21 +02:00
this.queue = [];
this.channels = {};
this.lastActivity = {};
2021-07-19 21:30:31 +02:00
this.misc = {}; // Random misc data, should not be non-primitive data types
2021-06-20 13:11:21 +02:00
2021-07-19 21:30:31 +02:00
// Stored separately if at all
2021-06-20 13:11:21 +02:00
this.modmail = {};
this.updatedThreads = [];
}
2021-10-22 09:35:04 +02:00
load () {
2021-06-20 13:11:21 +02:00
if (this._ready) return;
if (fs.existsSync('./persistent_cache.json')) {
this.logger.info('Loading cache');
const raw = JSON.parse(fs.readFileSync('./persistent_cache.json', { encoding: 'utf-8' }));
const entries = Object.entries(raw);
2021-10-22 09:35:04 +02:00
for (const [ key, val ] of entries) this[key] = val;
2021-06-20 13:11:21 +02:00
} else {
this.logger.info('Cache file missing, creating...');
2021-10-22 09:35:04 +02:00
this.savePersistentCache();
2021-06-20 13:11:21 +02:00
}
2021-10-22 09:35:04 +02:00
this.cacheSaveInterval = setInterval(this.savePersistentCache.bind(this), 10 * 60 * 1000);
2021-06-21 16:54:05 +02:00
this.modmailSaveInterval = setInterval(this.saveModmailHistory.bind(this), this.saveInterval * 60 * 1000, this.client.modmail);
2021-06-20 13:11:21 +02:00
this._ready = true;
}
2021-10-22 09:35:04 +02:00
savePersistentCache () {
2021-06-20 13:11:21 +02:00
this.logger.debug('Saving cache');
fs.writeFileSync('./persistent_cache.json', JSON.stringify(this.json));
}
2021-10-22 09:35:04 +02:00
saveModmailHistory () {
2021-06-20 13:11:21 +02:00
if (!this.updatedThreads.length) return;
2021-10-22 09:35:04 +02:00
const toSave = [ ...this.updatedThreads ];
2021-06-20 13:11:21 +02:00
this.updatedThreads = [];
this.client.logger.debug(`Saving modmail data`);
if (!fs.existsSync('./modmail_cache')) fs.mkdirSync('./modmail_cache');
for (const id of toSave) {
const path = `./modmail_cache/${id}.json`;
try {
fs.writeFileSync(path, JSON.stringify(this.modmail[id]));
} catch (err) {
this.client.logger.error(`Error during saving of history\n${id}\n${JSON.stringify(this.modmail)}\n${err.stack}`);
}
}
}
2021-10-22 09:35:04 +02:00
loadModmailHistory (userId) {
2021-06-20 13:11:21 +02:00
return new Promise((resolve, reject) => {
if (this.modmail[userId]) return resolve(this.modmail[userId]);
const path = `./modmail_cache/${userId}.json`;
if (!fs.existsSync(path)) {
this.modmail[userId] = [];
return resolve(this.modmail[userId]);
}
fs.readFile(path, { encoding: 'utf-8' }, (err, data) => {
if (err) reject(err);
const parsed = JSON.parse(data);
this.modmail[userId] = parsed;
resolve(parsed);
});
});
}
verifyQueue () {
this.client.logger.info(`Verifying modmail queue.`);
this.queue.forEach(async entry => {
const path = `./modmail_cache/${entry}.json`;
if (fs.existsSync(path)) return;
this.client.logger.warn(`User ${entry} is in queue but is missing history. Attempting to recover history.`);
const user = await this.client.resolveUser(entry);
const dm = await user.createDM();
let messages = await dm.messages.fetch();
messages = messages.filter(msg => msg.author.id !== this.client.user.id).sort((a, b) => a.createdTimestamp - b.createdTimestamp);
const history = await this.loadModmailHistory(entry);
for (const { author, content, createdTimestamp, attachments } of messages) history.push({ attachments: attachments.map(att => att.url), author: author.id, content, timestamp: createdTimestamp });
});
this.client.logger.info(`Queue verified.`);
}
2021-10-22 09:35:04 +02:00
get json () {
2021-06-20 13:11:21 +02:00
return {
queue: this.queue,
channels: this.channels,
2021-07-19 21:30:31 +02:00
lastActivity: this.lastActivity,
misc: this.misc
2021-06-20 13:11:21 +02:00
};
}
}
2021-10-22 09:35:04 +02:00
module.exports = JsonCache;