[Add] BotCommandProcess 将 getImageById 中用于构造BotCode的代码分离到 getImageToBotCode 方法;

[Add] PreLoadDataComparator 增加新的比较器, 主要用于对Pixiv搜索结果的排序;
[Change] BotCommandProcess 重写 getImageById 方法以提高处理效率;
[Change] BotCommandProcess 将 search 方法对搜索结果的排序抽出到新的Comparator实现类(PreLoadDataComparator);
This commit is contained in:
LamGC 2020-04-16 16:51:25 +08:00
parent 2af3c20a21
commit 5ad2a56ce2
2 changed files with 124 additions and 72 deletions

View File

@ -9,9 +9,11 @@ import io.netty.handler.codec.http.HttpHeaderNames;
import net.lamgc.cgj.Main;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.event.BotEventHandler;
import net.lamgc.cgj.bot.sort.PreLoadDataComparator;
import net.lamgc.cgj.pixiv.PixivDownload;
import net.lamgc.cgj.pixiv.PixivSearchBuilder;
import net.lamgc.cgj.pixiv.PixivURL;
import net.lamgc.cgj.util.URLs;
import net.lamgc.utils.base.runner.Argument;
import net.lamgc.utils.base.runner.Command;
import net.lamgc.utils.event.EventExecutor;
@ -336,25 +338,7 @@ public class BotCommandProcess {
.getAsJsonObject(searchArea.jsonKey).getAsJsonArray("data");
ArrayList<JsonElement> illustsList = new ArrayList<>();
illustsArray.forEach(illustsList::add);
illustsList.sort((o1, o2) -> {
if(!o1.getAsJsonObject().has("illustId") || !o2.getAsJsonObject().has("illustId")) {
if(o1.getAsJsonObject().has("illustId")) {
return 1;
} else if(o2.getAsJsonObject().has("illustId")) {
return -1;
} else {
return 0;
}
}
try {
JsonObject illustPreLoadData1 = getIllustPreLoadData(o1.getAsJsonObject().get("illustId").getAsInt(), false);
JsonObject illustPreLoadData2 = getIllustPreLoadData(o2.getAsJsonObject().get("illustId").getAsInt(), false);
return Integer.compare(illustPreLoadData2.get("likeCount").getAsInt(), illustPreLoadData1.get("likeCount").getAsInt());
} catch (IOException e) {
e.printStackTrace();
return 0;
}
});
illustsList.sort(new PreLoadDataComparator(PreLoadDataComparator.Attribute.LIKE));
log.info("已找到与 {} 相关插图信息({})", content, searchArea.name().toLowerCase());
int count = 1;
@ -435,6 +419,13 @@ public class BotCommandProcess {
return PixivURL.getPixivRefererLink(illustId);
}
/**
* 通过illustId获取作品图片
* @param illustId 作品Id
* @param quality 图片质量
* @param pageIndex 指定页面索引, 从1开始
* @return 如果成功, 返回BotCode, 否则返回错误信息.
*/
@Command(commandName = "image")
public static String getImageById(@Argument(name = "id") int illustId,
@Argument(name = "quality", force = false) PixivDownload.PageQuality quality,
@ -463,27 +454,20 @@ public class BotCommandProcess {
try {
if (isNoSafe(illustId, globalProp, false)) {
log.warn("作品 {} 存在R-18内容且设置\"image.allowR18\"为false将屏蔽该作品不发送.", illustId);
pageIndex = -1;
return "(根据设置,该作品已被屏蔽!)";
}
} catch (IOException e) {
log.warn("作品信息无法获取!", e);
return "发生网络异常,无法获取图片!";
}
int index = 0;
String targetLink = null;
File targetFile;
File currentImageFile;
for (String link : pagesList) {
index++;
log.trace("PagesIndex: {}, Link: {}", index, link);
if (index == pageIndex) {
targetLink = link;
}
currentImageFile = new File(getImageStoreDir(), link.substring(link.lastIndexOf("/") + 1));
log.debug("检查图片文件是否已缓存...");
if (!imageCache.containsKey(link)) {
HttpHead headRequest = new HttpHead(link);
String downloadLink = pagesList.get(pageIndex - 1);
String fileName = URLs.getResourceName(Strings.nullToEmpty(downloadLink));
File imageFile = new File(getImageStoreDir(), downloadLink.substring(downloadLink.lastIndexOf("/") + 1));
log.debug("FileName: {}, DownloadLink: {}", fileName, downloadLink);
if(!imageCache.containsKey(fileName)) {
if(imageFile.exists()) {
HttpHead headRequest = new HttpHead(downloadLink);
headRequest.addHeader("Referer", PixivURL.getPixivRefererLink(illustId));
HttpResponse headResponse;
try {
@ -493,49 +477,35 @@ public class BotCommandProcess {
return "图片获取失败!";
}
String contentLengthStr = headResponse.getFirstHeader(HttpHeaderNames.CONTENT_LENGTH.toString()).getValue();
if (currentImageFile.exists() && currentImageFile.length() == Long.parseLong(contentLengthStr)) {
imageCache.put(link, currentImageFile);
log.debug("作品Id {} 第 {} 页缓存已补充.", illustId, index);
continue;
log.debug("图片大小: {}B", contentLengthStr);
if (imageFile.length() == Long.parseLong(contentLengthStr)) {
imageCache.put(URLs.getResourceName(downloadLink), imageFile);
log.debug("作品Id {} 第 {} 页缓存已补充.", illustId, pageIndex);
return getImageToBotCode(imageFile, false).toString();
}
}
ImageCacheObject imageCacheObject = new ImageCacheObject(imageCache, illustId, link, currentImageFile);
log.trace("向 ImageCacheExecutor发出下载事件: \n{}", imageCacheObject);
if (index == pageIndex) {
ImageCacheObject taskObject = new ImageCacheObject(imageCache, illustId, downloadLink, imageFile);
try {
//TODO: 这里可以尝试改成直接提交所有所需的图片给这里然后再获取结果
imageCacheExecutor.executorSync(imageCacheObject);
log.debug("下载事件发出完成(Sync)");
imageCacheExecutor.executorSync(taskObject);
} catch (InterruptedException e) {
log.warn("图片下载遭到中断!", e);
log.error("等待图片下载时发生中断", e);
return "图片获取失败!";
}
} else if(globalProp.getProperty("image.downloadAllPages", "false")
.equalsIgnoreCase("true")) {
imageCacheExecutor.executor(imageCacheObject);
log.debug("下载事件发出完成(A-Sync)");
}
}
}
if (pageIndex == -1) {
return "(根据设置,该作品已被屏蔽!)";
}
if (targetLink == null) {
return "未找到对应的图片!";
}
targetFile = imageCache.get(targetLink);
if (targetFile == null) {
return "未找到对应的图片!";
} else {
log.debug("图片 {} 缓存命中.", fileName);
}
return getImageToBotCode(imageCache.get(fileName), false).toString();
}
private static BotCode getImageToBotCode(File targetFile, boolean updateCache) {
String fileName = targetFile.getName();
BotCode code = BotCode.parse(CQCode.image(getImageStoreDir().getName() + "/" + fileName));
code.addParameter("absolutePath", targetFile.getAbsolutePath());
code.addParameter("imageName", fileName.substring(0, fileName.lastIndexOf(".")));
code.addParameter("updateCache", "false");
return code.toString();
}
code.addParameter("updateCache", updateCache ? "true" : "false");
return code;
}
static void clearCache() {

View File

@ -0,0 +1,82 @@
package net.lamgc.cgj.bot.sort;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.lamgc.cgj.bot.BotCommandProcess;
import java.io.IOException;
import java.util.Comparator;
/**
* 收藏数比较器
*/
public class PreLoadDataComparator implements Comparator<JsonElement> {
private final Attribute attribute;
public PreLoadDataComparator(Attribute attribute) {
this.attribute = attribute;
}
@Override
public int compare(JsonElement o1, JsonElement o2) {
if(!o1.getAsJsonObject().has("illustId") || !o2.getAsJsonObject().has("illustId")) {
if(o1.getAsJsonObject().has("illustId")) {
return 1;
} else if(o2.getAsJsonObject().has("illustId")) {
return -1;
} else {
return 0;
}
}
try {
JsonObject illustPreLoadData1 = BotCommandProcess.getIllustPreLoadData(o1.getAsJsonObject().get("illustId").getAsInt(), false);
JsonObject illustPreLoadData2 = BotCommandProcess.getIllustPreLoadData(o2.getAsJsonObject().get("illustId").getAsInt(), false);
return Integer.compare(illustPreLoadData2.get(attribute.attrName).getAsInt(), illustPreLoadData1.get(attribute.attrName).getAsInt());
} catch (IOException e) {
e.printStackTrace();
return 0;
}
}
public enum Attribute {
/**
* 按点赞数排序
*/
LIKE("likeCount"),
/**
* 按页面数排序
*/
PAGE("pageCount"),
/**
* 按收藏数排序
*/
BOOKMARK("bookmarkCount"),
/**
* 按评论数排序
*/
COMMENT("commentCount"),
/**
* 不明
*/
RESPONSE("responseCount"),
/**
* 按查看次数排序
*/
VIEW("viewCount"),
;
final String attrName;
Attribute(String attrName) {
this.attrName = attrName;
}
}
}