update some deps
This commit is contained in:
parent
67e0ba8383
commit
7231dea945
3 changed files with 481 additions and 481 deletions
|
@ -27,7 +27,7 @@
|
|||
"node-ffprobe": "^3.0.0",
|
||||
"sharp": "^0.28.3",
|
||||
"sqlite3": "^5.0.2",
|
||||
"ytdl-core": "^4.9.1"
|
||||
"ytdl-core": "4.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.26.0",
|
||||
|
|
|
@ -13,12 +13,12 @@ specifiers:
|
|||
prettier: ^2.3.0
|
||||
sharp: ^0.28.3
|
||||
sqlite3: ^5.0.2
|
||||
ytdl-core: ^4.9.1
|
||||
ytdl-core: 4.11.0
|
||||
|
||||
dependencies:
|
||||
'@ctrl/tinycolor': 3.4.1
|
||||
dumpy: github.com/Cynosphere/dumpy.js/5fc22353cdcb97084bab572266390e780d9f7a7b
|
||||
eris: github.com/abalabahaha/eris/bd58677d91b532dd06227e73824b2cb40de9e816
|
||||
eris: github.com/abalabahaha/eris/4ea56e45ffe68e95d89d7f3edcc181097f4f9f8d
|
||||
google-images: 2.1.0
|
||||
jimp: 0.16.1
|
||||
murmurhash: 2.0.0
|
||||
|
@ -26,7 +26,7 @@ dependencies:
|
|||
node-ffprobe: 3.0.0
|
||||
sharp: 0.28.3
|
||||
sqlite3: 5.0.2
|
||||
ytdl-core: 4.9.1
|
||||
ytdl-core: 4.11.0
|
||||
|
||||
devDependencies:
|
||||
eslint: 7.26.0
|
||||
|
@ -695,7 +695,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/color-name/1.1.3:
|
||||
resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=}
|
||||
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
|
||||
|
||||
/color-name/1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
@ -1442,11 +1442,11 @@ packages:
|
|||
dependencies:
|
||||
yallist: 4.0.0
|
||||
|
||||
/m3u8stream/0.8.4:
|
||||
resolution: {integrity: sha512-sco80Db+30RvcaIOndenX6E6oQNgTiBKeJbFPc+yDXwPQIkryfboEbCvXPlBRq3mQTCVPQO93TDVlfRwqpD35w==}
|
||||
engines: {node: '>=10'}
|
||||
/m3u8stream/0.8.6:
|
||||
resolution: {integrity: sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
miniget: 4.2.1
|
||||
miniget: 4.2.2
|
||||
sax: 1.2.4
|
||||
dev: false
|
||||
|
||||
|
@ -1481,9 +1481,9 @@ packages:
|
|||
dom-walk: 0.1.2
|
||||
dev: false
|
||||
|
||||
/miniget/4.2.1:
|
||||
resolution: {integrity: sha512-O/DduzDR6f+oDtVype9S/Qu5hhnx73EDYGyZKwU/qN82lehFZdfhoa4DT51SpsO+8epYrB3gcRmws56ROfTIoQ==}
|
||||
engines: {node: '>=10'}
|
||||
/miniget/4.2.2:
|
||||
resolution: {integrity: sha512-a7voNL1N5lDMxvTMExOkg+Fq89jM2vY8pAi9ZEWzZtfNmdfP6RXkvUtFnCAXoCv2T9k1v/fUJVaAEuepGcvLYA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/minimatch/3.0.4:
|
||||
|
@ -2231,7 +2231,7 @@ packages:
|
|||
dev: false
|
||||
|
||||
/tweetnacl/0.14.5:
|
||||
resolution: {integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=}
|
||||
resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
|
@ -2387,12 +2387,12 @@ packages:
|
|||
/yallist/4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
|
||||
/ytdl-core/4.9.1:
|
||||
resolution: {integrity: sha512-6Jbp5RDhUEozlaJQAR+l8oV8AHsx3WUXxSyPxzE6wOIAaLql7Hjiy0ZM58wZoyj1YEenlEPjEqcJIjKYKxvHtQ==}
|
||||
engines: {node: '>=10'}
|
||||
/ytdl-core/4.11.0:
|
||||
resolution: {integrity: sha512-Q3hCLiUA9AOGQXzPvno14GN+HgF9wsO1ZBHlj0COTcyxjIyFpWvMfii0UC4/cAbVaIjEdbWB71GdcGuc4J1Lmw==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
m3u8stream: 0.8.4
|
||||
miniget: 4.2.1
|
||||
m3u8stream: 0.8.6
|
||||
miniget: 4.2.2
|
||||
sax: 1.2.4
|
||||
dev: false
|
||||
|
||||
|
@ -2407,10 +2407,10 @@ packages:
|
|||
node-fetch: 2.6.1
|
||||
dev: false
|
||||
|
||||
github.com/abalabahaha/eris/bd58677d91b532dd06227e73824b2cb40de9e816:
|
||||
resolution: {tarball: https://codeload.github.com/abalabahaha/eris/tar.gz/bd58677d91b532dd06227e73824b2cb40de9e816}
|
||||
github.com/abalabahaha/eris/4ea56e45ffe68e95d89d7f3edcc181097f4f9f8d:
|
||||
resolution: {tarball: https://codeload.github.com/abalabahaha/eris/tar.gz/4ea56e45ffe68e95d89d7f3edcc181097f4f9f8d}
|
||||
name: eris
|
||||
version: 0.17.1-dev
|
||||
version: 0.17.2-dev
|
||||
engines: {node: '>=10.4.0'}
|
||||
dependencies:
|
||||
ws: 8.5.0
|
||||
|
|
|
@ -1,460 +1,460 @@
|
|||
const Command = require("../lib/command.js");
|
||||
const CATEGORY = "misc";
|
||||
|
||||
const fetch = require("node-fetch");
|
||||
const {
|
||||
hastebin,
|
||||
safeString,
|
||||
parseHtmlEntities,
|
||||
formatTime,
|
||||
} = require("../lib/utils.js");
|
||||
const GoogleImages = require("google-images");
|
||||
|
||||
const imagesClient = new GoogleImages(hf.apikeys.gimg, hf.apikeys.google);
|
||||
|
||||
const yt = new Command("youtube");
|
||||
yt.addAlias("yt");
|
||||
yt.category = CATEGORY;
|
||||
yt.helpText = "Search YouTube";
|
||||
yt.usage = "[search term]";
|
||||
yt.callback = async function (msg, line) {
|
||||
if (!line) return "Arguments are required.";
|
||||
|
||||
const req = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/search?key=${
|
||||
hf.apikeys.google
|
||||
}&maxResults=5&part=snippet&type=video&q=${encodeURIComponent(line)}`
|
||||
).then((x) => x.json());
|
||||
|
||||
const topVid = req.items[0];
|
||||
|
||||
let out = `**${safeString(
|
||||
parseHtmlEntities(topVid.snippet.title)
|
||||
)}** | \`${safeString(
|
||||
parseHtmlEntities(topVid.snippet.channelTitle)
|
||||
)}\`\nhttps://youtu.be/${topVid.id.videoId}\n\n**__See Also:__**\n`;
|
||||
|
||||
for (let i = 1; i < req.items.length; i++) {
|
||||
const vid = req.items[i];
|
||||
out += `- **${safeString(
|
||||
parseHtmlEntities(vid.snippet.title)
|
||||
)}** | By: \`${safeString(
|
||||
parseHtmlEntities(vid.snippet.channelTitle)
|
||||
)}\` | <https://youtu.be/${vid.id.videoId}>\n`;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
hf.registerCommand(yt);
|
||||
|
||||
const fyt = new Command("fyt");
|
||||
fyt.category = CATEGORY;
|
||||
fyt.helpText = "Search YouTube and take the first result.";
|
||||
fyt.usage = "[search term]";
|
||||
fyt.callback = async function (msg, line) {
|
||||
if (!line) return "Arguments are required.";
|
||||
|
||||
const req = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/search?key=${
|
||||
hf.apikeys.google
|
||||
}&maxResults=2&part=snippet&type=video&q=${encodeURIComponent(line)}`
|
||||
).then((x) => x.json());
|
||||
|
||||
const vid = req.items[0];
|
||||
|
||||
return `**${safeString(
|
||||
parseHtmlEntities(vid.snippet.title)
|
||||
)}** | \`${safeString(
|
||||
parseHtmlEntities(vid.snippet.channelTitle)
|
||||
)}\`\nhttps://youtu.be/${vid.id.videoId}`;
|
||||
};
|
||||
hf.registerCommand(fyt);
|
||||
|
||||
const WA_NO_ANSWER = "<:ms_cross:503341994974773250> No answer.";
|
||||
|
||||
const wolfram = new Command("wolfram");
|
||||
wolfram.category = CATEGORY;
|
||||
wolfram.helpText = "Wolfram Alpha";
|
||||
wolfram.usage = "<-v> [query]";
|
||||
wolfram.addAlias("wa");
|
||||
wolfram.callback = async function (msg, line) {
|
||||
let verbose = false;
|
||||
|
||||
if (line.includes("-v")) {
|
||||
line = line.replace("-v", "").trim();
|
||||
verbose = true;
|
||||
}
|
||||
|
||||
const req = await fetch(
|
||||
`http://api.wolframalpha.com/v2/query?input=${encodeURIComponent(
|
||||
line
|
||||
)}&appid=LH2K8H-T3QKETAGT3&output=json`
|
||||
).then((x) => x.json());
|
||||
|
||||
const data = req.queryresult.pods;
|
||||
|
||||
if (!data) return WA_NO_ANSWER;
|
||||
|
||||
// fake no answer
|
||||
if (data[0].subpods[0].plaintext.includes("geoIP")) return WA_NO_ANSWER;
|
||||
|
||||
if (verbose) {
|
||||
const embed = {
|
||||
title: `Result for: \`${safeString(line)}\``,
|
||||
fields: [],
|
||||
footer: {
|
||||
icon_url: "http://www.wolframalpha.com/share.png",
|
||||
text: "Powered by Wolfram Alpha",
|
||||
},
|
||||
image: {
|
||||
url: data[1].subpods[0].img.src,
|
||||
},
|
||||
};
|
||||
|
||||
const extra = data.slice(1, 6);
|
||||
for (const x in extra) {
|
||||
embed.fields.push({
|
||||
name: extra[x].title,
|
||||
value: `[${
|
||||
extra[x].subpods[0].plaintext.length > 0
|
||||
? extra[x].subpods[0].plaintext
|
||||
: "<click for image>"
|
||||
}](${extra[x].subpods[0].img.src})`,
|
||||
inline: true,
|
||||
});
|
||||
}
|
||||
|
||||
return {embed};
|
||||
} else {
|
||||
let image;
|
||||
|
||||
if (data[1].subpods[0].img.src)
|
||||
try {
|
||||
const res = await fetch(data[1].subpods[0].img.src);
|
||||
if (res) {
|
||||
const imgData = await res.arrayBuffer();
|
||||
image = Buffer.from(imgData);
|
||||
}
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
|
||||
let string = "";
|
||||
if (data[1].subpods[0].plaintext.length > 0)
|
||||
string = safeString(data[1].subpods[0].plaintext);
|
||||
|
||||
if (string.length > 2000 - (6 + safeString(line).length))
|
||||
string = "Output too long: " + (await hastebin(string));
|
||||
|
||||
return {
|
||||
content: `\`${safeString(line)}\` -> ${string.length > 0 ? string : ""}`,
|
||||
file: image && {
|
||||
file: image,
|
||||
name: "wolfram_output.gif",
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
hf.registerCommand(wolfram);
|
||||
|
||||
const gimg = new Command("gimg");
|
||||
gimg.category = CATEGORY;
|
||||
gimg.helpText = "Search Google Images";
|
||||
gimg.usage = "[query]";
|
||||
gimg.addAlias("img");
|
||||
gimg.callback = async function (msg, line) {
|
||||
if (!line) return "No arguments given.";
|
||||
|
||||
const images = await imagesClient.search(line, {
|
||||
safe:
|
||||
msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]")
|
||||
? "off"
|
||||
: "high",
|
||||
});
|
||||
|
||||
const index = Math.floor(Math.random() * images.length);
|
||||
const image = images[index];
|
||||
|
||||
return {
|
||||
embeds: [
|
||||
{
|
||||
title: image.description,
|
||||
url: image.parentPage,
|
||||
image: {
|
||||
url: image.url,
|
||||
},
|
||||
footer: {
|
||||
text: `Image ${index}/${images.length}. Rerun to get a different image.`,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(gimg);
|
||||
|
||||
const fimg = new Command("fimg");
|
||||
fimg.category = CATEGORY;
|
||||
fimg.helpText = "Send first result from Google Images";
|
||||
fimg.usage = "[query]";
|
||||
fimg.callback = async function (msg, line) {
|
||||
if (!line) return "No arguments given.";
|
||||
|
||||
const images = await imagesClient.search(line, {
|
||||
safe:
|
||||
msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]")
|
||||
? "off"
|
||||
: "high",
|
||||
});
|
||||
|
||||
const image = images[0];
|
||||
|
||||
return {
|
||||
embeds: [
|
||||
{
|
||||
title: image.description,
|
||||
url: image.parentPage,
|
||||
image: {
|
||||
url: image.url,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(fimg);
|
||||
|
||||
const poll = new Command("poll");
|
||||
poll.category = CATEGORY;
|
||||
poll.helpText = "Start a poll";
|
||||
poll.usage = "[topic] [option 1] [option 2] [...option 3-10]";
|
||||
poll.callback = async function (msg, line, topic, ...options) {
|
||||
if (!line || !topic)
|
||||
return 'Usage: hf!poll "topic" "option 1" "option 2" "...options 3-10"';
|
||||
|
||||
const arrOptions = [...options].slice(0, 10);
|
||||
if (arrOptions.length < 2) return "A minimum of two options are required.";
|
||||
|
||||
const reactions = [];
|
||||
let displayString = `**${msg.author.username}#${msg.author.discriminator}** has started a poll:\n**__${topic}__**\n`;
|
||||
for (let i = 0; i < arrOptions.length; i++) {
|
||||
displayString +=
|
||||
(i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`) +
|
||||
": " +
|
||||
arrOptions[i] +
|
||||
"\n";
|
||||
reactions[i] = i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`;
|
||||
}
|
||||
|
||||
return {
|
||||
content: displayString,
|
||||
addReactions: reactions,
|
||||
};
|
||||
};
|
||||
hf.registerCommand(poll);
|
||||
|
||||
const vote = new Command("vote");
|
||||
vote.category = CATEGORY;
|
||||
vote.helpText = "Start a yes/no vote";
|
||||
vote.usage = "[topic]";
|
||||
vote.callback = async function (msg, line) {
|
||||
if (!line) return "No topic given.";
|
||||
|
||||
return {
|
||||
content: `**${msg.author.username}#${msg.author.discriminator}** has started a vote:\n**__${line}__**\n<:ms_tick:503341995348066313>: Yes\n<:ms_cross:503341994974773250>: No`,
|
||||
addReactions: [
|
||||
":ms_tick:503341995348066313",
|
||||
":ms_cross:503341994974773250",
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(vote);
|
||||
|
||||
const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
const arsched = new Command("arsched");
|
||||
arsched.category = CATEGORY;
|
||||
arsched.helpText = "aNONradio.net schedule";
|
||||
arsched.addAlias("anonradio");
|
||||
arsched.callback = async function (msg, line) {
|
||||
const now = new Date();
|
||||
|
||||
const schedule = await fetch("https://anonradio.net/schedule/").then((res) =>
|
||||
res.text()
|
||||
);
|
||||
|
||||
let lines = schedule.split("\n");
|
||||
lines = lines.slice(4, lines.length - 2);
|
||||
|
||||
const parsedLines = [];
|
||||
|
||||
for (const line of lines) {
|
||||
const [_, time, id, name] = line.match(/^(.{3,4} .{4})\s+(.+?) {2}(.+?)$/);
|
||||
|
||||
const tmp = time.split(" ");
|
||||
const day = tmp[0];
|
||||
let hour = tmp[1];
|
||||
const currentDay = now.getUTCDay();
|
||||
const targetDay = DAYS.indexOf(day);
|
||||
const delta = (targetDay + 7 - currentDay) % 7;
|
||||
|
||||
let currentYear = now.getUTCFullYear();
|
||||
const currentMonth = now.getUTCMonth() + 1;
|
||||
const currentDateDay = now.getUTCDate();
|
||||
let targetMonth = currentMonth;
|
||||
const lastDay = new Date(currentYear, currentMonth, 0).getDate();
|
||||
let targetDateDay = currentDateDay + delta;
|
||||
if (targetDateDay > lastDay) {
|
||||
targetMonth = currentMonth === 12 ? 1 : currentMonth + 1;
|
||||
targetDateDay = 1;
|
||||
if (currentMonth === 12) currentYear++;
|
||||
}
|
||||
|
||||
hour = hour.slice(0, 2) + ":" + hour.slice(-2);
|
||||
|
||||
const timestamp =
|
||||
Date.parse(
|
||||
`${DAYS[targetDay]}, ${currentYear}-${targetMonth}-${targetDateDay} ${hour} UTC`
|
||||
) / 1000;
|
||||
|
||||
parsedLines.push({timestamp, id, name});
|
||||
}
|
||||
|
||||
const liveNow = parsedLines.splice(0, 1)[0];
|
||||
liveNow.name = liveNow.name.replace(" <- Live NOW", "");
|
||||
|
||||
return {
|
||||
embeds: [
|
||||
{
|
||||
title: "Click to listen",
|
||||
url: "http://anonradio.net:8000/anonradio",
|
||||
author: {
|
||||
name: `LIVE NOW: ${liveNow.name} (\`${liveNow.id}\`)`,
|
||||
},
|
||||
fields: parsedLines.map((line) => ({
|
||||
inline: true,
|
||||
name: `${line.name} (\`${line.id}\`)`,
|
||||
value: `<t:${line.timestamp}:R>`,
|
||||
})),
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(arsched);
|
||||
|
||||
const REGEX_IPV4 = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
|
||||
const shodan = new Command("shodan");
|
||||
shodan.category = CATEGORY;
|
||||
shodan.helpText = "Look up an IP on Shodan InternetDB";
|
||||
shodan.callback = async function (msg, line) {
|
||||
if (!line || line == "") return "Arguments required.";
|
||||
if (!REGEX_IPV4.test(line)) return "Invalid IP address.";
|
||||
|
||||
const data = await fetch("https://internetdb.shodan.io/" + line).then((res) =>
|
||||
res.json()
|
||||
);
|
||||
|
||||
if (data.detail) return data.detail;
|
||||
|
||||
return {
|
||||
embed: {
|
||||
title: `Results for \`${data.ip}\``,
|
||||
fields: [
|
||||
{
|
||||
name: "Hostnames",
|
||||
value:
|
||||
data.hostnames.length > 0
|
||||
? data.hostnames.map((str) => `\`${str}\``).join("\n")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Open ports",
|
||||
value: data.ports.length > 0 ? data.ports.join(", ") : "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Tags",
|
||||
value:
|
||||
data.tags.length > 0
|
||||
? data.tags.map((str) => `\`${str}\``).join(", ")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "CPEs",
|
||||
value:
|
||||
data.cpes.length > 0
|
||||
? data.cpes.map((str) => `\`${str}\``).join("\n")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Vulnerabilities",
|
||||
value:
|
||||
data.vulns.length > 0
|
||||
? data.vulns.map((str) => `\`${str}\``).join("\n")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
||||
hf.registerCommand(shodan);
|
||||
|
||||
const GENERATE_HEADERS = {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const generate = new Command("generate");
|
||||
generate.category = CATEGORY;
|
||||
generate.helpText = "Generate images from prompt via craiyon";
|
||||
generate.callback = async function (msg, line) {
|
||||
if (!line || line.length === 0) return "Arguments required.";
|
||||
msg.channel.sendTyping();
|
||||
|
||||
const start = Date.now();
|
||||
let retries = 0;
|
||||
|
||||
let request = await fetch("https://backend.craiyon.com/generate", {
|
||||
method: "POST",
|
||||
headers: GENERATE_HEADERS,
|
||||
body: JSON.stringify({prompt: line}),
|
||||
});
|
||||
while (request.status !== 200) {
|
||||
request = await fetch("https://backend.craiyon.com/generate", {
|
||||
method: "POST",
|
||||
headers: GENERATE_HEADERS,
|
||||
body: JSON.stringify({prompt: line}),
|
||||
});
|
||||
retries++;
|
||||
}
|
||||
|
||||
const data = await request.json();
|
||||
const images = data.images
|
||||
.map((img) => Buffer.from(img, "base64"))
|
||||
.map((img, index) => ({file: img, name: `${index}.jpg`}));
|
||||
|
||||
const title = `Responses for "${safeString(line)}"`;
|
||||
|
||||
const out = {
|
||||
content: `Generated in ${formatTime(Date.now() - start)}${
|
||||
retries > 0 ? " with " + retries + " retries" : ""
|
||||
}`,
|
||||
embeds: [],
|
||||
file: images,
|
||||
};
|
||||
|
||||
let splitIndex = 0;
|
||||
for (const index in images) {
|
||||
if (index % 3 == 0) splitIndex++;
|
||||
out.embeds.push({
|
||||
title,
|
||||
url: "https://www.craiyon.com/?" + splitIndex,
|
||||
image: {
|
||||
url: `attachment://${index}.jpg`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
hf.registerCommand(generate);
|
||||
const Command = require("../lib/command.js");
|
||||
const CATEGORY = "misc";
|
||||
|
||||
const fetch = require("node-fetch");
|
||||
const {
|
||||
hastebin,
|
||||
safeString,
|
||||
parseHtmlEntities,
|
||||
formatTime,
|
||||
} = require("../lib/utils.js");
|
||||
const GoogleImages = require("google-images");
|
||||
|
||||
const imagesClient = new GoogleImages(hf.apikeys.gimg, hf.apikeys.google);
|
||||
|
||||
const yt = new Command("youtube");
|
||||
yt.addAlias("yt");
|
||||
yt.category = CATEGORY;
|
||||
yt.helpText = "Search YouTube";
|
||||
yt.usage = "[search term]";
|
||||
yt.callback = async function (msg, line) {
|
||||
if (!line) return "Arguments are required.";
|
||||
|
||||
const req = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/search?key=${
|
||||
hf.apikeys.google
|
||||
}&maxResults=5&part=snippet&type=video&q=${encodeURIComponent(line)}`
|
||||
).then((x) => x.json());
|
||||
|
||||
const topVid = req.items[0];
|
||||
|
||||
let out = `**${safeString(
|
||||
parseHtmlEntities(topVid.snippet.title)
|
||||
)}** | \`${safeString(
|
||||
parseHtmlEntities(topVid.snippet.channelTitle)
|
||||
)}\`\nhttps://youtu.be/${topVid.id.videoId}\n\n**__See Also:__**\n`;
|
||||
|
||||
for (let i = 1; i < req.items.length; i++) {
|
||||
const vid = req.items[i];
|
||||
out += `- **${safeString(
|
||||
parseHtmlEntities(vid.snippet.title)
|
||||
)}** | By: \`${safeString(
|
||||
parseHtmlEntities(vid.snippet.channelTitle)
|
||||
)}\` | <https://youtu.be/${vid.id.videoId}>\n`;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
hf.registerCommand(yt);
|
||||
|
||||
const fyt = new Command("fyt");
|
||||
fyt.category = CATEGORY;
|
||||
fyt.helpText = "Search YouTube and take the first result.";
|
||||
fyt.usage = "[search term]";
|
||||
fyt.callback = async function (msg, line) {
|
||||
if (!line) return "Arguments are required.";
|
||||
|
||||
const req = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/search?key=${
|
||||
hf.apikeys.google
|
||||
}&maxResults=2&part=snippet&type=video&q=${encodeURIComponent(line)}`
|
||||
).then((x) => x.json());
|
||||
|
||||
const vid = req.items[0];
|
||||
|
||||
return `**${safeString(
|
||||
parseHtmlEntities(vid.snippet.title)
|
||||
)}** | \`${safeString(
|
||||
parseHtmlEntities(vid.snippet.channelTitle)
|
||||
)}\`\nhttps://youtu.be/${vid.id.videoId}`;
|
||||
};
|
||||
hf.registerCommand(fyt);
|
||||
|
||||
const WA_NO_ANSWER = "<:ms_cross:503341994974773250> No answer.";
|
||||
|
||||
const wolfram = new Command("wolfram");
|
||||
wolfram.category = CATEGORY;
|
||||
wolfram.helpText = "Wolfram Alpha";
|
||||
wolfram.usage = "<-v> [query]";
|
||||
wolfram.addAlias("wa");
|
||||
wolfram.callback = async function (msg, line) {
|
||||
let verbose = false;
|
||||
|
||||
if (line.includes("-v")) {
|
||||
line = line.replace("-v", "").trim();
|
||||
verbose = true;
|
||||
}
|
||||
|
||||
const req = await fetch(
|
||||
`http://api.wolframalpha.com/v2/query?input=${encodeURIComponent(
|
||||
line
|
||||
)}&appid=LH2K8H-T3QKETAGT3&output=json`
|
||||
).then((x) => x.json());
|
||||
|
||||
const data = req.queryresult.pods;
|
||||
|
||||
if (!data) return WA_NO_ANSWER;
|
||||
|
||||
// fake no answer
|
||||
if (data[0].subpods[0].plaintext.includes("geoIP")) return WA_NO_ANSWER;
|
||||
|
||||
if (verbose) {
|
||||
const embed = {
|
||||
title: `Result for: \`${safeString(line)}\``,
|
||||
fields: [],
|
||||
footer: {
|
||||
icon_url: "http://www.wolframalpha.com/share.png",
|
||||
text: "Powered by Wolfram Alpha",
|
||||
},
|
||||
image: {
|
||||
url: data[1].subpods[0].img.src,
|
||||
},
|
||||
};
|
||||
|
||||
const extra = data.slice(1, 6);
|
||||
for (const x in extra) {
|
||||
embed.fields.push({
|
||||
name: extra[x].title,
|
||||
value: `[${
|
||||
extra[x].subpods[0].plaintext.length > 0
|
||||
? extra[x].subpods[0].plaintext
|
||||
: "<click for image>"
|
||||
}](${extra[x].subpods[0].img.src})`,
|
||||
inline: true,
|
||||
});
|
||||
}
|
||||
|
||||
return {embed};
|
||||
} else {
|
||||
let image;
|
||||
|
||||
if (data[1].subpods[0].img.src)
|
||||
try {
|
||||
const res = await fetch(data[1].subpods[0].img.src);
|
||||
if (res) {
|
||||
const imgData = await res.arrayBuffer();
|
||||
image = Buffer.from(imgData);
|
||||
}
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
|
||||
let string = "";
|
||||
if (data[1].subpods[0].plaintext.length > 0)
|
||||
string = safeString(data[1].subpods[0].plaintext);
|
||||
|
||||
if (string.length > 2000 - (6 + safeString(line).length))
|
||||
string = "Output too long: " + (await hastebin(string));
|
||||
|
||||
return {
|
||||
content: `\`${safeString(line)}\` -> ${string.length > 0 ? string : ""}`,
|
||||
file: image && {
|
||||
file: image,
|
||||
name: "wolfram_output.gif",
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
hf.registerCommand(wolfram);
|
||||
|
||||
const gimg = new Command("gimg");
|
||||
gimg.category = CATEGORY;
|
||||
gimg.helpText = "Search Google Images";
|
||||
gimg.usage = "[query]";
|
||||
gimg.addAlias("img");
|
||||
gimg.callback = async function (msg, line) {
|
||||
if (!line) return "No arguments given.";
|
||||
|
||||
const images = await imagesClient.search(line, {
|
||||
safe:
|
||||
msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]")
|
||||
? "off"
|
||||
: "high",
|
||||
});
|
||||
|
||||
const index = Math.floor(Math.random() * images.length);
|
||||
const image = images[index];
|
||||
|
||||
return {
|
||||
embeds: [
|
||||
{
|
||||
title: image.description,
|
||||
url: image.parentPage,
|
||||
image: {
|
||||
url: image.url,
|
||||
},
|
||||
footer: {
|
||||
text: `Image ${index}/${images.length}. Rerun to get a different image.`,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(gimg);
|
||||
|
||||
const fimg = new Command("fimg");
|
||||
fimg.category = CATEGORY;
|
||||
fimg.helpText = "Send first result from Google Images";
|
||||
fimg.usage = "[query]";
|
||||
fimg.callback = async function (msg, line) {
|
||||
if (!line) return "No arguments given.";
|
||||
|
||||
const images = await imagesClient.search(line, {
|
||||
safe:
|
||||
msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]")
|
||||
? "off"
|
||||
: "high",
|
||||
});
|
||||
|
||||
const image = images[0];
|
||||
|
||||
return {
|
||||
embeds: [
|
||||
{
|
||||
title: image.description,
|
||||
url: image.parentPage,
|
||||
image: {
|
||||
url: image.url,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(fimg);
|
||||
|
||||
const poll = new Command("poll");
|
||||
poll.category = CATEGORY;
|
||||
poll.helpText = "Start a poll";
|
||||
poll.usage = "[topic] [option 1] [option 2] [...option 3-10]";
|
||||
poll.callback = async function (msg, line, topic, ...options) {
|
||||
if (!line || !topic)
|
||||
return 'Usage: hf!poll "topic" "option 1" "option 2" "...options 3-10"';
|
||||
|
||||
const arrOptions = [...options].slice(0, 10);
|
||||
if (arrOptions.length < 2) return "A minimum of two options are required.";
|
||||
|
||||
const reactions = [];
|
||||
let displayString = `**${msg.author.username}#${msg.author.discriminator}** has started a poll:\n**__${topic}__**\n`;
|
||||
for (let i = 0; i < arrOptions.length; i++) {
|
||||
displayString +=
|
||||
(i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`) +
|
||||
": " +
|
||||
arrOptions[i] +
|
||||
"\n";
|
||||
reactions[i] = i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`;
|
||||
}
|
||||
|
||||
return {
|
||||
content: displayString,
|
||||
addReactions: reactions,
|
||||
};
|
||||
};
|
||||
hf.registerCommand(poll);
|
||||
|
||||
const vote = new Command("vote");
|
||||
vote.category = CATEGORY;
|
||||
vote.helpText = "Start a yes/no vote";
|
||||
vote.usage = "[topic]";
|
||||
vote.callback = async function (msg, line) {
|
||||
if (!line) return "No topic given.";
|
||||
|
||||
return {
|
||||
content: `**${msg.author.username}#${msg.author.discriminator}** has started a vote:\n**__${line}__**\n<:ms_tick:503341995348066313>: Yes\n<:ms_cross:503341994974773250>: No`,
|
||||
addReactions: [
|
||||
":ms_tick:503341995348066313",
|
||||
":ms_cross:503341994974773250",
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(vote);
|
||||
|
||||
const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
const arsched = new Command("arsched");
|
||||
arsched.category = CATEGORY;
|
||||
arsched.helpText = "aNONradio.net schedule";
|
||||
arsched.addAlias("anonradio");
|
||||
arsched.callback = async function (msg, line) {
|
||||
const now = new Date();
|
||||
|
||||
const schedule = await fetch("https://anonradio.net/schedule/").then((res) =>
|
||||
res.text()
|
||||
);
|
||||
|
||||
let lines = schedule.split("\n");
|
||||
lines = lines.slice(4, lines.length - 2);
|
||||
|
||||
const parsedLines = [];
|
||||
|
||||
for (const line of lines) {
|
||||
const [_, time, id, name] = line.match(/^(.{3,4} .{4})\s+(.+?) {2}(.+?)$/);
|
||||
|
||||
const tmp = time.split(" ");
|
||||
const day = tmp[0];
|
||||
let hour = tmp[1];
|
||||
const currentDay = now.getUTCDay();
|
||||
const targetDay = DAYS.indexOf(day);
|
||||
const delta = (targetDay + 7 - currentDay) % 7;
|
||||
|
||||
let currentYear = now.getUTCFullYear();
|
||||
const currentMonth = now.getUTCMonth() + 1;
|
||||
const currentDateDay = now.getUTCDate();
|
||||
let targetMonth = currentMonth;
|
||||
const lastDay = new Date(currentYear, currentMonth, 0).getDate();
|
||||
let targetDateDay = currentDateDay + delta;
|
||||
if (targetDateDay > lastDay) {
|
||||
targetMonth = currentMonth === 12 ? 1 : currentMonth + 1;
|
||||
targetDateDay = 1;
|
||||
if (currentMonth === 12) currentYear++;
|
||||
}
|
||||
|
||||
hour = hour.slice(0, 2) + ":" + hour.slice(-2);
|
||||
|
||||
const timestamp =
|
||||
Date.parse(
|
||||
`${DAYS[targetDay]}, ${currentYear}-${targetMonth}-${targetDateDay} ${hour} UTC`
|
||||
) / 1000;
|
||||
|
||||
parsedLines.push({timestamp, id, name});
|
||||
}
|
||||
|
||||
const liveNow = parsedLines.splice(0, 1)[0];
|
||||
liveNow.name = liveNow.name.replace(" <- Live NOW", "");
|
||||
|
||||
return {
|
||||
embeds: [
|
||||
{
|
||||
title: "Click to listen",
|
||||
url: "http://anonradio.net:8000/anonradio",
|
||||
author: {
|
||||
name: `LIVE NOW: ${liveNow.name} (\`${liveNow.id}\`)`,
|
||||
},
|
||||
fields: parsedLines.map((line) => ({
|
||||
inline: true,
|
||||
name: `${line.name} (\`${line.id}\`)`,
|
||||
value: `<t:${line.timestamp}:R>`,
|
||||
})),
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
hf.registerCommand(arsched);
|
||||
|
||||
const REGEX_IPV4 = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
|
||||
const shodan = new Command("shodan");
|
||||
shodan.category = CATEGORY;
|
||||
shodan.helpText = "Look up an IP on Shodan InternetDB";
|
||||
shodan.callback = async function (msg, line) {
|
||||
if (!line || line == "") return "Arguments required.";
|
||||
if (!REGEX_IPV4.test(line)) return "Invalid IP address.";
|
||||
|
||||
const data = await fetch("https://internetdb.shodan.io/" + line).then((res) =>
|
||||
res.json()
|
||||
);
|
||||
|
||||
if (data.detail) return data.detail;
|
||||
|
||||
return {
|
||||
embed: {
|
||||
title: `Results for \`${data.ip}\``,
|
||||
fields: [
|
||||
{
|
||||
name: "Hostnames",
|
||||
value:
|
||||
data.hostnames.length > 0
|
||||
? data.hostnames.map((str) => `\`${str}\``).join("\n")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Open ports",
|
||||
value: data.ports.length > 0 ? data.ports.join(", ") : "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Tags",
|
||||
value:
|
||||
data.tags.length > 0
|
||||
? data.tags.map((str) => `\`${str}\``).join(", ")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "CPEs",
|
||||
value:
|
||||
data.cpes.length > 0
|
||||
? data.cpes.map((str) => `\`${str}\``).join("\n")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: "Vulnerabilities",
|
||||
value:
|
||||
data.vulns.length > 0
|
||||
? data.vulns.map((str) => `\`${str}\``).join("\n")
|
||||
: "None",
|
||||
inline: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
||||
hf.registerCommand(shodan);
|
||||
|
||||
const GENERATE_HEADERS = {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const generate = new Command("generate");
|
||||
generate.category = CATEGORY;
|
||||
generate.helpText = "Generate images from prompt via craiyon";
|
||||
generate.callback = async function (msg, line) {
|
||||
if (!line || line.length === 0) return "Arguments required.";
|
||||
msg.channel.sendTyping();
|
||||
|
||||
const start = Date.now();
|
||||
let retries = 0;
|
||||
|
||||
let request = await fetch("https://backend.craiyon.com/generate", {
|
||||
method: "POST",
|
||||
headers: GENERATE_HEADERS,
|
||||
body: JSON.stringify({prompt: line}),
|
||||
});
|
||||
while (request.status !== 200) {
|
||||
request = await fetch("https://backend.craiyon.com/generate", {
|
||||
method: "POST",
|
||||
headers: GENERATE_HEADERS,
|
||||
body: JSON.stringify({prompt: line}),
|
||||
});
|
||||
retries++;
|
||||
}
|
||||
|
||||
const data = await request.json();
|
||||
const images = data.images
|
||||
.map((img) => Buffer.from(img, "base64"))
|
||||
.map((img, index) => ({file: img, name: `${index}.jpg`}));
|
||||
|
||||
const title = `Responses for "${safeString(line)}"`;
|
||||
|
||||
const out = {
|
||||
content: `Generated in ${formatTime(Date.now() - start)}${
|
||||
retries > 0 ? " with " + retries + " retries" : ""
|
||||
}`,
|
||||
embeds: [],
|
||||
file: images,
|
||||
};
|
||||
|
||||
let splitIndex = 0;
|
||||
for (const index in images) {
|
||||
if (index % 3 == 0) splitIndex++;
|
||||
out.embeds.push({
|
||||
title,
|
||||
url: "https://www.craiyon.com/?" + splitIndex,
|
||||
image: {
|
||||
url: `attachment://${index}.jpg`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
hf.registerCommand(generate);
|
||||
|
|
Loading…
Reference in a new issue