Last active
March 5, 2020 21:14
-
-
Save consoleSkunk/307940eb97648b0794eafd66d09b558a to your computer and use it in GitHub Desktop.
Legacy e621 random search command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"prefix": "/", | |
"whitelist": { | |
"guilds": [ | |
"<guild ID>" | |
], | |
"categories": [ | |
"<category ID>" | |
], | |
"channels": [ | |
"<channel ID>" | |
], | |
"fetish": [ | |
"<channel ID>", | |
"<channel ID>", | |
"<channel ID>" | |
], | |
"chan_names": [ | |
"<channel name>", | |
"<channel name>" | |
] | |
}, | |
"blacklist": { | |
"users": [ | |
"<user id>" | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var clearModule = require('clear-module'); | |
clearModule("../config/filter.json"); // remove old filter from cache | |
var qs = require("querystring"), | |
Discord = require("discord.js"), | |
request = require("request"), | |
prettysize = require('prettysize'), | |
whitelist = require("../config/config.json").whitelist, | |
filter = require("../config/filter.json"), | |
name = require('../package.json').name, | |
version = require('../package.json').version; | |
// as per the API documentation, it's recommended to include your e621 username | |
var userAgent = `${name}/${version} (by <username> on e621)`; | |
exports.module = { | |
commands: ["e621","e6","e926","e9","e"], | |
description: "Returns a random image from [e621](https://e621.net/) or [e926](https://e926.net/), depending on the channel.\n[Cheatsheet available here](https://e621.net/help/show/cheatsheet).", | |
syntax: "tag_1 tag_2 tag_3", | |
tags: [], | |
process: function(client, msg, params) { | |
if(params.includes(",")) { | |
params = | |
params | |
.split(",") | |
.map(s => s.trim().replace(/ /g,"_")) | |
.join(" "); | |
} | |
var paramsLC = params.toLowerCase(); | |
var sfwMode = !msg.channel.nsfw; | |
var domain = `e${sfwMode ? "926" : "621"}`; | |
if(params.includes("*")) { | |
msg.reply(`Wildcards cannot be used.`); | |
return; | |
} | |
if( | |
(sfwMode && filter.nsfw.some(r=> paramsLC.replace(/\~/g,"").split(" ").includes(r))) || | |
(!sfwMode && filter.sfw_only.some(r=> paramsLC.replace(/\~/g,"").split(" ").includes(r))) || | |
(whitelist.fetish.indexOf(msg.channel.id) == -1 && filter.fetish.some(r=> paramsLC.replace(/\~/g,"").split(" ").includes(r))) || | |
(filter.blacklist.some(r=> paramsLC.replace(/\~/g,"").split(" ").includes(r))) || | |
(filter.guilds[msg.guild.id] && filter.guilds[msg.guild.id].some(r=> paramsLC.replace(/\~/g,"").split(" ").includes(r))) | |
){ | |
msg.reply("Your search contains tags that are blacklisted in this channel."); | |
return; | |
} | |
if((sfwMode && paramsLC.indexOf("order:") === -1 && params.split(" ").length > 4) | |
|| ((sfwMode && paramsLC.indexOf("order:") != -1 || !sfwMode && params.indexOf("order:") === -1) && params.split(" ").length > 5) | |
|| (!sfwMode && paramsLC.indexOf("order:") != -1 && params.split(" ").length > 6)) { | |
msg.reply(undefined,{embed: { | |
author: { | |
name: `${domain}`, | |
icon_url: "https://e926.net/apple-touch-icon.png" | |
}, | |
description: `Error: You can only search up to ${ | |
sfwMode && paramsLC.indexOf("order:") === -1 && params.split(" ").length > 4 ? "4" : | |
(sfwMode && paramsLC.indexOf("order:") != -1 || | |
!sfwMode && paramsLC.indexOf("order:") === -1) && params.split(" ").length > 5 ? "5" : | |
"6" | |
} tags at once`, | |
color: 8529960, | |
footer: { | |
} | |
}}) | |
return; | |
} | |
else { | |
var searchURL; | |
var singleImage; | |
var md5Reg = /^(?:md5:)?([0-9a-f]{32})$/i; | |
var idReg = /^(?:id:|#)(\d+)$/i; | |
if(md5Reg.test(params)) { // md5 | |
searchURL = `https://${domain}.net/post/show.json?md5=${qs.escape(md5Reg.exec(params)[1])}`; | |
singleImage = true; | |
} else if(idReg.test(params)) { // post ID | |
searchURL = `https://${domain}.net/post/show.json?id=${qs.escape(idReg.exec(params)[1])}`; | |
singleImage = true; | |
} else { // regular search | |
searchURL = `https://${domain}.net/post/index.json?limit=${ | |
paramsLC.indexOf("order:") != -1 ? "75" : "10" | |
}&tags=${paramsLC.indexOf("order:") != -1 ? "" : "order:random+"}${qs.escape(params)}`; | |
singleImage = false; | |
}; | |
msg.channel.startTyping(); | |
var search = request({ | |
url: searchURL, | |
headers: { | |
'User-Agent': userAgent | |
} | |
}, | |
function (error, response, body) { | |
if(error !== null) { | |
if(!msg.channel.permissionsFor(client.user).has("EMBED_LINKS")) { | |
msg.reply(`An error has occured. Please try again later..\n\n\`\`\`js\n${error}\`\`\`\nURL: ${searchURL}`); | |
} else { | |
msg.reply(undefined,{embed: { | |
title: domain, | |
description: `Sorry, an error has occured. Please try again later.`, | |
color: 8529960, | |
fields: [ | |
{ | |
name: "Error Message", | |
value: "```js\n" + error + "```", | |
inline: false | |
}, | |
{ | |
name: "URL", | |
value: searchURL, | |
inline: false | |
} | |
], | |
footer: { | |
icon_url: "https://e926.net/apple-touch-icon.png", | |
text: domain | |
} | |
}}); | |
} | |
} else if(body.indexOf("<title>e621 Maintenance</title>") != -1) { // a crude way to support the maintenance page | |
if(!msg.channel.permissionsFor(client.user).has("EMBED_LINKS")) { | |
msg.reply("e621 is currently performing server maintenance. Please try again later.\nYou may want to check https://twitter.com/e621dotnet for more information."); | |
} else { | |
msg.reply(undefined,{embed: { | |
title: `${domain} - Maintenance`, | |
description: "e621 is currently performing server maintenance. Please try again later.\nYou may want to check [@e621dotnet](https://twitter.com/e621dotnet) for more information.", | |
color: 8529960, | |
footer: { | |
icon_url: "https://e926.net/apple-touch-icon.png", | |
text: domain | |
} | |
}}); | |
} | |
} else if ((!error && response.statusCode == 200) || response.statusCode == 404) { | |
try { | |
var json = JSON.parse(body); | |
var isFiltered = function(post){ | |
return (sfwMode && filter.nsfw.some(r=> post.tags.split(" ").includes(r))) || | |
(post.rating !== "s" && filter.sfw_only.some(r=> post.tags.split(" ").includes(r))) || | |
(whitelist.fetish.indexOf(msg.channel.id) == -1 && filter.fetish.some(r=> post.tags.split(" ").includes(r))) || | |
(filter.blacklist.some(r=> post.tags.split(" ").includes(r))) || | |
(filter.guilds[msg.guild.id] && filter.guilds[msg.guild.id].some(r=> post.tags.split(" ").includes(r))) | |
} | |
if(typeof (json) !== "undefined") { | |
var trueCount = Object.keys(json).length; | |
json = singleImage ? json : json.filter(function(element){ return !isFiltered(element) }); | |
} | |
if (typeof (json) !== "undefined" && Object.keys(json).length > 0) { | |
var post = | |
singleImage ? json : json[Math.floor(Math.random() * json.length)]; | |
var srcUrls = (post.sources ? post.sources : []).filter(function(srcValue){ | |
if(srcValue) { | |
return urlRegex = /^https?:\/\/(?:[-0-9A-Za-z]+\.)+[-0-9A-Za-z]+\/.*/.test(srcValue); | |
} | |
}); | |
// Blacklisted image | |
let blacklistedTags = []; | |
if(isFiltered(post)) { | |
let tags = post.tags.split(" "); | |
if(sfwMode && filter.nsfw.some(r=> tags.includes(r))) { | |
filter.nsfw.map((first) => { | |
blacklistedTags[tags.findIndex(def => def === first)] = first; | |
}); | |
} | |
if(post.rating !== "s" && filter.sfw_only.some(r=> tags.includes(r))) { | |
filter.sfw_only.map((first) => { | |
blacklistedTags[tags.findIndex(def => def === first)] = first; | |
}); | |
} | |
if(whitelist.fetish.indexOf(msg.channel.id) == -1 && filter.fetish.some(r=> tags.includes(r))) { | |
filter.fetish.map((first) => { | |
blacklistedTags[tags.findIndex(def => def === first)] = first; | |
}); | |
} | |
if(filter.blacklist.some(r=> tags.includes(r))) { | |
filter.blacklist.map((first) => { | |
blacklistedTags[tags.findIndex(def => def === first)] = first; | |
}); | |
} | |
if(filter.guilds[msg.guild.id] && filter.guilds[msg.guild.id].some(r=> tags.includes(r))) { | |
filter.guilds[msg.guild.id].map((first) => { | |
blacklistedTags[tags.findIndex(def => def === first)] = first; | |
}); | |
} | |
blacklistedTags = blacklistedTags.filter(v => v); | |
} | |
var rating = ( | |
post.rating == "s" ? "Safe" : | |
post.rating == "e" ? "Explicit" : | |
post.rating == "q" ? "Questionable" : | |
"Unknown"); | |
if(sfwMode && post.rating !== "s" && post.status !== "deleted") { | |
msg.reply(`Sorry, the post you requested is not appropriate for this channel. (${rating})`); | |
} | |
else if(!msg.channel.permissionsFor(client.user).has("EMBED_LINKS")) { | |
if(isFiltered(post)) { | |
msg.reply( | |
`Image #${post.id} (${rating}) has th${blacklistedTags.length > 1 ? 'ese' : 'is'} blacklisted tag${blacklistedTags.length > 1 ? 's' : ''}:` + | |
`${blacklistedTags.length > 3 ? '\n' : ' '}${blacklistedTags.join(", ").replace(/_/g, " ")}` | |
); | |
} else { | |
msg.reply(`https://${domain}.net/post/show/${post.id} (${rating})`); | |
} | |
} else { | |
var description = DText(post.description).replace(/\]\(https\:\/\/e926.net\//g,`](https://${domain}.net/`); | |
var postEmbed = new Discord.MessageEmbed({ | |
author: { | |
name: (post.artist.length ? post.artist.join(", ").replace(/_\(artist\)/g,"").replace(/_/g, " ") : (srcUrls ? srcUrls[0] : null)), | |
url: (srcUrls ? srcUrls[0] : null), | |
}, | |
title: | |
`${domain} - #${post.id} (${rating})`, | |
url: `https://${domain}.net/post/show/${post.id}`, | |
description: (description.length > 280 ? description.substr(0,279) + "…" : description), | |
color: 77398, | |
image: { | |
url: ( | |
post.status == "deleted" ? "https://static1.e926.net/images/deleted-preview.png" : | |
post.file_ext == "swf" ? "https://static1.e926.net/images/download-preview.png" : | |
post.file_ext == "webm" ? post.sample_url : | |
post.file_size > "52428800" ? post.sample_url : | |
post.file_url | |
) | |
}, | |
footer: { | |
text: `Uploaded by ${post.author} | ${(post.score > 0 ? "↑" : (post.score < 0 ? "↓" : "↕")) + Math.abs(post.score)} ♥${post.fav_count}${post.has_comments ? ' 💬' : ''} | ${prettysize(post.file_size)}`, | |
icon_url: 'https://e926.net/apple-touch-icon.png' | |
}, | |
timestamp: new Date(post.created_at.s*1000).toISOString() | |
}); | |
// Deleted post | |
if(post.status == "deleted") { | |
postEmbed.addField( | |
`Reason for deletion`, | |
DText(post.delreason).replace(/\]\(https\:\/\/e926.net\//g,`](https://${domain}.net/`), | |
false | |
); | |
} | |
if(isFiltered(post)) { | |
// prevent blacklisted posts from being linked to | |
// this is only done if you access a post directly | |
postEmbed.setThumbnail("https://static1.e926.net/images/blacklisted-preview.png"); | |
if(postEmbed.image) { | |
delete postEmbed.image; | |
} | |
if(postEmbed.url) { | |
delete postEmbed.url; | |
} | |
if(postEmbed.author.url) { | |
delete postEmbed.author.url; | |
} | |
postEmbed.addField( | |
`Blacklisted tag${blacklistedTags.length > 1 ? 's' : ''}`, | |
blacklistedTags.join(", ").replace(/_/g, " "), | |
false | |
); | |
} | |
// Deleted or SWF/WebM | |
if(post.status == "deleted" || post.file_ext == "swf" || post.file_ext == "webm") { | |
postEmbed.setThumbnail( | |
post.status == "deleted" ? "https://static1.e926.net/images/deleted-preview.png" : | |
post.file_ext == "swf" ? "https://static1.e926.net/images/download-preview.png" : | |
post.file_ext == "webm" ? "https://static1.e926.net/images/webm-preview.png" : | |
postEmbed.thumbnail | |
); | |
if(postEmbed.image && post.file_ext !== "webm") { | |
delete postEmbed.image; | |
} | |
} | |
if(post.parent_id != null) { | |
postEmbed.addField( | |
`Parent`, | |
(isFiltered(post) ? `#${post.parent_id}` : `[#${post.parent_id}](https://${domain}.net/post/show/${post.parent_id})`), | |
true | |
); | |
} | |
if(post.has_children) { | |
var children = post.children.split(","); | |
for ( var i = 0; i < children.length; i++ ) { | |
children[i] = (isFiltered(post) ? `#${children[i]}` : `[#${children[i]}](https://${domain}.net/post/show/${children[i]})`); | |
} | |
postEmbed.addField( | |
`Child${children.length > 1 ? 'ren' : ''}`, | |
children.join(", "), | |
true | |
); | |
} | |
msg.reply(undefined, {embed: postEmbed}); | |
} | |
} | |
else { | |
var response = singleImage ? "The post you requested does not exist." : trueCount > 0 ? "Your search returned only filtered images." : "No posts matched your search."; | |
if(!msg.channel.permissionsFor(client.user).has("EMBED_LINKS")) { | |
msg.reply(response); | |
} | |
else { | |
msg.reply(undefined,{embed: { | |
title: | |
`${domain}`, | |
url: searchURL.replace(/\.json|limit=1&|order:random\+/gi,""), | |
description: response, | |
color: 8529960, | |
footer: { | |
icon_url: "https://e926.net/apple-touch-icon.png", | |
text: domain | |
} | |
}}); | |
} | |
} | |
} catch (e) { | |
console.error("[e621 Error]", e); | |
if(!msg.channel.permissionsFor(client.user).has("EMBED_LINKS")) { | |
msg.reply(`Sorry, an error occured while an error occured while getting your image. Please try again later.\n\n\`\`\`js\n${e}\`\`\`\nURL: ${response.request.uri.href}`); | |
} else { | |
msg.reply(undefined,{embed: { | |
title: domain, | |
description: `Sorry, an error occured while an error occured while getting your image. Please try again later.`, | |
color: 8529960, | |
fields: [ | |
{ | |
name: "Error Message", | |
value: "```js\n" + e + "```", | |
inline: false | |
}, | |
{ | |
name: "URL", | |
value: response.request.uri.href, | |
inline: false | |
} | |
], | |
footer: { | |
icon_url: "https://e926.net/apple-touch-icon.png", | |
text: domain | |
} | |
}}); | |
} | |
} | |
} | |
else { | |
var errJSON = {}; | |
try { | |
errJSON = JSON.parse(body); | |
} catch (e) { | |
errJSON = {}; | |
} | |
if(!msg.channel.permissionsFor(client.user).has("EMBED_LINKS")) { | |
msg.reply(errJSON.message ? errJSON.message : `A server error occured. Please try again later. (${response.statusCode} ${response.statusMessage})\nYou may want to check https://twitter.com/e621dotnet for more information.`); | |
} else { | |
msg.reply(undefined,{embed: { | |
title: `${response.statusCode} ${response.statusMessage}`, | |
description: errJSON.message ? errJSON.message : `A server error occured. Please try again later.\nYou may want to check [@e621dotnet](https://twitter.com/e621dotnet) for more information.`, | |
color: 8529960, | |
footer: { | |
icon_url: "https://e926.net/apple-touch-icon.png", | |
text: domain | |
} | |
}}); | |
} | |
} | |
}); | |
msg.channel.stopTyping(); | |
} | |
} | |
}; | |
// DText parser | |
var DTextMap = new Map([ | |
//escapes | |
[/(\r\n|\r|\n\r)/g,'\n'], | |
// bullets, put before bbcode to avoid conflict with bold | |
[/^\* ([\s\S]+?)$/gim,'• $1'], | |
[/^\*{2} ([\s\S]+?)$/gim,' ◦ $1'], | |
[/^\*{3,} ([\s\S]+?)$/gim,' ▪ $1'], | |
//BBCode | |
[/\[b\]([\s\S]+?)\[\/b\]/gi,'**$1**'], | |
[/\[i\]([\s\S]+?)\[\/i\]/gi,'*$1*'], | |
[/\[u\]([\s\S]+?)\[\/u\]/gi,'__$1__'], | |
[/\[s\]([\s\S]+?)\[\/s\]/gi,'~~$1~~'], | |
[/\[code\]([\s\S]+?)\[\/code\]/gi,'```$1```'], | |
[/\[spoiler\]([\s\S]+?)\[\/spoiler\]/gi,'||$1||'], | |
[/\[section(?:,expanded)?\]([\s\S]+?)\[\/section\]/gi,'**Section:**\n$1'], | |
[/\[section(?:,expanded)?=([^\]]+?)\]([\s\S]+?)\[\/section\]/gi,'**$1:**\n$2'], | |
//disabled since there's no Discord equivalent | |
[/\[o\]([\s\S]+?)\[\/o\]/gi,'$1'], | |
[/\[sup\]([\s\S]+?)\[\/sup\]/gi,'$1'], | |
[/\[sub\]([\s\S]+?)\[\/sub\]/gi,'$1'], | |
[/\[color=([\s\S]+?)\]([\s\S]+?)\[\/color\]/gi,'$2'], | |
[/\[quote\]([\s\S]+?)\[\/quote\]/gi,'$1'], // may need a special case for this (i.e. prepending `> ` before every line) | |
//enclosing stuff | |
//[/`([\s\S]+?)`/gi, "<span style=\"background:#64ffffff;\">$1</span>] //discord already handles inline code | |
[/\"([^"]+?)\":\/([^\s]+)/g, '[$1](https://e926.net/$2)'], //local links, that stay on the page | |
[/\"([^"]+?)\":([^\s]+)/g,'[$1]($2)'], | |
[/\[\[(.+?)\|([\s\S]+?)\]\]/g,'[$2](https://e926.net/wiki/show?title=$1)'], | |
[/\[\[(.+?)\]\]/g,'[$1](https://e926.net/wiki/show?title=$1)'], | |
[/\{\{(.+?)\|([\s\S]+?)\}\}/g,'[$2](https://e926.net/post/index?tags=$1)'], | |
[/\{\{(.+?)\}\}/g,'[$1](https://e926.net/post/index?tags=$1)'], | |
[ | |
/(post|forum|comment|blip|pool|set|takedown|ticket) #([0-9]+)/gi, | |
'[$1 #$2](https://e926.net/$1/show/$2)' | |
], | |
[/thumb #([0-9]+)/gi, '[thumb #$1](https://e926.net/post/show/$1)'], | |
[/record #([0-9]+)/gi, '[record #$1](https://e926.net/user_record/show/$1)'], | |
[/category #([0-9]+)/gi, '[category #$1](https://e926.net/forum?category=$1)'], | |
//[/\]\(http[\S]+?([\s])[\S]+?\)$/gi,'%20'], //replace spaces in URLS with %20 | |
[/^h[1-6]\.(\*\*[\s\S]+?\*\*)$/gim,'$1'], // do not double bold | |
[/^h[1-6]\.([\s\S]+?)$/gim,'**$1**'], | |
]); | |
var DText = function(text) { | |
DTextMap.forEach((value, key) => { | |
text = text.replace(key, value); | |
}); | |
return text; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nsfw": [ | |
"tag1", "tag2", "tagN" | |
], | |
"sfw_only": [ | |
"tag1", "tag2", "tagN" | |
], | |
"fetish": [ | |
"tag1", "tag2", "tagN" | |
], | |
"blacklist": [ | |
"tag1", "tag2", "tagN" | |
], | |
"guilds": { | |
"<guild ID>": ["tag1", "tag2", "tagN"], | |
"<guild ID>": ["tag1", "tag2", "tagN"] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment