this.remarks = Arrays.asList("The URL should be a direct link to an image.", "You can also upload an image as an attachment while calling this command instead of using a url.",
- " * Specify the `-d` parameter to do a depth search!", " * It is useful for cropped images and edited images, but makes the search much longer.");
+ " * Specify the `-d` parameter to do a depth search!", " * It is useful for cropped images and edited images, but makes the search much longer,", " * and can sometimes result in a related image instead of the actual source.");
}
@Override
public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) { //allow people to not input url to check sauce of the most recent image like u/2dgt3d?
List<String> amend = new ArrayList<String>(Arrays.asList(args));
+ //check if image boards are found, if so return the first one found and discard similar results since imageboards are as standard as we can get
+ //it is possible but unlikely that we would be grabbing the wrong image's source in the lower sections even though there are good sources (that are not imageboards) at the top due to this
+ //gets second image coz usually the first one is just a sharper identical image
+ Element simThumb = yandex.select(osSimilar).get(1);
+ String similar = "https:" + (osSimilar.contains(".CbirSimilar") ? simThumb.attr("style").replaceAll(".*url\\((.*?)\\).*", "$1") : simThumb.attr("src")); //use yandex's thumbnails since the actual source might be broken already
+
+ //use other sizes if found - second most accurate result (unless theres edits that uses the image in it (memes for example), so still retain similar results)
+ if(yandex.select(".CbirOtherSizes-Wrapper").size() > 0) { //merge the sort algorithms? //sorting with ratio seems to perform bad for most crops so dont sort anymore
- String other, site = null, similar = URLDecoder.decode(yandex.select(".cbir-similar__thumb .cbir-similar__image").get(yandex.select(".cbir-other-sizes__item").size() > 0 ? 1 : 0).parent().attr("href").split("img_url=")[1].split("&")[0], "UTF-8");
- if(yandex.select(".cbir-other-sizes__list").size() > 0) { //TODO merge the sort algorithms?
- /*other = yandex.select(".cbir-other-sizes__list").first().select("a").stream().sorted((a, b) -> { //selects largest possible section of the other sizes
- String[] aA = a.select(".cbir-other-sizes__resolution").first().text().split("×"), bA = b.select(".cbir-other-sizes__resolution").first().text().split("×");
- other = yandex.select(".cbir-other-sizes__list a").first().attr("href"); //sorting with ratio seems to perform bad for most crops so dont sort anymore
- } else {
- yandex.select(".other-sites__item").stream().limit(12).sorted((a, b) -> {
- String[] aA = a.select(".other-sites__meta").first().text().split("×"), bA = b.select(".other-sites__meta").first().text().split("×");
- other = eSite.select(".other-sites__preview-link").first().attr("href");
- site = eSite.select(".other-sites__snippet-site-link").first().attr("href");
- }
- return new String[]{similar, other, site};
- //gets second image coz usually the first one is just a sharper identical image, then get the largest image that has the image inside or select an image closest to 16:9 for anime checking //closest to given ratio now, anime checking usually cant be done with depth search anyways since not every scene is screen capped online
+ Element eSite = yandex.select(osItem).stream().limit(12).sorted((a, b) -> {
+ String[] aA = a.select(osMeta).first().text().split("×"), bA = b.select(osMeta).first().text().split("×");
try { //search iqdb first for the tags; results usually more organized and formatted
- Element iqdb = Jsoup.connect("https://iqdb.org/?url=" + url + "&service[]=1&service[]=2&service[]=3&service[]=4&service[]=5&service[]=11&service[]=13").get().body(); //services excluding eshuushuu since it has no tags and will fallback to saucenao anyways
- if(iqdb.select(".err").size() > 0 && iqdb.select(".err").html().contains("HTTP")) throw new IOException(iqdb.selectFirst(".err").ownText().split("\\.")[0]);
+ Element iqdb = Jsoup.connect("https://iqdb.org/?url=" + URLEncoder.encode(url, "UTF-8") + "&service[]=1&service[]=2&service[]=3&service[]=4&service[]=5&service[]=11&service[]=13").post().body(); //services excluding eshuushuu since it has no tags and will fallback to saucenao anyways
+ //post instead of get due to the recent incident making iqdb and saucenao block imgur
+
+ if(iqdb.select(".err").size() > 0 && iqdb.select(".err").html().contains("HTTP")) //iqdb errors, most likely broken link so dont fallback
+ throw new IOException(iqdb.selectFirst(".err").ownText().split("\\.")[0]);
+
Elements tb = iqdb.select("th:contains(Best match)").get(0).parent().siblingElements();
+ try { //fallback to saucenao, usually pixiv source instead of image boards; also falls back if its anime scenes
+ Element saucenao = Jsoup.connect("https://saucenao.com/search.php").requestBody("url=" + URLEncoder.encode(url, "UTF-8")).post().body(); //same reason as iqdb post
Element result = saucenao.selectFirst(".resulttable");
+ //change line break tags to \n, and use first line as title
result.select("br").after("\\n");
String[] title = result.selectFirst(".resulttitle") == null ? new String[]{"No title"} : result.selectFirst(".resulttitle").wholeText().replaceAll("\\\\n", "\n").split("\n", 2); //there can be no titles, like 4chan sources