API changes and new database models w/ new utils
parent
9762dd87cd
commit
98216ceecf
|
@ -23,5 +23,18 @@ export default class Root extends Route {
|
||||||
return res.status(500).json({ code: this.constants.codes.SERVER_ERROR, message: this.constants.messages.SERVER_ERROR });
|
return res.status(500).json({ code: this.constants.codes.SERVER_ERROR, message: this.constants.messages.SERVER_ERROR });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.router.get('/m/:id', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const id = req.params.id.split('.')[0];
|
||||||
|
const file = await this.server.client.db.File.findOne({ identifier: id });
|
||||||
|
if (file.downloaded >= file.maxDownloads) return res.status(404).json({ code: this.constants.codes.NOT_FOUND, message: this.constants.messages.NOT_FOUND });
|
||||||
|
res.contentType(file.mimeType);
|
||||||
|
res.status(200).send(file.data);
|
||||||
|
return await file.updateOne({ $inc: { downloaded: 1 } });
|
||||||
|
} catch (err) {
|
||||||
|
return this.handleError(err, res);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import eris from 'eris';
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import { Collection, Command, LocalStorage, Util, ServerManagement, Event } from '.';
|
import { Collection, Command, LocalStorage, Util, ServerManagement, Event } from '.';
|
||||||
import { Member, MemberInterface, Moderation, ModerationInterface, PagerNumber, PagerNumberInterface, Rank, RankInterface, Redirect, RedirectInterface } from '../models';
|
import { File, FileInterface, Member, MemberInterface, Moderation, ModerationInterface, PagerNumber, PagerNumberInterface, Rank, RankInterface, Redirect, RedirectInterface } from '../models';
|
||||||
|
|
||||||
export default class Client extends eris.Client {
|
export default class Client extends eris.Client {
|
||||||
public config: { token: string, prefix: string, guildID: string, mongoDB: string, emailPass: string, };
|
public config: { token: string, prefix: string, guildID: string, mongoDB: string, emailPass: string, };
|
||||||
|
@ -17,14 +17,14 @@ export default class Client extends eris.Client {
|
||||||
|
|
||||||
public serverManagement: ServerManagement;
|
public serverManagement: ServerManagement;
|
||||||
|
|
||||||
public db: { Member: mongoose.Model<MemberInterface>, Moderation: mongoose.Model<ModerationInterface>, PagerNumber: mongoose.Model<PagerNumberInterface>, Rank: mongoose.Model<RankInterface>, Redirect: mongoose.Model<RedirectInterface>, local: { muted: LocalStorage } };
|
public db: { File: mongoose.Model<FileInterface>, Member: mongoose.Model<MemberInterface>, Moderation: mongoose.Model<ModerationInterface>, PagerNumber: mongoose.Model<PagerNumberInterface>, Rank: mongoose.Model<RankInterface>, Redirect: mongoose.Model<RedirectInterface>, local: { muted: LocalStorage } };
|
||||||
|
|
||||||
constructor(token: string, options?: eris.ClientOptions) {
|
constructor(token: string, options?: eris.ClientOptions) {
|
||||||
super(token, options);
|
super(token, options);
|
||||||
this.commands = new Collection<Command>();
|
this.commands = new Collection<Command>();
|
||||||
this.events = new Collection<Event>();
|
this.events = new Collection<Event>();
|
||||||
this.intervals = new Collection<NodeJS.Timeout>();
|
this.intervals = new Collection<NodeJS.Timeout>();
|
||||||
this.db = { Member, Moderation, PagerNumber, Rank, Redirect, local: { muted: new LocalStorage('muted') } };
|
this.db = { File, Member, Moderation, PagerNumber, Rank, Redirect, local: { muted: new LocalStorage('muted') } };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadDatabase() {
|
public async loadDatabase() {
|
||||||
|
|
|
@ -17,8 +17,8 @@ export default class LocalStorage {
|
||||||
|
|
||||||
private locked: boolean = false;
|
private locked: boolean = false;
|
||||||
|
|
||||||
constructor(dbName: string) {
|
constructor(dbName: string, dir = `${__dirname}/../../localstorage`) {
|
||||||
this.storagePath = `${__dirname}/../../localstorage/${dbName}.json.gz`;
|
this.storagePath = `${dir}/${dbName}.json.gz`;
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ export default class Moderation {
|
||||||
return mod.save();
|
return mod.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async kick(user: Member|User, moderator: Member, reason?: string): Promise<ModerationInterface> {
|
public async kick(user: Member | User, moderator: Member, reason?: string): Promise<ModerationInterface> {
|
||||||
if (reason && reason.length > 512) throw new Error('Kick reason cannot be longer than 512 characters');
|
if (reason && reason.length > 512) throw new Error('Kick reason cannot be longer than 512 characters');
|
||||||
await this.client.guilds.get(this.client.config.guildID).kickMember(user.id, reason);
|
await this.client.guilds.get(this.client.config.guildID).kickMember(user.id, reason);
|
||||||
const logID = randomBytes(2).toString('hex');
|
const logID = randomBytes(2).toString('hex');
|
||||||
|
|
|
@ -45,7 +45,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Sets the title of this embed.
|
* Sets the title of this embed.
|
||||||
*/
|
*/
|
||||||
setTitle(title: string) {
|
public setTitle(title: string) {
|
||||||
if (typeof title !== 'string') throw new TypeError('RichEmbed titles must be a string.');
|
if (typeof title !== 'string') throw new TypeError('RichEmbed titles must be a string.');
|
||||||
if (title.length > 256) throw new RangeError('RichEmbed titles may not exceed 256 characters.');
|
if (title.length > 256) throw new RangeError('RichEmbed titles may not exceed 256 characters.');
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
@ -55,7 +55,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Sets the description of this embed.
|
* Sets the description of this embed.
|
||||||
*/
|
*/
|
||||||
setDescription(description: string) {
|
public setDescription(description: string) {
|
||||||
if (typeof description !== 'string') throw new TypeError('RichEmbed descriptions must be a string.');
|
if (typeof description !== 'string') throw new TypeError('RichEmbed descriptions must be a string.');
|
||||||
if (description.length > 2048) throw new RangeError('RichEmbed descriptions may not exceed 2048 characters.');
|
if (description.length > 2048) throw new RangeError('RichEmbed descriptions may not exceed 2048 characters.');
|
||||||
this.description = description;
|
this.description = description;
|
||||||
|
@ -65,7 +65,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Sets the URL of this embed.
|
* Sets the URL of this embed.
|
||||||
*/
|
*/
|
||||||
setURL(url: string) {
|
public setURL(url: string) {
|
||||||
if (typeof url !== 'string') throw new TypeError('RichEmbed URLs must be a string.');
|
if (typeof url !== 'string') throw new TypeError('RichEmbed URLs must be a string.');
|
||||||
if (!url.startsWith('http://') && !url.startsWith('https://')) url = `https://${url}`;
|
if (!url.startsWith('http://') && !url.startsWith('https://')) url = `https://${url}`;
|
||||||
this.url = encodeURI(url);
|
this.url = encodeURI(url);
|
||||||
|
@ -75,7 +75,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Sets the color of this embed.
|
* Sets the color of this embed.
|
||||||
*/
|
*/
|
||||||
setColor(color: string | number) {
|
public setColor(color: string | number) {
|
||||||
if (typeof color === 'string' || typeof color === 'number') {
|
if (typeof color === 'string' || typeof color === 'number') {
|
||||||
if (typeof color === 'string') {
|
if (typeof color === 'string') {
|
||||||
const regex = /[^a-f0-9]/gi;
|
const regex = /[^a-f0-9]/gi;
|
||||||
|
@ -92,7 +92,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Sets the author of this embed.
|
* Sets the author of this embed.
|
||||||
*/
|
*/
|
||||||
setAuthor(name: string, icon_url?: string, url?: string) {
|
public setAuthor(name: string, icon_url?: string, url?: string) {
|
||||||
if (typeof name !== 'string') throw new TypeError('RichEmbed Author names must be a string.');
|
if (typeof name !== 'string') throw new TypeError('RichEmbed Author names must be a string.');
|
||||||
if (url && typeof url !== 'string') throw new TypeError('RichEmbed Author URLs must be a string.');
|
if (url && typeof url !== 'string') throw new TypeError('RichEmbed Author URLs must be a string.');
|
||||||
if (icon_url && typeof icon_url !== 'string') throw new TypeError('RichEmbed Author icons must be a string.');
|
if (icon_url && typeof icon_url !== 'string') throw new TypeError('RichEmbed Author icons must be a string.');
|
||||||
|
@ -103,7 +103,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Sets the timestamp of this embed.
|
* Sets the timestamp of this embed.
|
||||||
*/
|
*/
|
||||||
setTimestamp(timestamp = new Date()) {
|
public setTimestamp(timestamp = new Date()) {
|
||||||
if (Number.isNaN(timestamp.getTime())) throw new TypeError('Expecting ISO8601 (Date constructor)');
|
if (Number.isNaN(timestamp.getTime())) throw new TypeError('Expecting ISO8601 (Date constructor)');
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
return this;
|
return this;
|
||||||
|
@ -112,7 +112,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Adds a field to the embed (max 25).
|
* Adds a field to the embed (max 25).
|
||||||
*/
|
*/
|
||||||
addField(name: string, value: string, inline = false) {
|
public addField(name: string, value: string, inline = false) {
|
||||||
if (typeof name !== 'string') throw new TypeError('RichEmbed Field names must be a string.');
|
if (typeof name !== 'string') throw new TypeError('RichEmbed Field names must be a string.');
|
||||||
if (typeof value !== 'string') throw new TypeError('RichEmbed Field values must be a string.');
|
if (typeof value !== 'string') throw new TypeError('RichEmbed Field values must be a string.');
|
||||||
if (typeof inline !== 'boolean') throw new TypeError('RichEmbed Field inlines must be a boolean.');
|
if (typeof inline !== 'boolean') throw new TypeError('RichEmbed Field inlines must be a boolean.');
|
||||||
|
@ -128,14 +128,14 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Convenience function for `<RichEmbed>.addField('\u200B', '\u200B', inline)`.
|
* Convenience function for `<RichEmbed>.addField('\u200B', '\u200B', inline)`.
|
||||||
*/
|
*/
|
||||||
addBlankField(inline = false) {
|
public addBlankField(inline = false) {
|
||||||
return this.addField('\u200B', '\u200B', inline);
|
return this.addField('\u200B', '\u200B', inline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the thumbnail of this embed.
|
* Set the thumbnail of this embed.
|
||||||
*/
|
*/
|
||||||
setThumbnail(url: string) {
|
public setThumbnail(url: string) {
|
||||||
if (typeof url !== 'string') throw new TypeError('RichEmbed Thumbnail URLs must be a string.');
|
if (typeof url !== 'string') throw new TypeError('RichEmbed Thumbnail URLs must be a string.');
|
||||||
this.thumbnail = { url };
|
this.thumbnail = { url };
|
||||||
return this;
|
return this;
|
||||||
|
@ -144,7 +144,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Set the image of this embed.
|
* Set the image of this embed.
|
||||||
*/
|
*/
|
||||||
setImage(url: string) {
|
public setImage(url: string) {
|
||||||
if (typeof url !== 'string') throw new TypeError('RichEmbed Image URLs must be a string.');
|
if (typeof url !== 'string') throw new TypeError('RichEmbed Image URLs must be a string.');
|
||||||
if (!url.startsWith('http://') || !url.startsWith('https://')) url = `https://${url}`;
|
if (!url.startsWith('http://') || !url.startsWith('https://')) url = `https://${url}`;
|
||||||
this.image = { url };
|
this.image = { url };
|
||||||
|
@ -154,7 +154,7 @@ export default class RichEmbed implements EmbedOptions {
|
||||||
/**
|
/**
|
||||||
* Sets the footer of this embed.
|
* Sets the footer of this embed.
|
||||||
*/
|
*/
|
||||||
setFooter(text: string, icon_url?: string) {
|
public setFooter(text: string, icon_url?: string) {
|
||||||
if (typeof text !== 'string') throw new TypeError('RichEmbed Footers must be a string.');
|
if (typeof text !== 'string') throw new TypeError('RichEmbed Footers must be a string.');
|
||||||
if (icon_url && typeof icon_url !== 'string') throw new TypeError('RichEmbed Footer icon URLs must be a string.');
|
if (icon_url && typeof icon_url !== 'string') throw new TypeError('RichEmbed Footer icon URLs must be a string.');
|
||||||
if (text.length > 2048) throw new RangeError('RichEmbed footer text may not exceed 2048 characters.');
|
if (text.length > 2048) throw new RangeError('RichEmbed footer text may not exceed 2048 characters.');
|
||||||
|
|
|
@ -131,6 +131,14 @@ export default class Util {
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public splitArray<T>(array: T[], count: number) {
|
||||||
|
const finalArray: T[][] = [];
|
||||||
|
while (array.length) {
|
||||||
|
finalArray.push(array.splice(0, count));
|
||||||
|
}
|
||||||
|
return finalArray;
|
||||||
|
}
|
||||||
|
|
||||||
public decimalToHex(int: number): string {
|
public decimalToHex(int: number): string {
|
||||||
const hex = int.toString(16);
|
const hex = int.toString(16);
|
||||||
return '#000000'.substring(0, 7 - hex.length) + hex;
|
return '#000000'.substring(0, 7 - hex.length) + hex;
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Document, Schema, model } from 'mongoose';
|
||||||
|
|
||||||
|
export interface FileInterface extends Document {
|
||||||
|
name: string,
|
||||||
|
identifier: string,
|
||||||
|
mimeType: string,
|
||||||
|
data: Buffer,
|
||||||
|
downloaded: number,
|
||||||
|
maxDownloads: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
const File: Schema = new Schema({
|
||||||
|
name: String,
|
||||||
|
identifier: String,
|
||||||
|
mimeType: String,
|
||||||
|
data: Buffer,
|
||||||
|
downloaded: Number,
|
||||||
|
maxDownloads: Number,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default model<FileInterface>('File', File);
|
|
@ -1,3 +1,4 @@
|
||||||
|
export { default as File, FileInterface } from './File';
|
||||||
export { default as Member, MemberInterface } from './Member';
|
export { default as Member, MemberInterface } from './Member';
|
||||||
export { default as Moderation, ModerationInterface } from './Moderation';
|
export { default as Moderation, ModerationInterface } from './Moderation';
|
||||||
export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber';
|
export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber';
|
||||||
|
|
Loading…
Reference in New Issue