Verified Commit 118166be authored by recette lemonweed's avatar recette lemonweed 🇮🇸

created reverse image search command

parent 8bf50453
module.exports = {
name: "Reverse Image Search",
triggers: ["ris", "rimg"],
description: "Searches various services for images, or just gives a link to the site. Defaults to Google.",
category: "search",
arguments: {
flags: {
backend: {
google: [false, "g"],
tineye: [false, "tin", "t"],
whatanime: [false, "wa", "trace", "a"],
iqdb: [false, "i"],
saucenao: [false, "sauce", "sn", "s"]
}
}
},
func
};
let Request = require("request");
let HTMLParse = require("node-html-parser").parse;
function google(message, url){ // trying to actually parse the site is wasted effort
let embed = new Discord.RichEmbed({
title: "Google.com",
color: Config.embedColour,
url: "https://www.google.com/searchbyimage?&image_url="+url
});
message.reply({embed});
}
function tineye(message, url){
let embed = new Discord.RichEmbed({
title: "Tineye.com",
color: Config.embedColour,
url: "https://tineye.com/search?url=" + encodeURIComponent(url)
});
message.reply({embed});
}
function saucenao(message, url){
Request.get("https://saucenao.com/search.php?url="+encodeURIComponent(url), (err, res, bod) => {
if(err || !bod)
return message.reply("Couldn't get results.");
let results = [];
for(let t of HTMLParse(bod).querySelectorAll(".result")){
if(t.getAttribute("id") === "result-hidden-notification")
break;
results.push({
thumbnail: t.querySelector("img").getAttribute("src"),
content: t.querySelector(".resulttablecontent").structuredText
});
}
if(results.length === 0)
return message.reply("Nothing found.");
let embed = new Discord.RichEmbed({
color: Config.embedColour,
fields: [
{
name: "SauceNAO",
value: results[0].content
}
],
thumbnail: {
url: results[0].thumbnail
},
footer: {
text: "#1 of "+results.length
}
});
message.channel.send({embed}).then(mes=>{
let controls = new Utility.MessageControls(mes, message.author);
let index = 0;
controls.on("reaction", r => {
if(r.n === 0 && results[index-1])
index--;
else if(r.n === 1 && results[index+1])
index++;
else return;
embed.fields[0].value = results[index].content;
embed.thumbnail.url = results[index].thumbnail;
embed.footer.text = "#"+(index+1)+" of "+results.length;
mes.edit({embed});
});
});
});
}
function iqdb(message, url){
Request.get("https://iqdb.org/?url="+encodeURIComponent(url), (err, res, bod) => {
if(err || !bod)
return message.reply("Couldn't get results.");
let results = [];
for(let t of HTMLParse(bod).querySelectorAll("#pages table").slice(1)){
let td = t.querySelectorAll("td");
let link = t.querySelector("a").getAttribute("href");
let thumbnail = t.querySelector("img");
if(!thumbnail)
continue;
thumbnail = "https://iqdb.org"+thumbnail.getAttribute("src");
results.push({
link: link.startsWith("http") ? link : "https:"+link,
thumbnail: thumbnail,
info: td[2].structuredText,
similarity: td[3].structuredText,
service: thumbnail.split("/")[3]
});
}
if(!results[0])
return message.reply("No results.");
let embed = new Discord.RichEmbed({
title: results[0].service,
url: results[0].link,
color: Config.embedColour,
thumbnail: {
url: results[0].thumbnail
},
footer: {
text: `#1 of ${results.length} `+results[0].info,
}
});
message.channel.send({embed}).then(mes=>{
let controls = new Utility.MessageControls(mes, message.author);
let index = 0;
controls.on("reaction", r => {
if(r.n === 0 && results[index-1])
index--;
else if(r.n === 1 && results[index+1])
index++;
else return;
embed.title = results[index].service;
embed.url = results[index].link;
embed.thumbnail.url = results[index].thumbnail;
embed.footer.text = `#${index+1} of ${results.length} `+results[index].info;
mes.edit({embed});
});
});
});
}
function whatanime(message, url){
Request.get("https://trace.moe/api/search?url="+url, (err, res, bod) => {
if(err || !bod)
return message.reply("Couldn't get results.");
let json = JSON.parse(bod);
let docs = json.docs[0];
if(!docs)
return message.reply("Couldn't get a hit.");
let thumbnail = `https://trace.moe/thumbnail.php?anilist_id=${docs.anilist_id}&file=${encodeURIComponent(docs.filename)}&t=${docs.at}&token=${docs.tokenthumb}`;
let embed = new Discord.RichEmbed({
title: docs.title_english,
description: docs.title_romaji,
color: Config.embedColour,
thumbnail: {
url: thumbnail
},
footer: {
text: (docs.similarity * 100).toFixed(2) + "% similarity."
}
});
embed.addField("Duration", Utility.toHHMMSS(docs.from|0).replace(/^00:/, "")+"-"+Utility.toHHMMSS(docs.to|0).replace(/^00:/, ""), true);
embed.addField("Episode", docs.episode || "?", true);
embed.addField("Links", `[MAL](https://myanimelist.net/anime/${docs.mal_id}) [Anilist](https://anilist.co/anime/${docs.anilist_id})`, true);
message.reply({embed});
});
}
let backends = {google, whatanime, iqdb, saucenao, tineye};
function func(message, args){
let url = Utility.getImage(message);
let backend = args.backend || "google";
if(!url)
return message.reply("No idea what image you want me to search with.");
backends[backend](message, url);
}
{
"name": "Ika3",
"version": "3.3.1",
"version": "3.3.2",
"description": "v3 of the Ika Discord bot, built for the DMC Discord server.",
"main": "index.js",
"scripts": {
......@@ -25,6 +25,7 @@
"dependencies": {
"discord.js": "^11.6.3",
"minimist": "https://github.com/recette-lemon/minimist-without-numbers",
"node-html-parser": "^1.2.16",
"request": "^2.88.2",
"sqlite": "^3.0.3"
}
......
......@@ -129,7 +129,7 @@ module.exports.imageCommand = function(message, folder){
ext = file.split(".").pop(),
name = folder+"-"+(n+1)+"."+ext;
let embed = ~["png", "jpg", "jpeg", "gif", "webp"].indexOf(ext.toLowerCase()) ? new Discord.RichEmbed({
let embed = isImageExt(ext) ? new Discord.RichEmbed({
color: Config.embedColour,
image: {url: "attachment://"+name},
footer: {
......@@ -160,3 +160,28 @@ module.exports.getUser = function(message, args){
}
return Bot.users.get(args._[0]);
};
function isImageExt(file){
return ~["png", "jpg", "jpeg", "gif", "webp"].indexOf(file.split(".").pop());
}
function parseMessageForImages(message){
if(message.attachments.first())
return message.attachments.first().url;
if(message.embeds[0] && message.embeds[0].image)
return message.embeds[0].image.url;
let args = message.content.split(" ");
return args.find(a => a.startsWith("http") && isImageExt(a));
}
module.exports.getImage = function(message){ // still need to expand to cover more cases
let url = parseMessageForImages(message);
if(!url){
for(let mes of message.channel.messages.array().reverse()){
url = parseMessageForImages(mes);
if(url)
return url;
}
}
return url;
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment