Skip to content

Commit

Permalink
Merge pull request #47 from Mazawrath/Analyze_Improvement
Browse files Browse the repository at this point in the history
Cleaned up analyze command and put image requests into their own class
  • Loading branch information
Mazawrath authored Jan 13, 2019
2 parents b641998 + fed835a commit ab5994c
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 109 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/mazawrath/beanbot/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static void main(String[] args) {
// Bean Lottery Commands
cmdHandler.registerCommand(new BeanLotteryCommand(points, lottery));
// Google Vision Commands
cmdHandler.registerCommand(new AnalyzeCommand(points, cloudVision));
cmdHandler.registerCommand(new AnalyzeCommand(points));
// Admin commands
cmdHandler.registerCommand(new AdminPostChangeLogCommand());
cmdHandler.registerCommand(new AdminDeleteMessageCommand());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,19 @@ public void onCommand(String[] args, DiscordApi api, ServerTextChannel serverTex

private String getRecentChangeLog() {
return "**New beanBOT update released.**\n" +
"Release can be found on https://github.com/Mazawrath/beanBOT/releases/tag/v3.2.0\n" +
"Detailed changelog can be found on https://github.com/Mazawrath/beanBOT/compare/v3.1.1...v3.2.0\n" +
"Release can be found on https://github.com/Mazawrath/beanBOT/releases/tag/v3.2.1\n" +
"Detailed changelog can be found on https://github.com/Mazawrath/beanBOT/compare/v3.2.0...v3.2.1\n" +
"\n" +
"**v3.2.0**\n" +
"**New**\n" +
"\t- Added `.analyze`.\n" +
"\t\t- Using Google Cloud Vision, beanBOT can now examine a photo for objects, faces, emotions, and more.\n" +
"**v3.2.1**\n" +
// "**New**\n" +
// "\t- Added `.analyze`.\n" +
// "\t\t- Using Google Cloud Vision, beanBOT can now examine a photo for objects, faces, emotions, and more.\n" +
// "\t\t- Server owners can now type `.admintwitch add [twitch channel name]` to subscribe to live notifications for a twitch channel.\n" +
"**Changes**\n" +
"\t- Disabled `.beanlottery draw`.";
// "**Bug Fixes**\n" +
// "\t- Fixed an issue with `.beanlottery` not giving help information.\n";
"\t- Cleaned up analyze command.\n" +
"\t- Expanded lottery numbers that could be drawn from 20 to 40.\n" +
"\t- Raised price of beanLottery tickets from 20 beanCoin to 40 beanCoin.\n" +
"**Bug Fixes**\n" +
"\t- Fixed an issue with Discord not creating new thumbnail previews.\n";
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
package com.mazawrath.beanbot.commands.googlevision;

import com.google.cloud.vision.v1.AnnotateImageResponse;
import com.google.cloud.vision.v1.EntityAnnotation;
import com.google.cloud.vision.v1.SafeSearchAnnotation;
import com.google.cloud.vision.v1.WebDetection;
import com.mazawrath.beanbot.utilities.GoogleCloudVision;
import com.mazawrath.beanbot.utilities.ImageRequest;
import com.mazawrath.beanbot.utilities.Points;
import de.btobastian.sdcf4j.Command;
import de.btobastian.sdcf4j.CommandExecutor;
import org.apache.commons.lang3.text.WordUtils;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.ServerTextChannel;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.server.Server;
import org.javacord.api.entity.user.User;

import javax.activation.MimetypesFileTypeMap;
import java.awt.*;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

public class AnalyzeCommand implements CommandExecutor {
private Points points;
private GoogleCloudVision cloudVision;

public AnalyzeCommand(Points points, GoogleCloudVision cloudVision) {
public AnalyzeCommand(Points points) {
this.points = points;
this.cloudVision = cloudVision;
}

@Command(
Expand Down Expand Up @@ -63,17 +53,11 @@ else if (args.length > 0) {

serverTextChannel.sendMessage("Analyzing image...");

List<EntityAnnotation> labelAnnotation;
AnnotateImageResponse faceDetection;
SafeSearchAnnotation safeSearchAnnotation;
WebDetection webDetection;
ImageRequest imageRequest;

if (urlContainsImage(url)) {
try {
labelAnnotation = cloudVision.getLabelDetection(url);
faceDetection = cloudVision.getFaceDetection(url);
safeSearchAnnotation = cloudVision.detectSafeSearch(url);
webDetection = cloudVision.getWebDetection(url);
imageRequest = new ImageRequest(url);
} catch (Exception e) {
e.printStackTrace();
serverTextChannel.sendMessage("Something went wrong.");
Expand All @@ -84,61 +68,7 @@ else if (args.length > 0) {
return;
}

EmbedBuilder embed = new EmbedBuilder()
.setTitle("Image Analysis")
.setColor(Color.BLUE);

StringBuilder labels = new StringBuilder();
for (int i = 0; i < labelAnnotation.size(); i++) {
if (i != labelAnnotation.size() - 1) {
labels.append(labelAnnotation.get(i).getDescription()).append(" (").append(Math.round(labelAnnotation.get(0).getScore() * 100)).append("%), ");
} else
labels.append(labelAnnotation.get(i).getDescription()).append(" (").append(Math.round(labelAnnotation.get(0).getScore() * 100)).append("%)");
}

embed.addField("Things I See", labels.toString());

embed.addInlineField("Faces I See", String.valueOf(faceDetection.getFaceAnnotationsCount()));

for (int i = 0; i < faceDetection.getFaceAnnotationsCount(); i++) {
StringBuilder emotionsSeen = new StringBuilder();
if (faceDetection.getFaceAnnotations(i).getJoyLikelihoodValue() > 1)
emotionsSeen.append("joy, ");
if (faceDetection.getFaceAnnotations(i).getSorrowLikelihoodValue() > 1)
emotionsSeen.append("sorrow, ");
if (faceDetection.getFaceAnnotations(i).getAngerLikelihoodValue() > 1)
emotionsSeen.append("anger, ");
if (faceDetection.getFaceAnnotations(i).getSurpriseLikelihoodValue() > 1)
emotionsSeen.append("surprise, ");

if (emotionsSeen.length() != 0)
embed.addInlineField("Face " + (i + 1) + "'s Possible Emotions", WordUtils.capitalizeFully(emotionsSeen.substring(0, emotionsSeen.length() - 2)));
else
embed.addInlineField("Face " + (i + 1) + "'s Possible Emotions", "none");
}
embed.addInlineField("Best Guess", webDetection.getBestGuessLabels(0).getLabel());

StringBuilder webLabels = new StringBuilder();
for (int i = 0; i < webDetection.getWebEntitiesCount(); i++) {
if (i != webDetection.getWebEntitiesCount() - 1)
webLabels.append(webDetection.getWebEntities(i).getDescription()).append(" (").append(Math.round(webDetection.getWebEntities(i).getScore() * 100)).append("%), ");
else
webLabels.append(webDetection.getWebEntities(i).getDescription()).append(" (").append(Math.round(webDetection.getWebEntities(i).getScore() * 100)).append("%)");
}
embed.addField("Things I Think This Is", webLabels.toString());

if (safeSearchAnnotation.getAdultValue() > 2)
embed.addInlineField("Adult Content", WordUtils.capitalizeFully(safeSearchAnnotation.getAdult().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getSpoofValue() > 2)
embed.addInlineField("Spoof / Edited Photo", WordUtils.capitalizeFully(safeSearchAnnotation.getSpoof().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getMedicalValue() > 2)
embed.addInlineField("Medical / Surgery", WordUtils.capitalizeFully(safeSearchAnnotation.getMedical().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getViolenceValue() > 2)
embed.addInlineField("Violence / Blood / Gore", WordUtils.capitalizeFully(safeSearchAnnotation.getViolence().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getRacyValue() > 2)
embed.addInlineField("Skimpy / Nudity", WordUtils.capitalizeFully(safeSearchAnnotation.getRacy().name().replaceAll("_", " ")));

serverTextChannel.sendMessage(embed);
serverTextChannel.sendMessage(imageRequest.buildEmbed());
}

private boolean urlContainsImage(URL url) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public GoogleCloudVision() {
System.setProperty("http.agent", "Chrome");
}

public List<EntityAnnotation> getLabelDetection(URL image) {
List<EntityAnnotation> getLabelDetection(URL image) {
try (ImageAnnotatorClient vision = ImageAnnotatorClient.create()) {

ByteString imgBytes = ByteString.copyFrom(Objects.requireNonNull(downloadFile(image)));
Expand All @@ -38,21 +38,14 @@ public List<EntityAnnotation> getLabelDetection(URL image) {
BatchAnnotateImagesResponse response = vision.batchAnnotateImages(requests);
List<AnnotateImageResponse> responses = response.getResponsesList();

for (AnnotateImageResponse res : responses) {
if (res.hasError()) {
System.out.printf("Error: %s\n", res.getError().getMessage());
return null;
}

return res.getLabelAnnotationsList();
}
return responses.get(0).getLabelAnnotationsList();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

public SafeSearchAnnotation detectSafeSearch(URL image) throws IOException {
SafeSearchAnnotation detectSafeSearch(URL image) throws IOException {
List<AnnotateImageRequest> requests = new ArrayList<>();

ByteString imgBytes = ByteString.copyFrom(Objects.requireNonNull(downloadFile(image)));
Expand All @@ -67,19 +60,11 @@ public SafeSearchAnnotation detectSafeSearch(URL image) throws IOException {
BatchAnnotateImagesResponse response = client.batchAnnotateImages(requests);
List<AnnotateImageResponse> responses = response.getResponsesList();

for (AnnotateImageResponse res : responses) {
if (res.hasError()) {
return null;
}

// For full list of available annotations, see http://g.co/cloud/vision/docs
return res.getSafeSearchAnnotation();
}
return responses.get(0).getSafeSearchAnnotation();
}
return null;
}

public AnnotateImageResponse getFaceDetection(URL image) throws Exception, IOException {
AnnotateImageResponse getFaceDetection(URL image) throws Exception {
List<AnnotateImageRequest> requests = new ArrayList<>();

ByteString imgBytes = ByteString.copyFrom(Objects.requireNonNull(downloadFile(image)));
Expand All @@ -92,12 +77,12 @@ public AnnotateImageResponse getFaceDetection(URL image) throws Exception, IOExc

try (ImageAnnotatorClient client = ImageAnnotatorClient.create()) {
BatchAnnotateImagesResponse response = client.batchAnnotateImages(requests);

return response.getResponsesList().get(0);
}
}

public WebDetection getWebDetection(URL image) throws Exception,
IOException {
WebDetection getWebDetection(URL image) throws Exception {
List<AnnotateImageRequest> requests = new ArrayList<>();

ByteString imgBytes = ByteString.copyFrom(Objects.requireNonNull(downloadFile(image)));
Expand Down
113 changes: 113 additions & 0 deletions src/main/java/com/mazawrath/beanbot/utilities/ImageRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.mazawrath.beanbot.utilities;

import com.google.cloud.vision.v1.AnnotateImageResponse;
import com.google.cloud.vision.v1.EntityAnnotation;
import com.google.cloud.vision.v1.SafeSearchAnnotation;
import com.google.cloud.vision.v1.WebDetection;
import org.apache.commons.lang3.text.WordUtils;
import org.javacord.api.entity.message.embed.EmbedBuilder;

import java.awt.*;
import java.net.URL;
import java.util.List;

public class ImageRequest {
private URL image;

private List<EntityAnnotation> labelAnnotation;
private AnnotateImageResponse faceDetection;
private SafeSearchAnnotation safeSearchAnnotation;
private WebDetection webDetection;

public ImageRequest(URL image) {
this.image = image;
GoogleCloudVision cloudVision = new GoogleCloudVision();

try {
labelAnnotation = cloudVision.getLabelDetection(image);
faceDetection = cloudVision.getFaceDetection(image);
safeSearchAnnotation = cloudVision.detectSafeSearch(image);
webDetection = cloudVision.getWebDetection(image);
} catch (Exception e) {
e.printStackTrace();
}
}

public URL getImage() {
return image;
}

public List<EntityAnnotation> getLabelAnnotation() {
return labelAnnotation;
}

public AnnotateImageResponse getFaceDetection() {
return faceDetection;
}

public SafeSearchAnnotation getSafeSearchAnnotation() {
return safeSearchAnnotation;
}

public WebDetection getWebDetection() {
return webDetection;
}

public EmbedBuilder buildEmbed() {
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Image Analysis")
.setColor(Color.BLUE);

StringBuilder labels = new StringBuilder();
for (int i = 0; i < labelAnnotation.size(); i++) {
if (i != labelAnnotation.size() - 1) {
labels.append(labelAnnotation.get(i).getDescription()).append(" (").append(Math.round(labelAnnotation.get(0).getScore() * 100)).append("%), ");
} else
labels.append(labelAnnotation.get(i).getDescription()).append(" (").append(Math.round(labelAnnotation.get(0).getScore() * 100)).append("%)");
}

embed.addField("Things I See", labels.toString());

embed.addInlineField("Faces I See", String.valueOf(faceDetection.getFaceAnnotationsCount()));

for (int i = 0; i < faceDetection.getFaceAnnotationsCount(); i++) {
StringBuilder emotionsSeen = new StringBuilder();
if (faceDetection.getFaceAnnotations(i).getJoyLikelihoodValue() > 1)
emotionsSeen.append("joy, ");
if (faceDetection.getFaceAnnotations(i).getSorrowLikelihoodValue() > 1)
emotionsSeen.append("sorrow, ");
if (faceDetection.getFaceAnnotations(i).getAngerLikelihoodValue() > 1)
emotionsSeen.append("anger, ");
if (faceDetection.getFaceAnnotations(i).getSurpriseLikelihoodValue() > 1)
emotionsSeen.append("surprise, ");

if (emotionsSeen.length() != 0)
embed.addInlineField("Face " + (i + 1) + "'s Possible Emotions", WordUtils.capitalizeFully(emotionsSeen.substring(0, emotionsSeen.length() - 2)));
else
embed.addInlineField("Face " + (i + 1) + "'s Possible Emotions", "none");
}
embed.addInlineField("Best Guess", webDetection.getBestGuessLabels(0).getLabel());

StringBuilder webLabels = new StringBuilder();
for (int i = 0; i < webDetection.getWebEntitiesCount(); i++) {
if (i != webDetection.getWebEntitiesCount() - 1)
webLabels.append(webDetection.getWebEntities(i).getDescription()).append(" (").append(Math.round(webDetection.getWebEntities(i).getScore() * 100)).append("%), ");
else
webLabels.append(webDetection.getWebEntities(i).getDescription()).append(" (").append(Math.round(webDetection.getWebEntities(i).getScore() * 100)).append("%)");
}
embed.addField("Things I Think This Is", webLabels.toString());

if (safeSearchAnnotation.getAdultValue() > 2)
embed.addInlineField("Adult Content", WordUtils.capitalizeFully(safeSearchAnnotation.getAdult().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getSpoofValue() > 2)
embed.addInlineField("Spoof / Edited Photo", WordUtils.capitalizeFully(safeSearchAnnotation.getSpoof().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getMedicalValue() > 2)
embed.addInlineField("Medical / Surgery", WordUtils.capitalizeFully(safeSearchAnnotation.getMedical().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getViolenceValue() > 2)
embed.addInlineField("Violence / Blood / Gore", WordUtils.capitalizeFully(safeSearchAnnotation.getViolence().name().replaceAll("_", " ")));
if (safeSearchAnnotation.getRacyValue() > 2)
embed.addInlineField("Skimpy / Nudity", WordUtils.capitalizeFully(safeSearchAnnotation.getRacy().name().replaceAll("_", " ")));

return embed;
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/mazawrath/beanbot/utilities/Lottery.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
public class Lottery {
public static final int AMOUNT_DRAWN = 3;
public static final int MIN_NUMBER = 1;
public static final int MAX_NUMBER = 20;
public static final int MAX_NUMBER = 40;
public static final BigDecimal MIN_WEEKLY_VALUE = new BigDecimal(50000);
private static final String DB_NAME = "beanBotLottery";

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/mazawrath/beanbot/utilities/Points.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Points {
public static final BigDecimal FREE_POINTS = new BigDecimal("25.69").setScale(SCALE, ROUNDING_MODE);
public static final BigDecimal COMMAND_COST = new BigDecimal("2.00").setScale(SCALE, ROUNDING_MODE);
public static final BigDecimal COMMAND_COST_SPECIAL = new BigDecimal("10.00").setScale(SCALE, ROUNDING_MODE);
public static final BigDecimal LOTTERY_TICKET_COST = new BigDecimal("20.00").setScale(SCALE, ROUNDING_MODE);
public static final BigDecimal LOTTERY_TICKET_COST = new BigDecimal("40.00").setScale(SCALE, ROUNDING_MODE);
public static final BigDecimal LOTTERY_DRAWING_COST = new BigDecimal("20000.00").setScale(SCALE, ROUNDING_MODE);
public static final BigDecimal GOOGLE_VISION_COST = new BigDecimal("50.00").setScale(SCALE, ROUNDING_MODE);
private Connection conn;
Expand Down

0 comments on commit ab5994c

Please sign in to comment.