151 lines
4.2 KiB
JavaScript
151 lines
4.2 KiB
JavaScript
const path = require('path');
|
|
const fs = require('fs');
|
|
const fetch = require('node-fetch');
|
|
const { Util: DiscordUtil } = require('discord.js');
|
|
|
|
const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
|
|
|
|
class Util {
|
|
|
|
constructor() {
|
|
throw new Error("Class may not be instantiated.");
|
|
}
|
|
|
|
static paginate(items, page = 1, pageLength = 10) {
|
|
const maxPage = Math.ceil(items.length / pageLength);
|
|
if(page < 1) page = 1;
|
|
if(page > maxPage) page = maxPage;
|
|
const startIndex = (page - 1) * pageLength;
|
|
return {
|
|
items: items.length > pageLength ? items.slice(startIndex, startIndex + pageLength) : items,
|
|
page,
|
|
maxPage,
|
|
pageLength
|
|
};
|
|
}
|
|
|
|
static downloadAsBuffer(source) {
|
|
return new Promise((resolve, reject) => {
|
|
fetch(source).then((res) => {
|
|
if(res.ok) resolve(res.buffer());
|
|
else reject(res.statusText);
|
|
});
|
|
});
|
|
}
|
|
|
|
static readdirRecursive(directory) {
|
|
|
|
const result = [];
|
|
|
|
(function read(directory) {
|
|
const files = fs.readdirSync(directory);
|
|
for(const file of files) {
|
|
const filePath = path.join(directory, file);
|
|
|
|
if(fs.statSync(filePath).isDirectory()) {
|
|
read(filePath);
|
|
} else {
|
|
result.push(filePath);
|
|
}
|
|
}
|
|
}(directory));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
static wait(ms) {
|
|
return this.delayFor(ms);
|
|
}
|
|
|
|
static delayFor(ms) {
|
|
return new Promise((resolve) => {
|
|
setTimeout(resolve, ms);
|
|
});
|
|
}
|
|
|
|
static mergeDefault(def, given) {
|
|
if (!given) return def;
|
|
for (const key in def) {
|
|
if (!has(given, key) || given[key] === undefined) {
|
|
given[key] = def[key];
|
|
} else if (given[key] === Object(given[key])) {
|
|
given[key] = Util.mergeDefault(def[key], given[key]);
|
|
}
|
|
}
|
|
return given;
|
|
}
|
|
|
|
//Shard Managing
|
|
|
|
static fetchRecommendedShards(token, guildsPerShard = 1000) {
|
|
if(!token) throw new Error("[util] Token missing.");
|
|
return fetch("https://discord.com/api/v7/gateway/bot", {
|
|
method: 'GET',
|
|
headers: { Authorization: `Bot ${token.replace(/^Bot\s*/iu, '')}` }
|
|
}).then((res) => {
|
|
if (res.ok) return res.json();
|
|
throw res;
|
|
})
|
|
.then((data) => data.shards * (1000 / guildsPerShard));
|
|
}
|
|
|
|
static makePlainError(err) {
|
|
return {
|
|
name: err.name,
|
|
message: err.message,
|
|
stack: err.stack
|
|
};
|
|
}
|
|
|
|
static escapeMarkdown(text, options) {
|
|
return DiscordUtil.escapeMarkdown(text, options);
|
|
}
|
|
|
|
/**
|
|
* Sanitise user given regex; escapes unauthorised characters
|
|
*
|
|
* @static
|
|
* @param {string} input
|
|
* @param {string} [allowed=['?', '\\', '(', ')', '|']]
|
|
* @return {string} The sanitised expression
|
|
* @memberof Util
|
|
*/
|
|
static sanitiseRegex(input, allowed = ['?', '\\', '(', ')', '|']) {
|
|
if (!input) throw new Error('Missing input');
|
|
const reg = new RegExp(`[${this.regChars.filter((char) => !allowed.includes(char)).join('')}]`, 'gu');
|
|
return input.replace(reg, '\\$&');
|
|
}
|
|
|
|
static get regChars() {
|
|
return ['.', '+', '*', '?', '\\[', '\\]', '^', '$', '(', ')', '{', '}', '=', '<', '>', '|', ':', '\\\\', '-'];
|
|
}
|
|
|
|
static duration(seconds) {
|
|
const { plural } = this;
|
|
let s = 0,
|
|
m = 0,
|
|
h = 0,
|
|
d = 0,
|
|
w = 0;
|
|
s = Math.floor(seconds);
|
|
m = Math.floor(s/60);
|
|
s %= 60;
|
|
h = Math.floor(m/60);
|
|
m %= 60;
|
|
d = Math.floor(h/24);
|
|
h %= 24;
|
|
w = Math.floor(d/7);
|
|
d %= 7;
|
|
return `${w ? `${w} ${plural(w, 'week')} ` : ''}${d ? `${d} ${plural(d, 'day')} ` : ''}${h ? `${h} ${plural(h, 'hour')} ` : ''}${m ? `${m} ${plural(m, 'minute')} ` : ''}${s ? `${s} ${plural(s, 'second')} ` : ''}`.trim();
|
|
}
|
|
|
|
static plural(amt, word) {
|
|
if(amt === 1) return word;
|
|
return `${word}s`;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
module.exports = Util; |