From 69da2b02ac0c5dd1b86611589bac4cc4f7383e02 Mon Sep 17 00:00:00 2001 From: LamGC Date: Thu, 4 Jun 2020 09:29:53 +0800 Subject: [PATCH] =?UTF-8?q?[Fix=20#11]=20=E4=BF=AE=E5=A4=8D=E5=9C=A8?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E7=BC=93=E5=AD=98=E5=A4=B1=E6=95=88=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=B8=8B,=20'getImageToBotCode'=E4=BE=9D?= =?UTF-8?q?=E7=84=B6=E4=BC=9A=E5=B0=9D=E8=AF=95=E4=BB=8E=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=9B=BE=E7=89=87File=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E5=AF=BC=E8=87=B4NPE;=20[Change]=20BotCommandProcess=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=8B=BC=E6=8E=A5?= =?UTF-8?q?=E5=BD=A2=E5=BC=8F,=20=E7=BB=9F=E4=B8=80=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=AF=AD=E7=9A=84=E6=A0=BC=E5=BC=8F;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/lamgc/cgj/bot/BotCommandProcess.java | 98 +++++++++---------- .../cgj/bot/cache/ImageCacheHandler.java | 6 +- .../lamgc/cgj/bot/cache/ImageCacheStore.java | 34 ++++++- .../cache/exception/HttpRequestException.java | 44 +++++++++ 4 files changed, 125 insertions(+), 57 deletions(-) create mode 100644 src/main/java/net/lamgc/cgj/bot/cache/exception/HttpRequestException.java diff --git a/src/main/java/net/lamgc/cgj/bot/BotCommandProcess.java b/src/main/java/net/lamgc/cgj/bot/BotCommandProcess.java index eaae020..0403640 100644 --- a/src/main/java/net/lamgc/cgj/bot/BotCommandProcess.java +++ b/src/main/java/net/lamgc/cgj/bot/BotCommandProcess.java @@ -110,34 +110,27 @@ public class BotCommandProcess { @Command(defaultCommand = true) public static String help() { - StringBuilder helpStrBuilder = new StringBuilder(); - helpStrBuilder.append("CGJ Bot使用指南").append("\n"); - helpStrBuilder.append("使用方法:.cgj <命令> [参数...]").append("\n"); - helpStrBuilder.append("例如查询作品信息功能:").append("\n"); - helpStrBuilder.append(".cgj info -id 80846159").append("\n"); - helpStrBuilder.append("目前可用的命令:").append("\n"); - helpStrBuilder.append("\t").append("ranking - 获取今天或指定日期排行榜的前10名作品").append("\n"); - helpStrBuilder.append("\t\t").append("-date - 指定查询日期(年-月-日)").append("\n"); - helpStrBuilder.append("\t\t").append("-type - 排行榜类型(illust/插画, ugoira/动图, manga/漫画)").append("\n"); - - helpStrBuilder.append("\t").append("search - 搜索指定关键词并显示前10个作品").append("\n"); - helpStrBuilder.append("\t\t").append("-content - 搜索内容").append("\n"); - - helpStrBuilder.append("\t").append("link - 获取作品的Pixiv页面").append("\n"); - helpStrBuilder.append("\t\t").append("-id - 作品id").append("\n"); - - helpStrBuilder.append("\t").append("info - 获取Pixiv作品信息").append("\n"); - helpStrBuilder.append("\t\t").append("-id - 作品id").append("\n"); - - helpStrBuilder.append("\t").append("image - 获取指定作品的图片").append("\n"); - helpStrBuilder.append("\t\t").append("-id - 作品id").append("\n"); - helpStrBuilder.append("\t\t").append("-quality - 图片质量(original/原图 regular/预览图)").append("\n"); - helpStrBuilder.append("\t\t").append("-page - 页数").append("\n"); - - helpStrBuilder.append("\t").append("report - 报告不当作品").append("\n"); - helpStrBuilder.append("\t\t").append("-id - 作品Id").append("\n"); - helpStrBuilder.append("\t\t").append("-msg - 报告原因").append("\n"); - return helpStrBuilder.toString(); + return "CGJ Bot使用指南" + "\n" + + "使用方法:.cgj <命令> [参数...]" + "\n" + + "例如查询作品信息功能:" + "\n" + + ".cgj info -id 80846159" + "\n" + + "目前可用的命令:" + "\n" + + "\t" + "ranking - 获取今天或指定日期排行榜的前10名作品" + "\n" + + "\t\t" + "-date - 指定查询日期(年-月-日)" + "\n" + + "\t\t" + "-type - 排行榜类型(illust/插画, ugoira/动图, manga/漫画)" + "\n" + + "\t" + "search - 搜索指定关键词并显示前10个作品" + "\n" + + "\t\t" + "-content - 搜索内容" + "\n" + + "\t" + "link - 获取作品的Pixiv页面" + "\n" + + "\t\t" + "-id - 作品id" + "\n" + + "\t" + "info - 获取Pixiv作品信息" + "\n" + + "\t\t" + "-id - 作品id" + "\n" + + "\t" + "image - 获取指定作品的图片" + "\n" + + "\t\t" + "-id - 作品id" + "\n" + + "\t\t" + "-quality - 图片质量(original/原图 regular/预览图)" + "\n" + + "\t\t" + "-page - 页数" + "\n" + + "\t" + "report - 报告不当作品" + "\n" + + "\t\t" + "-id - 作品Id" + "\n" + + "\t\t" + "-msg - 报告原因" + "\n"; } /** @@ -158,25 +151,24 @@ public class BotCommandProcess { } JsonObject illustPreLoadData = getIllustPreLoadData(illustId, false); - StringBuilder builder = new StringBuilder("色图姬帮你了解了这个作品的信息!\n"); - builder.append("---------------- 作品信息 ----------------"); - builder.append("\n作品Id: ").append(illustId); - builder.append("\n作品标题:").append(illustPreLoadData.get("illustTitle").getAsString()); - builder.append("\n作者(作者Id):").append(illustPreLoadData.get("userName").getAsString()) - .append("(").append(illustPreLoadData.get("userId").getAsInt()).append(")"); - builder.append("\n点赞数:").append(illustPreLoadData.get(PreLoadDataComparator.Attribute.LIKE.attrName).getAsInt()); - builder.append("\n收藏数:").append(illustPreLoadData.get(PreLoadDataComparator.Attribute.BOOKMARK.attrName).getAsInt()); - builder.append("\n围观数:").append(illustPreLoadData.get(PreLoadDataComparator.Attribute.VIEW.attrName).getAsInt()); - builder.append("\n评论数:").append(illustPreLoadData.get(PreLoadDataComparator.Attribute.COMMENT.attrName).getAsInt()); - builder.append("\n页数:").append(illustPreLoadData.get(PreLoadDataComparator.Attribute.PAGE.attrName).getAsInt()).append("页"); - builder.append("\n作品链接:").append(artworksLink(fromGroup, illustId)).append("\n"); - builder.append("---------------- 作品图片 ----------------\n"); - builder.append(getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1)).append("\n"); - builder.append("使用 \".cgj image -id ") - .append(illustId) - .append("\" 获取原图。\n如有不当作品,可使用\".cgj report -id ") - .append(illustId).append("\"向色图姬反馈。"); - return builder.toString(); + // 在 Java 6 开始, 编译器会将用'+'进行的字符串拼接将自动转换成StringBuilder拼接 + return "色图姬帮你了解了这个作品的信息!\n" + "---------------- 作品信息 ----------------" + + "\n作品Id: " + illustId + + "\n作品标题:" + illustPreLoadData.get("illustTitle").getAsString() + + "\n作者(作者Id):" + illustPreLoadData.get("userName").getAsString() + + "(" + illustPreLoadData.get("userId").getAsInt() + ")" + + "\n点赞数:" + illustPreLoadData.get(PreLoadDataComparator.Attribute.LIKE.attrName).getAsInt() + + "\n收藏数:" + illustPreLoadData.get(PreLoadDataComparator.Attribute.BOOKMARK.attrName).getAsInt() + + "\n围观数:" + illustPreLoadData.get(PreLoadDataComparator.Attribute.VIEW.attrName).getAsInt() + + "\n评论数:" + illustPreLoadData.get(PreLoadDataComparator.Attribute.COMMENT.attrName).getAsInt() + + "\n页数:" + illustPreLoadData.get(PreLoadDataComparator.Attribute.PAGE.attrName).getAsInt() + "页" + + "\n作品链接:" + artworksLink(fromGroup, illustId) + "\n" + + "---------------- 作品图片 ----------------\n" + + getImageById(fromGroup, illustId, PageQuality.REGULAR, 1) + "\n" + + "使用 \".cgj image -id " + + illustId + + "\" 获取原图。\n如有不当作品,可使用\".cgj report -id " + + illustId + "\"向色图姬反馈。"; } catch (IOException e) { e.printStackTrace(); } @@ -583,7 +575,7 @@ public class BotCommandProcess { } } catch (IOException e) { log.warn("作品信息无法获取!", e); - return "发生网络异常,无法获取图片!"; + return "(发生网络异常,无法获取图片!)"; } List pagesList; @@ -631,10 +623,16 @@ public class BotCommandProcess { } try { - ImageCacheStore.executeCacheRequest(new ImageCacheObject(imageCache, illustId, downloadLink, imageFile)); + Throwable throwable = ImageCacheStore.executeCacheRequest(new ImageCacheObject(imageCache, illustId, downloadLink, imageFile)); + if(throwable != null) { + throw throwable; + } } catch (InterruptedException e) { log.warn("图片缓存被中断", e); return "(错误:图片获取超时)"; + } catch (Throwable e) { + log.error("图片 {} 获取失败:\n{}", illustId + "p" + pageIndex, Throwables.getStackTraceAsString(e)); + return "(错误: 图片获取出错)"; } } else { log.debug("图片 {} 缓存命中.", fileName); @@ -650,7 +648,7 @@ public class BotCommandProcess { * @return 返回设定好参数的BotCode */ private static BotCode getImageToBotCode(File targetFile, boolean updateCache) { - String fileName = targetFile.getName(); + String fileName = Objects.requireNonNull(targetFile, "targetFile is null").getName(); BotCode code = BotCode.parse(CQCode.image(getImageStoreDir().getName() + "/" + fileName)); code.addParameter("absolutePath", targetFile.getAbsolutePath()); code.addParameter("imageName", fileName.substring(0, fileName.lastIndexOf("."))); diff --git a/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheHandler.java b/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheHandler.java index 20b6eae..7017521 100644 --- a/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheHandler.java +++ b/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheHandler.java @@ -1,6 +1,7 @@ package net.lamgc.cgj.bot.cache; import net.lamgc.cgj.Main; +import net.lamgc.cgj.bot.cache.exception.HttpRequestException; import net.lamgc.cgj.pixiv.PixivURL; import net.lamgc.cgj.util.URLs; import net.lamgc.utils.event.EventHandler; @@ -60,8 +61,9 @@ public class ImageCacheHandler implements EventHandler { throw e; } if(response.getStatusLine().getStatusCode() != 200) { - log.warn("Http请求异常:{}", response.getStatusLine()); - throw new IOException("Http Response Error: " + response.getStatusLine()); + HttpRequestException requestException = new HttpRequestException(response); + log.warn("Http请求异常:{}", requestException.getStatusLine()); + throw requestException; } log.debug("正在下载...(Content-Length: {}KB)", response.getEntity().getContentLength() / 1024); diff --git a/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheStore.java b/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheStore.java index 11b1f25..7657838 100644 --- a/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheStore.java +++ b/src/main/java/net/lamgc/cgj/bot/cache/ImageCacheStore.java @@ -1,9 +1,14 @@ package net.lamgc.cgj.bot.cache; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import net.lamgc.cgj.bot.cache.exception.HttpRequestException; + import java.util.Hashtable; import java.util.Map; import java.util.concurrent.*; @@ -34,29 +39,30 @@ public final class ImageCacheStore { * 传递图片缓存任务, 并等待缓存完成. * @param cacheObject 缓存任务组 */ - public static void executeCacheRequest(ImageCacheObject cacheObject) throws InterruptedException { + public static Throwable executeCacheRequest(ImageCacheObject cacheObject) throws InterruptedException { Task task = getTaskState(cacheObject); if(task.taskState.get() == TaskState.COMPLETE) { - return; + return null; } boolean locked = false; try { if(task.taskState.get() == TaskState.COMPLETE) { - return; + return null; } task.lock.lock(); locked = true; // 双重检查 if(task.taskState.get() == TaskState.COMPLETE) { - return; + return null; } // 置任务状态 task.taskState.set(TaskState.RUNNING); + Throwable throwable = null; try { - Throwable throwable = imageCacheExecutor.submit(() -> { + throwable = imageCacheExecutor.submit(() -> { try { handler.getImageToCache(cacheObject); } catch (Throwable e) { @@ -73,6 +79,7 @@ public final class ImageCacheStore { } catch (ExecutionException e) { log.error("执行图片缓存任务时发生异常", e); } + return throwable; } finally { if(locked) { task.lock.unlock(); @@ -88,6 +95,23 @@ public final class ImageCacheStore { return cacheMap.get(cacheObject); } + /** + * 获取错误信息 + */ + public static String getErrorMessageFromThrowable(Throwable throwable, boolean onlyRequestException) { + if(throwable == null) { + return ""; + } else if(!(throwable instanceof HttpRequestException)) { + if(onlyRequestException) { + return ""; + } + return throwable.getMessage(); + } + JsonObject result = new Gson() + .fromJson(((HttpRequestException) throwable).getContent(), JsonObject.class); + return result.get("msg").getAsString(); + } + /** * 任务状态 */ diff --git a/src/main/java/net/lamgc/cgj/bot/cache/exception/HttpRequestException.java b/src/main/java/net/lamgc/cgj/bot/cache/exception/HttpRequestException.java new file mode 100644 index 0000000..f7d6faa --- /dev/null +++ b/src/main/java/net/lamgc/cgj/bot/cache/exception/HttpRequestException.java @@ -0,0 +1,44 @@ +package net.lamgc.cgj.bot.cache.exception; + +import java.io.IOException; +import java.util.Objects; + +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.util.EntityUtils; + +public class HttpRequestException extends IOException { + + private static final long serialVersionUID = -2229221075943552798L; + + private final StatusLine statusLine; + + private final String content; + + public HttpRequestException(HttpResponse response) throws IOException { + this(response.getStatusLine(), EntityUtils.toString(response.getEntity())); + } + + public HttpRequestException(StatusLine statusLine, String content) { + super("Http Response Error: " + Objects.requireNonNull(statusLine, "statusLine is null") + + ", Response Content: " + (content == null ? "null" : '\'' + content + '\'')); + this.statusLine = statusLine; + this.content = content; + } + + /** + * 获取Http状态行 + */ + public StatusLine getStatusLine() { + return statusLine; + } + + /** + * 获取Response内容 + * @return 如果没有返回, 则返回null + */ + public String getContent() { + return content; + } + +} \ No newline at end of file