This commit is contained in:
Tyler Murphy 2022-08-23 00:55:22 -04:00
parent 30aa1d0613
commit 0fa1a8f455
11 changed files with 300 additions and 32 deletions

View file

@ -9,12 +9,13 @@ import java.nio.charset.StandardCharsets;
public class JsonRequest extends Request { public class JsonRequest extends Request {
public Object request() { public String request() {
super.addHeaders("Content-type","application/json"); super.addHeaders("Content-type","application/json");
HttpURLConnection connection = super.getConnection(); HttpURLConnection connection = super.getConnection();
try { try {
return parseJson(connection.getInputStream()); return parseJson(connection.getInputStream());
} catch (Exception ignored) {} finally { } catch (IOException ignored){
} finally {
if (connection != null) { if (connection != null) {
connection.disconnect(); connection.disconnect();
} }
@ -22,7 +23,7 @@ public class JsonRequest extends Request {
return null; return null;
} }
public static JSONObject parseJson(InputStream is) throws JSONException { public static String parseJson(InputStream is) throws JSONException {
char[] buffer = new char[1024 * 4]; char[] buffer = new char[1024 * 4];
int n; int n;
try (BufferedInputStream stream = new BufferedInputStream(is); InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) { try (BufferedInputStream stream = new BufferedInputStream(is); InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
@ -30,9 +31,9 @@ public class JsonRequest extends Request {
while (-1 != (n = reader.read(buffer))) { while (-1 != (n = reader.read(buffer))) {
writer.write(buffer, 0, n); writer.write(buffer, 0, n);
} }
return new JSONObject(writer.toString()); return writer.toString();
} catch (IOException ignored) {} } catch (IOException ignored) {}
return new JSONObject(""); return "{}";
} }
} }

View file

@ -1,5 +1,6 @@
package net.tylermurphy.ken.api; package net.tylermurphy.ken.api;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
@ -61,13 +62,17 @@ public abstract class Request {
byte[] input = body.getBytes("utf-8"); byte[] input = body.getBytes("utf-8");
os.write(input, 0, input.length); os.write(input, 0, input.length);
} catch (Exception e) { } catch (Exception e) {
throw new Exception("Error writing body to HTTP connection.\n"+e.getMessage()); throw new RuntimeException("Error writing body to HTTP connection.\n"+e.getMessage());
} }
} }
if(connection.getResponseCode() > 299){
throw new RuntimeException(connection.getResponseCode() + " " + connection.getResponseMessage());
}
return connection; return connection;
} catch (Exception e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;

View file

@ -13,12 +13,13 @@ import java.net.HttpURLConnection;
public class XmlRequest extends Request { public class XmlRequest extends Request {
public Document request() { public Document request() throws RuntimeException {
super.addHeaders("Content-type","text/xml"); super.addHeaders("Content-type","text/xml");
HttpURLConnection connection = super.getConnection(); HttpURLConnection connection = super.getConnection();
try { try {
return parseXML(connection.getInputStream()); return parseXML(connection.getInputStream());
} catch (Exception ignored) {} finally { } catch (IOException | ParserConfigurationException | SAXException ignored) {
} finally {
if (connection != null) { if (connection != null) {
connection.disconnect(); connection.disconnect();
} }

View file

@ -175,9 +175,8 @@ public class Responder extends ListenerAdapter {
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.setColor(Color.RED) .setColor(Color.RED)
.setTitle(":x: **Error**") .setTitle(":x: **Error**")
.setDescription(e.getMessage()); .setDescription(e.getCause().getMessage());
event.getHook().sendMessageEmbeds(builder.build()).queue(); event.getHook().sendMessageEmbeds(builder.build()).queue();
e.printStackTrace();
} }
} }
@ -236,8 +235,11 @@ public class Responder extends ListenerAdapter {
} }
} }
} catch (Exception e) { } catch (Exception e) {
event.getHook().sendMessage(e.getMessage()).queue(); EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
e.printStackTrace(); .setColor(Color.RED)
.setTitle(":x: **Error**")
.setDescription(e.getCause().getMessage());
event.getHook().editOriginalEmbeds(builder.build()).queue();
} }
} }

View file

@ -80,9 +80,12 @@ public class Help {
Ken.getInstance().getDefaultEmbed() Ken.getInstance().getDefaultEmbed()
.setAuthor(name + " Command List", sender.getUser().getAvatarUrl()) .setAuthor(name + " Command List", sender.getUser().getAvatarUrl())
.setTitle(":underage: **NSFW Commands**") .setTitle(":underage: **NSFW Commands**")
.appendDescription("**/rule34 <query>** Search on rule34\n") .appendDescription("**/hentai <query>** Retrieves a random hentai image\n")
.appendDescription("**/e612 <query>** Search on e621\n") .appendDescription("**/rule34 <query> <page>** Searches on rule34\n")
.appendDescription("**/akaneko <query>** Search on akaneko\n") .appendDescription("**/gelbooru <query> <page>** Searches on gelbooru\n")
.appendDescription("**/danbooru <query> <page>** Searches on danbooru\n")
.appendDescription("**/e621 <query> <page>** Searches on e621\n")
.appendDescription("**/nhentai <query>** Searches on nhentai\n")
.setFooter("Page "+page+"/"+PAGES) .setFooter("Page "+page+"/"+PAGES)
}; };
return embeds[page-1].build(); return embeds[page-1].build();

View file

@ -0,0 +1,57 @@
package net.tylermurphy.ken.command.nsfw;
import net.dv8tion.jda.api.entities.GuildMessageChannel;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.JsonRequest;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.util.Command;
import net.tylermurphy.ken.util.Option;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
public class Danbooru {
@Command(name="danbooru",description="Searches for an image off of danbooru")
@Option(name="query",description="Search query for danbooru",type= OptionType.STRING,required=true)
@Option(name="page",description="Page number for danbooru",type= OptionType.INTEGER)
public Response execute(GuildMessageChannel channel, List<Object> args){
if(!(channel instanceof TextChannel)) {
return Response.error("This command can only be used in a text channel");
}
TextChannel textChannel = (TextChannel) channel;
if(!textChannel.isNSFW()){
return Response.error("This command can only be used in an NSFW channel");
}
int page = args.size() > 1 ? (int)args.get(1) : 1;
String url = request((String)args.get(0), page);
if(url == null){
return Response.error("Unable to find post with search: "+args.get(0));
} else {
if(url.endsWith(".mp4") || url.endsWith(".webm"))
return Response.success(url);
return Response.success(Ken.getInstance().getDefaultEmbed().setImage(url).build());
}
}
private String request(String query, int page){
String response = (String) new JsonRequest()
.setURL("https://danbooru.donmai.us/posts.json?limit=100?tags="+query+"?page="+page)
.setType(HTTPMethod.GET)
.request();
try {
JSONArray results = new JSONArray(response);
int choice = (int) (Math.random()*results.length()-1);
JSONObject post = (JSONObject) results.get(choice);
return post.getString("file_url");
} catch (JSONException e) {
return null;
}
}
}

View file

@ -17,9 +17,10 @@ import java.util.List;
public class E621 { public class E621 {
@Command(name="e621",description=":underage: Searches for an image off of e621") @Command(name="e621",description="Searches for an image off of e621")
@Option(name="query",description="Search query for rule34",type= OptionType.STRING,required=true) @Option(name="query",description="Search query for e621",type= OptionType.STRING,required=true)
public Response execute(GuildMessageChannel channel, List<String> args){ @Option(name="page",description="Page number for e621",type= OptionType.INTEGER)
public Response execute(GuildMessageChannel channel, List<Object> args){
if(!(channel instanceof TextChannel)) { if(!(channel instanceof TextChannel)) {
return Response.error("This command can only be used in a text channel"); return Response.error("This command can only be used in a text channel");
} }
@ -27,7 +28,8 @@ public class E621 {
if(!textChannel.isNSFW()){ if(!textChannel.isNSFW()){
return Response.error("This command can only be used in an NSFW channel"); return Response.error("This command can only be used in an NSFW channel");
} }
String url = request(args.get(0)); int page = args.size() > 1 ? (int)args.get(1) : 1;
String url = request((String)args.get(0), page);
if(url == null){ if(url == null){
return Response.error("Unable to find post with search: "+args.get(0)); return Response.error("Unable to find post with search: "+args.get(0));
} else { } else {
@ -37,13 +39,13 @@ public class E621 {
} }
} }
private String request(String query){ private String request(String query, int page){
JSONObject json = (JSONObject) new JsonRequest() String response = (String) new JsonRequest()
.setURL("https://e621.net/posts.json?tags="+query) .setURL("https://e621.net/posts.json?limit=100?tags="+query+"?page="+page)
.setType(HTTPMethod.GET) .setType(HTTPMethod.GET)
.request(); .request();
try { try {
JSONArray results = json.getJSONArray("posts"); JSONArray results = new JSONObject(response).getJSONArray("posts");
int choice = (int) (Math.random()*results.length()-1); int choice = (int) (Math.random()*results.length()-1);
JSONObject post = (JSONObject) results.get(choice); JSONObject post = (JSONObject) results.get(choice);
JSONObject file = post.getJSONObject("file"); JSONObject file = post.getJSONObject("file");

View file

@ -0,0 +1,63 @@
package net.tylermurphy.ken.command.nsfw;
import net.dv8tion.jda.api.entities.GuildMessageChannel;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.XmlRequest;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.util.Command;
import net.tylermurphy.ken.util.Option;
import org.json.JSONException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.List;
public class Gelbooru {
@Command(name="gelbooru",description="Searches for an image off of gelbooru")
@Option(name="query",description="Search query for gelbooru",type=OptionType.STRING,required=true)
@Option(name="page",description="Page number for gelbooru",type= OptionType.INTEGER)
public Response execute(GuildMessageChannel channel, List<Object> args){
if(!(channel instanceof TextChannel)) {
return Response.error("This command can only be used in a text channel");
}
TextChannel textChannel = (TextChannel) channel;
if(!textChannel.isNSFW()){
return Response.error("This command can only be used in an NSFW channel");
}
int page = args.size() > 1 ? (int)args.get(1) : 1;
String url = request((String)args.get(0), page);
System.out.println(url);
if(url == null){
return Response.error("Unable to find post with search: "+args.get(0));
} else {
if(url.endsWith(".mp4") || url.endsWith(".webm"))
return Response.success(url);
return Response.success(Ken.getInstance().getDefaultEmbed().setImage(url).build());
}
}
private String request(String query, int page) {
Document doc = (Document) new XmlRequest()
.setURL("https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=100&tags="+query+"&pid="+page)
.setType(HTTPMethod.GET)
.request();
try {
NodeList nList = doc.getElementsByTagName("post");
int choice = (int) (Math.random() * nList.getLength() - 1);
if (choice < 0) return null;
Node node = nList.item(choice);
Element element = (Element) node;
Node file = element.getElementsByTagName("file_url").item(0);
return file.getTextContent();
} catch (JSONException e) {
return null;
}
}
}

View file

@ -14,9 +14,9 @@ import org.json.JSONObject;
import java.util.List; import java.util.List;
public class Akaneko { public class Hentai {
@Command(name="akaneko", description=":underage: Searches for an image off of akaneko") @Command(name="hentai", description="Retrieves a random hentai image")
@Selection(name="query", description="Type of post you want to get", type=OptionType.STRING, required=true, choices={"ass","bdsm","cum","hentai","femdom","doujin","maid","orgy","nsfwwallpapers","nsfwmobilewallpapers","gif","blowjob","feet","pussy","uglybastard","gangbang","cumslut","glasses","thighs","tentacles","masturbation","school","yuri","succubus"}) @Selection(name="query", description="Type of post you want to get", type=OptionType.STRING, required=true, choices={"ass","bdsm","cum","hentai","femdom","doujin","maid","orgy","nsfwwallpapers","nsfwmobilewallpapers","gif","blowjob","feet","pussy","uglybastard","gangbang","cumslut","glasses","thighs","tentacles","masturbation","school","yuri","succubus"})
public Response execute(GuildMessageChannel channel, List<Object> args){ public Response execute(GuildMessageChannel channel, List<Object> args){
if(!(channel instanceof TextChannel)) { if(!(channel instanceof TextChannel)) {
@ -37,12 +37,12 @@ public class Akaneko {
} }
private String request(String query){ private String request(String query){
JSONObject json = (JSONObject) new JsonRequest() String response = (String) new JsonRequest()
.setURL("https://akaneko-api.herokuapp.com/api/"+query) .setURL("https://akaneko-api.herokuapp.com/api/"+query)
.setType(HTTPMethod.GET) .setType(HTTPMethod.GET)
.request(); .request();
try { try {
return json.getString("url"); return new JSONObject(response).getString("url");
} catch (JSONException e) { } catch (JSONException e) {
return null; return null;
} }

View file

@ -19,8 +19,9 @@ import java.util.List;
public class Rule34 { public class Rule34 {
@Command(name="rule34",description=":underage: Searches for an image off of rule34") @Command(name="rule34",description="Searches for an image off of rule34")
@Option(name="query",description="Search query for rule34",type=OptionType.STRING,required=true) @Option(name="query",description="Search query for rule34",type=OptionType.STRING,required=true)
@Option(name="page",description="Page number for rule34",type= OptionType.INTEGER)
public Response execute(GuildMessageChannel channel, List<Object> args){ public Response execute(GuildMessageChannel channel, List<Object> args){
if(!(channel instanceof TextChannel)) { if(!(channel instanceof TextChannel)) {
return Response.error("This command can only be used in a text channel"); return Response.error("This command can only be used in a text channel");
@ -29,7 +30,8 @@ public class Rule34 {
if(!textChannel.isNSFW()){ if(!textChannel.isNSFW()){
return Response.error("This command can only be used in an NSFW channel"); return Response.error("This command can only be used in an NSFW channel");
} }
String url = request((String)args.get(0)); int page = args.size() > 1 ? (int)args.get(1) : 1;
String url = request((String)args.get(0), page);
if(url == null){ if(url == null){
return Response.error("Unable to find post with search: "+args.get(0)); return Response.error("Unable to find post with search: "+args.get(0));
} else { } else {
@ -39,9 +41,9 @@ public class Rule34 {
} }
} }
private String request(String query) { private String request(String query, int page) {
Document doc = (Document) new XmlRequest() Document doc = (Document) new XmlRequest()
.setURL("https://rule34.xxx/index.php?page=dapi&s=post&q=index&tags=" + query) .setURL("https://rule34.xxx/index.php?page=dapi&s=post&q=index&limit=100&tags="+query+"&pid="+page)
.setType(HTTPMethod.GET) .setType(HTTPMethod.GET)
.request(); .request();
try { try {

View file

@ -0,0 +1,132 @@
package net.tylermurphy.ken.command.nsfw;
import net.dv8tion.jda.api.entities.GuildMessageChannel;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.JsonRequest;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.util.ButtonCallback;
import net.tylermurphy.ken.util.Command;
import net.tylermurphy.ken.util.Option;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class nHentai {
private static class Comic{
public int pages;
public int id;
public String[] page_file_type;
public String cover_file_type;
public String media_id;
public String title;
}
private final Map<Integer,Comic> cache = new HashMap<>();
@Command(name="nhentai", description="Search for a post off of nhentai")
@Option(name="query", description="Post id or search for nhentai", type=OptionType.STRING, required=true)
public Response execute(GuildMessageChannel channel, List<Object> args) {
if (!(channel instanceof TextChannel)) {
return Response.error("This command can only be used in a text channel");
}
TextChannel textChannel = (TextChannel) channel;
if (!textChannel.isNSFW()) {
return Response.error("This command can only be used in an NSFW channel");
}
Comic comic = request((String)args.get(0));
if(comic == null){
return Response.error("Unable to find post with that query");
}
return Response.success(createEmbed(comic,0)).addSecondaryButton("nhentai", "previous", "Previous").addSecondaryButton("nhentai", "next", "Next");
}
@ButtonCallback(name="nhentai")
public Response onButton(String button_id, Message message){
int page, id;
if (message != null && message.getEmbeds().size() > 0 && message.getEmbeds().get(0) != null) {
page = Integer.parseInt(message.getEmbeds().get(0).getFooter().getText().split("/")[0].substring(5));
id = Integer.parseInt(message.getEmbeds().get(0).getDescription().substring(4));
} else {
return Response.error("Embed is missing, please resend command");
}
Comic comic = cache.get(id);
if(comic == null) comic = request(id+"");
if(comic == null) return Response.error("Failed to fetch comic data");
if(button_id.equals("previous"))
page = page - 1 < 0 ? comic.pages : page - 1;
else
page = page + 1 > comic.pages ? 0 : page + 1;
return Response.success(createEmbed(comic,page));
}
private MessageEmbed createEmbed(Comic comic, int page){
String imageLink = page == 0 ?
"https://t.nhentai.net/galleries/"+comic.id+"/cover."+comic.cover_file_type :
"https://i.nhentai.net/galleries/"+comic.id+"/"+page+"."+comic.page_file_type[page-1];
return Ken.getInstance().getDefaultEmbed()
.setTitle(comic.title, "https://nhentai.net/g/"+comic.id)
.setImage(imageLink)
.setDescription("id: "+comic.id)
.setFooter("Page "+page+"/"+comic.pages)
.build();
}
private Comic request(String search) {
int id;
JSONObject info;
if(search.length() == 6 && isNumber(search)){
id = Integer.parseInt(search);
if(cache.containsKey(id)) return cache.get(id);
String response = (String) new JsonRequest()
.setURL(String.format("https://nhentai.net/api/gallery/%s", id))
.setType(HTTPMethod.GET)
.request();
info = new JSONObject(response);
} else {
String response = (String) new JsonRequest()
.setURL("https://nhentai.net/api/galleries/search?query="+search+"%20language:english")
.setType(HTTPMethod.GET)
.request();
JSONArray results = new JSONObject(response).getJSONArray("result");
if(results.length() == 0) return null;
info = (JSONObject) results.get((int) (Math.random()*results.length()));
id = info.getInt("id");
}
Comic c = new Comic();
c.pages = info.getJSONObject("images").getJSONArray("pages").length();
c.page_file_type = new String[c.pages];
Iterator<Object> itr = info.getJSONObject("images").getJSONArray("pages").iterator();
int i = 0;
while(itr.hasNext()) {
JSONObject o = (JSONObject) itr.next();
c.page_file_type[i] = o.getString("t").equals("j") ? "jpg" : "png";
i++;
}
c.cover_file_type = info.getJSONObject("images").getJSONObject("cover").getString("t").equals("j") ? "jpg" : "png";
c.media_id = info.getString("media_id");
c.title = info.getJSONObject("title").getString("english");
c.id = id;
cache.put(id,c);
return c;
}
private static boolean isNumber(String test) {
try {
Integer.parseInt(test);
return true;
} catch (Exception e){
return false;
}
}
}