Added gif, detect if any image servers are disconnected

This commit is contained in:
Essem 2021-06-28 17:59:05 -05:00
parent 0fbc165154
commit 41c8be04cf
7 changed files with 523 additions and 437 deletions

View File

@ -52,7 +52,7 @@ class ImageCommand extends Command {
if (this.constructor.requiresImage) {
try {
const image = await imageDetect(this.client, this.message);
const image = await imageDetect(this.client, this.message, true);
if (image === undefined) {
collections.runningCommands.delete(this.message.author.id);
return this.constructor.noImage;
@ -61,7 +61,7 @@ class ImageCommand extends Command {
return "That image is too large!";
} else if (image.type === "tenorlimit") {
collections.runningCommands.delete(this.message.author.id);
return "I've been rate-limited by Tenor. Please try uploading the GIF elsewhere.";
return "I've been rate-limited by Tenor. Please try uploading your GIF elsewhere.";
}
magickParams.path = image.path;
magickParams.type = image.type;

16
commands/general/gif.js Normal file
View File

@ -0,0 +1,16 @@
const Command = require("../../classes/command.js");
const imageDetect = require("../../utils/imagedetect.js");
class GifCommand extends Command {
async run() {
this.message.channel.sendTyping();
const image = await imageDetect(this.client, this.message);
if (image === undefined) return "You need to provide an image with a QR code to read!";
return image.path;
}
static description = "Gets a direct GIF URL (useful for saving GIFs from sites like Tenor)";
static aliases = ["getgif", "giflink"];
}
module.exports = GifCommand;

View File

@ -13,6 +13,7 @@ Napi::Value Snapchat(const Napi::CallbackInfo &info) {
Napi::Object obj = info[0].As<Napi::Object>();
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
float pos = obj.Has("pos") ? obj.Get("pos").As<Napi::Number>().FloatValue() : 0.5;
string type = obj.Get("type").As<Napi::String>().Utf8Value();
int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
@ -26,6 +27,7 @@ Napi::Value Snapchat(const Napi::CallbackInfo &info) {
readImages(&frames, Blob(data.Data(), data.Length()));
size_t width = frames.front().baseColumns();
size_t height = frames.front().baseRows();
string query(to_string(width - ((width / 25) * 2)) + "x");
Image caption_image(Geometry(query), Color("none"));
caption_image.backgroundColor(Color("none"));
@ -42,7 +44,7 @@ Napi::Value Snapchat(const Napi::CallbackInfo &info) {
for (Image &image : coalesced) {
list<Image> images;
image.composite(caption_image, Magick::CenterGravity,
image.composite(caption_image, 0, height * pos,
Magick::OverCompositeOp);
image.magick(type);
image.animationDelay(delay == 0 ? image.animationDelay() : delay);

900
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@
"file-type": "^16.1.0",
"jsqr": "^1.3.1",
"lavacord": "^1.1.9",
"node-addon-api": "^3.1.0",
"node-addon-api": "^3.2.1",
"node-emoji": "^1.10.0",
"node-fetch": "^2.6.1",
"qrcode": "^1.4.4",

View File

@ -123,10 +123,10 @@ exports.disconnect = async () => {
const getIdeal = async () => {
let serversLeft = this.connections.size;
if (serversLeft === 0) {
if (serversLeft < this.servers.length) {
for (const server of this.servers) {
try {
await this.connect(server);
if (!this.connections.has(server)) await this.connect(server);
} catch (e) {
logger.error(e);
}
@ -193,7 +193,7 @@ exports.check = (cmd) => {
return magick[cmd] ? true : false;
};
exports.getType = async (image) => {
exports.getType = async (image, extraReturnTypes) => {
if (!image.startsWith("http")) {
const imageType = await fileType.fromFile(image);
if (imageType && formats.includes(imageType.mime)) {
@ -214,7 +214,7 @@ exports.getType = async (image) => {
});
clearTimeout(timeout);
const size = imageRequest.headers.has("Content-Range") ? imageRequest.headers.get("Content-Range").split("/")[1] : imageRequest.headers.get("Content-Length");
if (parseInt(size) > 26214400) { // 25 MB
if (parseInt(size) > 26214400 && extraReturnTypes) { // 25 MB
type = "large";
return type;
}

View File

@ -34,7 +34,7 @@ const imageFormats = ["image/jpeg", "image/png", "image/webp", "image/gif"];
const videoFormats = ["video/mp4", "video/webm", "video/mov"];
// gets the proper image paths
const getImage = async (image, image2, video, gifv = false) => {
const getImage = async (image, image2, video, extraReturnTypes, gifv = false) => {
try {
const payload = {
url: image2,
@ -48,7 +48,7 @@ const getImage = async (image, image2, video, gifv = false) => {
// Note that MP4 conversion requires an ImageMagick build that supports MPEG decoding
if (process.env.TENOR !== "") {
const data = await fetch(`https://g.tenor.com/v1/gifs?ids=${image2.split("-").pop()}&media_filter=minimal&limit=1&key=${process.env.TENOR}`);
if (data.status === 429) return "tenorlimit";
if (data.status === 429) return extraReturnTypes ? "tenorlimit" : null;
const json = await data.json();
payload.path = json.results[0].media[0].gif.url;
} else {
@ -69,10 +69,10 @@ const getImage = async (image, image2, video, gifv = false) => {
}
payload.type = "image/gif";
} else if (video) {
payload.type = await getType(payload.path);
payload.type = await getType(payload.path, extraReturnTypes);
if (!payload.type || (!videoFormats.includes(payload.type) && !imageFormats.includes(payload.type))) return;
} else {
payload.type = await getType(payload.path);
payload.type = await getType(payload.path, extraReturnTypes);
if (!payload.type || !imageFormats.includes(payload.type)) return;
}
return payload;
@ -85,22 +85,22 @@ const getImage = async (image, image2, video, gifv = false) => {
}
};
const checkImages = async (message, video) => {
const checkImages = async (message, extraReturnTypes, video) => {
let type;
// first check the embeds
if (message.embeds.length !== 0) {
// embeds can vary in types, we check for tenor gifs first
if (message.embeds[0].type === "gifv") {
type = await getImage(message.embeds[0].video.url, message.embeds[0].url, video, true);
type = await getImage(message.embeds[0].video.url, message.embeds[0].url, video, extraReturnTypes, true);
// then we check for other image types
} else if ((message.embeds[0].type === "video" || message.embeds[0].type === "image") && message.embeds[0].thumbnail) {
type = await getImage(message.embeds[0].thumbnail.proxy_url, message.embeds[0].thumbnail.url, video);
type = await getImage(message.embeds[0].thumbnail.proxy_url, message.embeds[0].thumbnail.url, video, extraReturnTypes);
// finally we check both possible image fields for "generic" embeds
} else if (message.embeds[0].type === "rich") {
if (message.embeds[0].thumbnail) {
type = await getImage(message.embeds[0].thumbnail.proxy_url, message.embeds[0].thumbnail.url, video);
type = await getImage(message.embeds[0].thumbnail.proxy_url, message.embeds[0].thumbnail.url, video, extraReturnTypes);
} else if (message.embeds[0].image) {
type = await getImage(message.embeds[0].image.proxy_url, message.embeds[0].image.url, video);
type = await getImage(message.embeds[0].image.proxy_url, message.embeds[0].image.url, video, extraReturnTypes);
}
}
// then check the attachments
@ -112,23 +112,23 @@ const checkImages = async (message, video) => {
};
// this checks for the latest message containing an image and returns the url of the image
module.exports = async (client, cmdMessage, video = false) => {
module.exports = async (client, cmdMessage, extraReturnTypes = false, video = false) => {
// we start by checking if the message is a reply to another message
if (cmdMessage.messageReference) {
const replyMessage = await client.getMessage(cmdMessage.messageReference.channelID, cmdMessage.messageReference.messageID).catch(() => undefined);
if (replyMessage) {
const replyResult = await checkImages(replyMessage, video);
const replyResult = await checkImages(replyMessage, extraReturnTypes, video);
if (replyResult !== false) return replyResult;
}
}
// then we check the current message
const result = await checkImages(cmdMessage, video);
const result = await checkImages(cmdMessage, extraReturnTypes, video);
if (result !== false) return result;
// if there aren't any replies then iterate over the last few messages in the channel
const messages = await client.getMessages(cmdMessage.channel.id);
// iterate over each message
for (const message of messages) {
const result = await checkImages(message, video);
const result = await checkImages(message, extraReturnTypes, video);
if (result === false) {
continue;
} else {