Compare commits

...

9 Commits

Author SHA1 Message Date
951824cbe2 [Version] 更新版本(2.5.2-20200610.4-SNAPSHOT -> 2.5.2-20200611.1-SNAPSHOT); 2020-06-11 16:47:35 +08:00
e104abedeb [Add] MiraiMain 增加原始消息事件日志信息; 2020-06-11 16:46:32 +08:00
c3967d214d [Change] Dockerfile.sample 提升镜像使用的Jdk版本(8-jre -> 14 jdk), 增加Arthas诊断工具, 优化构建指令顺序; 2020-06-11 10:57:40 +08:00
26e377a2c7 [Change] log4j2.xml 调整日志输出到文件的限制;
[Change] 将内容较长的日志设为TRACE级别, 以减少日志占用;
[CLear] 整理代码;
2020-06-11 09:49:19 +08:00
87f2535b48 [Change] BotCommandProcess 优化Tag过滤表达式;
[Change] ImageCacheHandler 调整日志输出级别;
2020-06-11 09:08:58 +08:00
97d06c4fc3 [Change] CacheStoreCentral 调整代码以为后续更改做准备;
[Change] BotCommandProcess, ImageCacheHandler, PreLoadDataComparator, RandomRankingArtworksSender 适配CacheStoreCentral的更改;
2020-06-10 20:21:23 +08:00
bfe25c2012 [Version] 更新版本(2.5.2-20200610.3-SNAPSHOT -> 2.5.2-20200610.4-SNAPSHOT); 2020-06-10 16:39:01 +08:00
036f3eaf4a [Delete] simple.properties 删除弃用的Properties模板文件; 2020-06-10 16:27:13 +08:00
f07c8d0b76 [Add] MiraiMain 增加Bot网络重连相关设置; 2020-06-10 16:26:20 +08:00
18 changed files with 139 additions and 108 deletions

View File

@ -1,10 +1,10 @@
FROM openjdk:8u252-jre
FROM openjdk:14
COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas
ENV jarFileName=ContentGrabbingJi-exec.jar
ENV CGJ_REDIS_URI="127.0.0.1:6379"
ENV CGJ_PROXY=""
RUN mkdir /data/
CMD [java, "-Dcgj.logsPath=/data/logs", "-jar", "/CGJ.jar", "botMode", "-botDataDir=/data"]
COPY ${jarFileName} /CGJ.jar
CMD ["java", "-Dcgj.logsPath=/data/logs", "-jar", "/CGJ.jar", "botMode", "-botDataDir=/data"]

View File

@ -6,7 +6,7 @@
<groupId>net.lamgc</groupId>
<artifactId>ContentGrabbingJi</artifactId>
<version>2.5.2-20200610.3-SNAPSHOT</version>
<version>2.5.2-20200611.1-SNAPSHOT</version>
<licenses>
<license>

View File

@ -64,7 +64,7 @@ public class BotCode {
private String platformName;
private String functionName;
private Hashtable<String, String> parameter = new Hashtable<>();
private final Hashtable<String, String> parameter = new Hashtable<>();
/**
* 构造一个机器功能码

View File

@ -23,6 +23,7 @@ import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
@SuppressWarnings({"SameParameterValue"})
public class BotCommandProcess {
@ -100,7 +101,7 @@ public class BotCommandProcess {
return "阅览禁止:该作品已被封印!!";
}
JsonObject illustPreLoadData = CacheStoreCentral.getIllustPreLoadData(illustId, false);
JsonObject illustPreLoadData = CacheStoreCentral.getCentral().getIllustPreLoadData(illustId, false);
// 在 Java 6 开始, 编译器会将用'+'进行的字符串拼接将自动转换成StringBuilder拼接
return "色图姬帮你了解了这个作品的信息!\n" + "---------------- 作品信息 ----------------" +
"\n作品Id: " + illustId +
@ -114,7 +115,7 @@ public class BotCommandProcess {
"\n页数" + illustPreLoadData.get(PreLoadDataComparator.Attribute.PAGE.attrName).getAsInt() + "" +
"\n作品链接" + artworksLink(fromGroup, illustId) + "\n" +
"---------------- 作品图片 ----------------\n" +
CacheStoreCentral.getImageById(fromGroup, illustId, PageQuality.REGULAR, 1) + "\n" +
CacheStoreCentral.getCentral().getImageById(fromGroup, illustId, PageQuality.REGULAR, 1) + "\n" +
"使用 \".cgj image -id " +
illustId +
"\" 获取原图。\n如有不当作品可使用\".cgj report -id " +
@ -209,7 +210,7 @@ public class BotCommandProcess {
log.warn("配置项 {} 的参数值格式有误!", imageLimitPropertyKey);
}
List<JsonObject> rankingInfoList = CacheStoreCentral
List<JsonObject> rankingInfoList = CacheStoreCentral.getCentral()
.getRankingInfoByCache(type, mode, queryDate, 1, Math.max(0, itemLimit), false);
if(rankingInfoList.isEmpty()) {
return "无法查询排行榜,可能排行榜尚未更新。";
@ -228,7 +229,7 @@ public class BotCommandProcess {
.append(pagesCount).append("p.\n");
if (index <= imageLimit) {
resultBuilder
.append(CacheStoreCentral
.append(CacheStoreCentral.getCentral()
.getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1))
.append("\n");
}
@ -312,7 +313,7 @@ public class BotCommandProcess {
@Argument(name = "page", force = false, defaultValue = "1") int pagesIndex
) throws IOException {
log.info("正在执行搜索...");
JsonObject resultBody = CacheStoreCentral
JsonObject resultBody = CacheStoreCentral.getCentral()
.getSearchBody(content, type, area, includeKeywords, excludeKeywords, contentOption);
StringBuilder result = new StringBuilder("内容 " + content + " 的搜索结果:\n");
@ -365,8 +366,8 @@ public class BotCommandProcess {
PixivURL.getPixivRefererLink(illustId)
);
String imageMsg =
CacheStoreCentral.getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1);
String imageMsg = CacheStoreCentral.getCentral()
.getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1);
if (isNoSafe(illustId, SettingProperties.getProperties(fromGroup), false)) {
log.warn("作品Id {} 为R-18作品, 跳过.", illustId);
continue;
@ -375,7 +376,8 @@ public class BotCommandProcess {
continue;
}
JsonObject illustPreLoadData = CacheStoreCentral.getIllustPreLoadData(illustId, false);
JsonObject illustPreLoadData = CacheStoreCentral.getCentral()
.getIllustPreLoadData(illustId, false);
result.append(searchArea.name()).append(" (").append(count).append(" / ")
.append(limit).append(")\n\t作品id: ").append(illustId)
.append(", \n\t作者名: ").append(illustObj.get("userName").getAsString())
@ -463,7 +465,7 @@ public class BotCommandProcess {
static void clearCache() {
log.warn("正在清除所有缓存...");
CacheStoreCentral.clearCache();
CacheStoreCentral.getCentral().clearCache();
File imageStoreDir = new File(BotGlobal.getGlobal().getDataStoreDir(), "data/image/cgj/");
File[] listFiles = imageStoreDir.listFiles();
if (listFiles == null) {
@ -484,7 +486,7 @@ public class BotCommandProcess {
@Argument(name = "quality", force = false) PixivDownload.PageQuality quality,
@Argument(name = "page", force = false, defaultValue = "1") int pageIndex
) {
return CacheStoreCentral.getImageById(fromGroup, illustId, quality, pageIndex);
return CacheStoreCentral.getCentral().getImageById(fromGroup, illustId, quality, pageIndex);
}
/**
@ -521,6 +523,10 @@ public class BotCommandProcess {
return reportStore.exists(String.valueOf(illustId));
}
/**
* Tag过滤表达式
*/
private final static Pattern tagPattern = Pattern.compile(".*R-*18.*");
/**
* 检查指定作品是否为r18
* @param illustId 作品Id
@ -532,12 +538,12 @@ public class BotCommandProcess {
*/
public static boolean isNoSafe(int illustId, Properties settingProp, boolean returnRaw)
throws IOException, NoSuchElementException {
JsonObject illustInfo = CacheStoreCentral.getIllustInfo(illustId, false);
JsonObject illustInfo = CacheStoreCentral.getCentral().getIllustInfo(illustId, false);
JsonArray tags = illustInfo.getAsJsonArray("tags");
boolean rawValue = illustInfo.get("xRestrict").getAsInt() != 0;
if(!rawValue) {
for(JsonElement tag : tags) {
boolean current = tag.getAsString().matches("R-*18") || tag.getAsString().contains("R18");
boolean current = tagPattern.matcher(tag.getAsString()).matches();
if (current) {
rawValue = true;
break;

View File

@ -92,7 +92,7 @@ public class RandomRankingArtworksSender extends AutoSender {
int selectRanking = rankingStart + new Random().nextInt(rankingStop - rankingStart + 1);
try {
List<JsonObject> rankingList = CacheStoreCentral.getRankingInfoByCache(
List<JsonObject> rankingList = CacheStoreCentral.getCentral().getRankingInfoByCache(
contentType,
mode,
queryDate,
@ -119,7 +119,7 @@ public class RandomRankingArtworksSender extends AutoSender {
String message = "#美图推送 - 今日排行榜 第 " + rankingInfo.get("rank").getAsInt() + "\n" +
"标题:" + rankingInfo.get("title").getAsString() + "(" + illustId + ")\n" +
"作者:" + rankingInfo.get("user_name").getAsString() + "\n" +
CacheStoreCentral.getImageById(0, illustId, quality, 1) +
CacheStoreCentral.getCentral().getImageById(0, illustId, quality, 1) +
"\n如有不当作品可使用\".cgj report -id " + illustId + "\"向色图姬反馈。";
getMessageSender().sendMessage(message);
} catch (Exception e) {

View File

@ -31,27 +31,44 @@ import java.util.concurrent.atomic.AtomicInteger;
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
public final class CacheStoreCentral {
private CacheStoreCentral() {}
private final static Logger log = LoggerFactory.getLogger(CacheStoreCentral.class);
private final static Hashtable<String, File> imageCache = new Hashtable<>();
private static CacheStoreCentral central = new CacheStoreCentral();
private final static JsonRedisCacheStore imageChecksumCache =
public static CacheStoreCentral getCentral() {
if(central == null) {
initialCentral();
}
return central;
}
private synchronized static void initialCentral() {
if(central != null) {
return;
}
central = new CacheStoreCentral();
}
private CacheStoreCentral() {}
private final Hashtable<String, File> imageCache = new Hashtable<>();
private final CacheStore<JsonElement> imageChecksumCache =
new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(),
"imageChecksum", BotGlobal.getGlobal().getGson());
/**
* 作品信息缓存 - 不过期
*/
private final static CacheStore<JsonElement> illustInfoCache =
private final CacheStore<JsonElement> illustInfoCache =
new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(),
"illustInfo", BotGlobal.getGlobal().getGson());
/**
* 作品信息预加载数据 - 有效期 2 小时, 本地缓存有效期1 ± 0.25
*/
private final static CacheStore<JsonElement> illustPreLoadDataCache =
private final CacheStore<JsonElement> illustPreLoadDataCache =
CacheStoreUtils.hashLocalHotDataStore(
new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(),
"illustPreLoadData", BotGlobal.getGlobal().getGson()),
@ -59,27 +76,27 @@ public final class CacheStoreCentral {
/**
* 搜索内容缓存, 有效期 2 小时
*/
private final static CacheStore<JsonElement> searchBodyCache =
private final CacheStore<JsonElement> searchBodyCache =
new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(),
"searchBody", BotGlobal.getGlobal().getGson());
/**
* 排行榜缓存, 不过期
*/
private final static CacheStore<List<JsonObject>> rankingCache =
private final CacheStore<List<JsonObject>> rankingCache =
new JsonObjectRedisListCacheStore(BotGlobal.getGlobal().getRedisServer(),
"ranking", BotGlobal.getGlobal().getGson());
/**
* 作品页面下载链接缓存 - 不过期
*/
private final static CacheStore<List<String>> pagesCache =
private final CacheStore<List<String>> pagesCache =
new StringListRedisCacheStore(BotGlobal.getGlobal().getRedisServer(), "imagePages");
/**
* 清空所有缓存
*/
public static void clearCache() {
public void clearCache() {
imageCache.clear();
illustInfoCache.clear();
illustPreLoadDataCache.clear();
@ -96,7 +113,7 @@ public final class CacheStoreCentral {
* @param pageIndex 指定页面索引, 从1开始
* @return 如果成功, 返回BotCode, 否则返回错误信息.
*/
public static String getImageById(long fromGroup, int illustId, PixivDownload.PageQuality quality, int pageIndex) {
public String getImageById(long fromGroup, int illustId, PixivDownload.PageQuality quality, int pageIndex) {
log.debug("IllustId: {}, Quality: {}, PageIndex: {}", illustId, quality.name(), pageIndex);
if(pageIndex <= 0) {
log.warn("指定的页数不能小于或等于0: {}", pageIndex);
@ -118,7 +135,7 @@ public final class CacheStoreCentral {
List<String> pagesList;
try {
pagesList = CacheStoreCentral.getIllustPages(illustId, quality, false);
pagesList = getIllustPages(illustId, quality, false);
} catch (IOException e) {
log.error("获取下载链接列表时发生异常", e);
return "发生网络异常,无法获取图片!";
@ -147,10 +164,10 @@ public final class CacheStoreCentral {
ImageChecksum imageChecksum = getImageChecksum(illustId, pageIndex);
if(imageChecksum != null) {
try {
log.debug("正在检查作品Id {} 第 {} 页图片文件 {} ...", illustId, pageIndex, imageFile.getName());
log.trace("正在检查作品Id {} 第 {} 页图片文件 {} ...", illustId, pageIndex, imageFile.getName());
if (ImageChecksum.checkFile(imageChecksum, Files.readAllBytes(imageFile.toPath()))) {
imageCache.put(URLs.getResourceName(downloadLink), imageFile);
log.debug("作品Id {} 第 {} 页缓存已补充.", illustId, pageIndex);
log.trace("作品Id {} 第 {} 页缓存已补充.", illustId, pageIndex);
return getImageToBotCode(imageFile, false).toString();
} else {
log.warn("图片文件 {} 校验失败, 重新下载图片...", imageFile.getName());
@ -177,7 +194,7 @@ public final class CacheStoreCentral {
return "(错误: 图片获取出错)";
}
} else {
log.debug("图片 {} 缓存命中.", fileName);
log.trace("图片 {} 缓存命中.", fileName);
}
return getImageToBotCode(imageCache.get(fileName), false).toString();
@ -190,7 +207,7 @@ public final class CacheStoreCentral {
* @return 返回设定好参数的BotCode
*/
@SuppressWarnings("SameParameterValue")
private static BotCode getImageToBotCode(File targetFile, boolean updateCache) {
private BotCode getImageToBotCode(File targetFile, boolean updateCache) {
String fileName = Objects.requireNonNull(targetFile, "targetFile is null").getName();
BotCode code = BotCode.parse(
CQCode.image(BotGlobal.getGlobal().getImageStoreDir().getName() + "/" + fileName));
@ -208,7 +225,7 @@ public final class CacheStoreCentral {
* @throws IOException 当Http请求发生异常时抛出
* @throws NoSuchElementException 当作品未找到时抛出
*/
public static JsonObject getIllustInfo(int illustId, boolean flushCache)
public JsonObject getIllustInfo(int illustId, boolean flushCache)
throws IOException, NoSuchElementException {
String illustIdStr = buildSyncKey(Integer.toString(illustId));
JsonObject illustInfoObj = null;
@ -223,7 +240,7 @@ public final class CacheStoreCentral {
if(Objects.isNull(illustInfoObj)) {
illustInfoObj = illustInfoCache.getCache(illustIdStr).getAsJsonObject();
log.debug("作品Id {} IllustInfo缓存命中.", illustId);
log.trace("作品Id {} IllustInfo缓存命中.", illustId);
}
return illustInfoObj;
}
@ -236,13 +253,13 @@ public final class CacheStoreCentral {
* @return 成功返回JsonObject对象
* @throws IOException 当Http请求处理发生异常时抛出
*/
public static JsonObject getIllustPreLoadData(int illustId, boolean flushCache) throws IOException {
public JsonObject getIllustPreLoadData(int illustId, boolean flushCache) throws IOException {
String illustIdStr = buildSyncKey(Integer.toString(illustId));
JsonObject result = null;
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
synchronized (illustIdStr) {
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
log.debug("IllustId {} 缓存失效, 正在更新...", illustId);
log.trace("IllustId {} 缓存失效, 正在更新...", illustId);
JsonObject preLoadDataObj = BotGlobal.getGlobal().getPixivDownload()
.getIllustPreLoadDataById(illustId)
.getAsJsonObject("illust")
@ -260,19 +277,19 @@ public final class CacheStoreCentral {
result = preLoadDataObj;
illustPreLoadDataCache.update(illustIdStr, preLoadDataObj, expire);
log.debug("作品Id {} preLoadData缓存已更新(有效时间: {})", illustId, expire);
log.trace("作品Id {} preLoadData缓存已更新(有效时间: {})", illustId, expire);
}
}
}
if(Objects.isNull(result)) {
result = illustPreLoadDataCache.getCache(illustIdStr).getAsJsonObject();
log.debug("作品Id {} PreLoadData缓存命中.", illustId);
log.trace("作品Id {} PreLoadData缓存命中.", illustId);
}
return result;
}
public static List<String> getIllustPages(int illustId, PixivDownload.PageQuality quality, boolean flushCache)
public List<String> getIllustPages(int illustId, PixivDownload.PageQuality quality, boolean flushCache)
throws IOException {
String pagesSign = buildSyncKey(Integer.toString(illustId), ".", quality.name());
List<String> result = null;
@ -290,12 +307,12 @@ public final class CacheStoreCentral {
if(Objects.isNull(result)) {
result = pagesCache.getCache(pagesSign);
log.debug("作品Id {} Pages缓存命中.", illustId);
log.trace("作品Id {} Pages缓存命中.", illustId);
}
return result;
}
private final static Random expireTimeFloatRandom = new Random();
private final Random expireTimeFloatRandom = new Random();
/**
* 获取排行榜
* @param contentType 排行榜类型
@ -307,7 +324,7 @@ public final class CacheStoreCentral {
* @return 成功返回有值List, 失败且无异常返回空
* @throws IOException 获取异常时抛出
*/
public static List<JsonObject> getRankingInfoByCache(PixivURL.RankingContentType contentType,
public List<JsonObject> getRankingInfoByCache(PixivURL.RankingContentType contentType,
PixivURL.RankingMode mode,
Date queryDate, int start, int range, boolean flushCache)
throws IOException {
@ -329,7 +346,7 @@ public final class CacheStoreCentral {
if(!rankingCache.exists(requestSign) || flushCache) {
synchronized(requestSign) {
if(!rankingCache.exists(requestSign) || flushCache) {
log.debug("Ranking缓存失效, 正在更新...(RequestSign: {})", requestSign);
log.trace("Ranking缓存失效, 正在更新...(RequestSign: {})", requestSign);
List<JsonObject> rankingResult = BotGlobal.getGlobal().getPixivDownload()
.getRanking(contentType, mode, queryDate, 1, 500);
long expireTime = 0;
@ -339,16 +356,15 @@ public final class CacheStoreCentral {
}
result = new ArrayList<>(rankingResult).subList(start - 1, start + range - 1);
rankingCache.update(requestSign, rankingResult, expireTime);
log.debug("Ranking缓存更新完成.(RequestSign: {})", requestSign);
log.trace("Ranking缓存更新完成.(RequestSign: {})", requestSign);
}
}
}
if (Objects.isNull(result)) {
result = rankingCache.getCache(requestSign, start - 1, range);
log.debug("RequestSign [{}] 缓存命中.", requestSign);
log.trace("RequestSign [{}] 缓存命中.", requestSign);
}
log.debug("Result-Length: {}", result.size());
return PixivDownload.getRanking(result, start - 1, range);
}
@ -363,7 +379,7 @@ public final class CacheStoreCentral {
* @return 返回完整搜索结果
* @throws IOException 当请求发生异常, 或接口返回异常信息时抛出.
*/
public static JsonObject getSearchBody(
public JsonObject getSearchBody(
String content,
String type,
String area,
@ -397,14 +413,14 @@ public final class CacheStoreCentral {
for (String keyword : includeKeywords.split(";")) {
searchBuilder.removeExcludeKeyword(keyword.trim());
searchBuilder.addIncludeKeyword(keyword.trim());
log.debug("已添加关键字: {}", keyword);
log.trace("已添加关键字: {}", keyword);
}
}
if (!Strings.isNullOrEmpty(excludeKeywords)) {
for (String keyword : excludeKeywords.split(";")) {
searchBuilder.removeIncludeKeyword(keyword.trim());
searchBuilder.addExcludeKeyword(keyword.trim());
log.debug("已添加排除关键字: {}", keyword);
log.trace("已添加排除关键字: {}", keyword);
}
}
@ -416,7 +432,7 @@ public final class CacheStoreCentral {
if(!searchBodyCache.exists(requestUrl)) {
synchronized (requestUrl) {
if (!searchBodyCache.exists(requestUrl)) {
log.debug("searchBody缓存失效, 正在更新...");
log.trace("searchBody缓存失效, 正在更新...");
JsonObject jsonObject;
HttpGet httpGetRequest = BotGlobal.getGlobal().getPixivDownload().
createHttpGetRequest(requestUrl);
@ -424,7 +440,7 @@ public final class CacheStoreCentral {
getHttpClient().execute(httpGetRequest);
String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
log.debug("ResponseBody: {}", responseBody);
log.trace("ResponseBody: {}", responseBody);
jsonObject = BotGlobal.getGlobal().getGson().fromJson(responseBody, JsonObject.class);
if (jsonObject.get("error").getAsBoolean()) {
@ -442,13 +458,13 @@ public final class CacheStoreCentral {
}
resultBody = jsonObject.getAsJsonObject().getAsJsonObject("body");
searchBodyCache.update(requestUrl, jsonObject, expire);
log.debug("searchBody缓存已更新(有效时间: {})", expire);
log.trace("searchBody缓存已更新(有效时间: {})", expire);
} else {
log.debug("搜索缓存命中.");
log.trace("搜索缓存命中.");
}
}
} else {
log.debug("搜索缓存命中.");
log.trace("搜索缓存命中.");
}
if(Objects.isNull(resultBody)) {
@ -457,7 +473,7 @@ public final class CacheStoreCentral {
return resultBody;
}
protected static ImageChecksum getImageChecksum(int illustId, int pageIndex) {
protected ImageChecksum getImageChecksum(int illustId, int pageIndex) {
String cacheKey = illustId + ":" + pageIndex;
if(!imageChecksumCache.exists(cacheKey)) {
return null;
@ -466,7 +482,7 @@ public final class CacheStoreCentral {
}
}
protected static void setImageChecksum(ImageChecksum checksum) {
protected void setImageChecksum(ImageChecksum checksum) {
String cacheKey = checksum.getIllustId() + ":" + checksum.getPage();
imageChecksumCache.update(cacheKey, ImageChecksum.toJsonObject(checksum), 0);
}

View File

@ -38,7 +38,7 @@ public class ImageCacheHandler implements EventHandler {
}
try {
log.info("图片 {} Event正在进行...({})", event.getStoreFile().getName(), Integer.toHexString(event.hashCode()));
log.debug("图片 {} Event正在进行...({})", event.getStoreFile().getName(), Integer.toHexString(event.hashCode()));
File storeFile = event.getStoreFile();
log.debug("正在缓存图片 {} (Path: {})", storeFile.getName(), storeFile.getAbsolutePath());
try {
@ -66,7 +66,7 @@ public class ImageCacheHandler implements EventHandler {
throw requestException;
}
log.debug("正在下载...(Content-Length: {}KB)", response.getEntity().getContentLength() / 1024);
log.trace("正在下载...(Content-Length: {}KB)", response.getEntity().getContentLength() / 1024);
ByteArrayOutputStream bufferOutputStream = new ByteArrayOutputStream();
try(FileOutputStream fileOutputStream = new FileOutputStream(storeFile)) {
Streams.copy(response.getEntity().getContent(), bufferOutputStream, false);
@ -80,14 +80,14 @@ public class ImageCacheHandler implements EventHandler {
);
bufferInputStream.reset();
Streams.copy(bufferInputStream, fileOutputStream, false);
CacheStoreCentral.setImageChecksum(imageChecksum);
CacheStoreCentral.getCentral().setImageChecksum(imageChecksum);
} catch (IOException e) {
log.error("下载图片时发生异常", e);
throw e;
}
event.getImageCache().put(URLs.getResourceName(event.getDownloadLink()), storeFile);
} finally {
log.info("图片 {} Event结束({})", event.getStoreFile().getName(), Integer.toHexString(event.hashCode()));
log.debug("图片 {} Event结束({})", event.getStoreFile().getName(), Integer.toHexString(event.hashCode()));
cacheQueue.remove(event);
}
}

View File

@ -149,7 +149,7 @@ public class LocalHashCacheStore<T> implements CacheStore<T>, Cleanable {
}
@Override
public void clean() throws Exception {
public void clean() {
Date currentDate = new Date();
cache.forEach((key, value) -> {
if(value.isExpire(currentDate)) {
@ -160,8 +160,8 @@ public class LocalHashCacheStore<T> implements CacheStore<T>, Cleanable {
public static class CacheObject<T> implements Comparable<CacheObject<T>> {
private AtomicReference<T> value;
private AtomicReference<Date> expire;
private final AtomicReference<T> value;
private final AtomicReference<Date> expire;
public CacheObject(T value, Date expire) {
this.value = new AtomicReference<>(value);

View File

@ -105,8 +105,6 @@ public class BotEventHandler implements EventHandler {
runnerConfig.addStringParameterParser(new DateParser(new SimpleDateFormat("yyyy-MM-dd")));
runnerConfig.addStringParameterParser(new PagesQualityParser());
log.debug("DateParser添加情况: {}", runnerConfig.hasStringParameterParser(Date.class));
processRunner = new ArgumentsRunner(BotCommandProcess.class, runnerConfig);
adminRunner = new ArgumentsRunner(BotAdminCommandProcess.class, runnerConfig);

View File

@ -6,9 +6,9 @@ import net.lz1998.cq.robot.CoolQ;
public class SpringCQMessageSender implements MessageSender {
private CoolQ coolQ;
private MessageSource source;
private long target;
private final CoolQ coolQ;
private final MessageSource source;
private final long target;
public SpringCQMessageSender(CoolQ coolQ, MessageSource source, long target) {
this.coolQ = coolQ;

View File

@ -53,6 +53,20 @@ public class MiraiMain implements Closeable {
BotConfiguration configuration = new BotConfiguration();
configuration.randomDeviceInfo();
configuration.setProtocol(BotConfiguration.MiraiProtocol.ANDROID_PAD);
// 心跳包周期间隔 (ms)
configuration.setHeartbeatPeriodMillis(
Long.parseLong(botProperties.getProperty("network.heartbeatPeriodMillis", "60000")));
// 心跳包超时时间 (ms)
configuration.setHeartbeatTimeoutMillis(
Long.parseLong(botProperties.getProperty("network.heartbeatTimeoutMillis", "5000")));
// 重连间隔时间
configuration.setReconnectPeriodMillis(
Integer.parseInt(botProperties.getProperty("network.reconnectPeriodMillis", "5")));
// 重连最大次数
configuration.setReconnectionRetryTimes(
Integer.parseInt(botProperties.getProperty("network.reconnectionRetryTimes", "10")));
bot = BotFactoryJvm.newBot(Long.parseLong(botProperties.getProperty("bot.qq", "0")),
Base64.getDecoder().decode(botProperties.getProperty("bot.password", "")), configuration);
Events.subscribeAlways(GroupMessageEvent.class, this::executeMessageEvent);
@ -73,6 +87,7 @@ public class MiraiMain implements Closeable {
* @param message 消息事件对象
*/
private void executeMessageEvent(MessageEvent message) {
log.debug("Mirai Message: {}", message);
if(message instanceof GroupMessageEvent) {
GroupMessageEvent GroupMessageEvent = (GroupMessageEvent) message;
if(BotEventHandler.isMute(GroupMessageEvent.getGroup().getId(), true) == null) {

View File

@ -151,7 +151,7 @@ public class MiraiMessageSender implements MessageSender {
synchronized (imageName) {
if(!imageIdCache.exists(imageName) ||
Strings.nullToEmpty(code.getParameter("updateCache")) .equalsIgnoreCase("true")) {
log.debug("imageName [{}] 缓存失效或强制更新, 正在更新缓存...", imageName);
log.trace("imageName [{}] 缓存失效或强制更新, 正在更新缓存...", imageName);
image = uploadImage0(new File(absolutePath));
String cacheExpireAt;
long expireTime = 864000000; // 10d
@ -163,13 +163,13 @@ public class MiraiMessageSender implements MessageSender {
}
}
imageIdCache.update(imageName, image.getImageId(), expireTime);
log.debug("imageName [{}] 缓存更新完成.(有效时间: {})", imageName, expireTime);
log.trace("imageName [{}] 缓存更新完成.(有效时间: {})", imageName, expireTime);
} else {
log.debug("ImageName: [{}] 缓存命中.", imageName);
log.trace("ImageName: [{}] 缓存命中.", imageName);
}
}
} else {
log.debug("ImageName: [{}] 缓存命中.", imageName);
log.trace("ImageName: [{}] 缓存命中.", imageName);
}
if(image == null) {

View File

@ -39,10 +39,10 @@ public class PreLoadDataComparator implements Comparator<JsonElement> {
}
}
try {
JsonObject illustPreLoadData1 =
CacheStoreCentral.getIllustPreLoadData(o1.getAsJsonObject().get("illustId").getAsInt(), false);
JsonObject illustPreLoadData2 =
CacheStoreCentral.getIllustPreLoadData(o2.getAsJsonObject().get("illustId").getAsInt(), false);
JsonObject illustPreLoadData1 = CacheStoreCentral.getCentral()
.getIllustPreLoadData(o1.getAsJsonObject().get("illustId").getAsInt(), false);
JsonObject illustPreLoadData2 = CacheStoreCentral.getCentral()
.getIllustPreLoadData(o2.getAsJsonObject().get("illustId").getAsInt(), false);
return Integer.compare(
illustPreLoadData2.get(attribute.attrName).getAsInt(),
illustPreLoadData1.get(attribute.attrName).getAsInt());

View File

@ -31,6 +31,7 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
@SuppressWarnings("ALL")
public class PixivDownload {
private final static Logger log = LoggerFactory.getLogger(PixivDownload.class);
@ -115,10 +116,10 @@ public class PixivDownload {
}
}
} while(!document.select(".pager-container>.next").isEmpty());
log.debug("获取完成.");
log.trace("获取完成.");
AtomicInteger count = new AtomicInteger(1);
linkList.forEach(link -> {
log.debug("Next Link [{}]: {}", count.getAndIncrement(), link);
log.trace("Next Link [{}]: {}", count.getAndIncrement(), link);
InputStream imageInputStream = null;
int tryCount = 0;
do {
@ -133,9 +134,9 @@ public class PixivDownload {
} while(imageInputStream == null);
try(InputStream imageInput = new BufferedInputStream(imageInputStream, 256 * 1024)) {
log.debug("调用回调方法...");
log.trace("调用回调方法...");
fn.accept(link, imageInput);
log.debug("回调方法调用完成.");
log.trace("回调方法调用完成.");
} catch (IOException e) {
log.error("图片获取失败", e);
}
@ -219,8 +220,8 @@ public class PixivDownload {
int authorId = rankInfo.get("user_id").getAsInt();
String authorName = rankInfo.get("user_name").getAsString();
String title = rankInfo.get("title").getAsString();
log.debug("当前到第 {}/{} 名(总共 {} 名), IllustID: {}, Author: ({}) {}, Title: {}", rank, rankStart + range - 1, range, illustId, authorId, authorName, title);
log.debug("正在获取PagesLink...");
log.trace("当前到第 {}/{} 名(总共 {} 名), IllustID: {}, Author: ({}) {}, Title: {}", rank, rankStart + range - 1, range, illustId, authorId, authorName, title);
log.trace("正在获取PagesLink...");
List<String> linkList;
try {
linkList = getIllustAllPageDownload(httpClient, this.cookieStore, illustId, quality);
@ -235,14 +236,14 @@ public class PixivDownload {
log.debug("PagesLink 获取完成, 总数: {}", linkList.size());
for (int pageIndex = 0; pageIndex < linkList.size(); pageIndex++) {
String downloadLink = linkList.get(pageIndex);
log.debug("当前Page: {}/{}", pageIndex + 1, linkList.size());
log.trace("当前Page: {}/{}", pageIndex + 1, linkList.size());
try(InputStream imageInputStream = new BufferedInputStream(getImageAsInputStream(HttpClientBuilder.create().build(), downloadLink), 256 * 1024)) {
fn.download(rank, downloadLink, rankInfo.deepCopy(), imageInputStream);
} catch(IOException e) {
log.error("下载插画时发生异常", e);
return;
}
log.debug("完成.");
log.trace("完成.");
}
});
}
@ -265,7 +266,7 @@ public class PixivDownload {
int authorId = rankInfo.get("user_id").getAsInt();
String authorName = rankInfo.get("user_name").getAsString();
String title = rankInfo.get("title").getAsString();
log.debug("Array-当前到第 {}/{} 名(总共 {} 名), IllustID: {}, Author: ({}) {}, Title: {}", rank, rankStart + range, range, illustId, authorId, authorName, title);
log.trace("Array-当前到第 {}/{} 名(总共 {} 名), IllustID: {}, Author: ({}) {}, Title: {}", rank, rankStart + range, range, illustId, authorId, authorName, title);
results.add(rankInfo);
}
log.debug("JsonArray读取完成.");
@ -320,10 +321,10 @@ public class PixivDownload {
boolean canNext = true;
for (int pageIndex = startPages; canNext && pageIndex <= endPages && count < range; pageIndex++) {
HttpGet request = createHttpGetRequest(PixivURL.getRankingLink(contentType, mode, time, pageIndex, true));
log.debug("RequestUri: {}", request.getURI());
log.trace("RequestUri: {}", request.getURI());
HttpResponse response = httpClient.execute(request);
String responseBody = EntityUtils.toString(response.getEntity());
log.debug("ResponseBody: {}", responseBody);
log.trace("ResponseBody: {}", responseBody);
if(response.getStatusLine().getStatusCode() != 200) {
throw new IOException("Http Response Error: '" + response.getStatusLine() + "', ResponseBody: '" + responseBody + '\'');
}
@ -399,7 +400,7 @@ public class PixivDownload {
if(resultObject.get("error").getAsBoolean()) {
String message = resultObject.get("message").getAsString();
log.debug("请求错误, 错误信息: {}", message);
log.warn("作品页面接口请求错误, 错误信息: {}", message);
throw new IOException(message);
}
@ -473,9 +474,11 @@ public class PixivDownload {
request.addHeader(HttpHeaderNames.REFERER.toString(), referer);
HttpResponse response = httpClient.execute(request);
log.debug("response: {}", response);
log.debug("Content Length: {}KB", Float.parseFloat(response.getFirstHeader(HttpHeaderNames.CONTENT_LENGTH.toString()).getValue()) / 1024F);
log.debug("{}", response.getFirstHeader(HttpHeaderNames.CONTENT_TYPE.toString()));
log.trace("response: {}", response);
log.trace("Content Length: {}KB",
Float.parseFloat(response.getFirstHeader(HttpHeaderNames.CONTENT_LENGTH.toString()).getValue()) / 1024F
);
log.trace(response.getFirstHeader(HttpHeaderNames.CONTENT_TYPE.toString()).toString());
return response.getEntity().getContent();
}
@ -548,7 +551,7 @@ public class PixivDownload {
HttpGet request = createHttpGetRequest(PixivURL.getPixivIllustInfoAPI(illustId));
HttpResponse response = httpClient.execute(request);
String responseStr = EntityUtils.toString(response.getEntity());
log.debug("Response Content: {}", responseStr);
log.trace("Response Content: {}", responseStr);
JsonObject responseObj = new Gson().fromJson(responseStr, JsonObject.class);
if(responseObj.get("error").getAsBoolean()) {

View File

@ -46,7 +46,7 @@ public final class PixivUgoiraBuilder {
log.debug("Request Url: {}", request.getURI());
HttpResponse response = httpClient.execute(request);
String bodyStr = EntityUtils.toString(response.getEntity());
log.debug("JsonBodyStr: {}", bodyStr);
log.trace("JsonBodyStr: {}", bodyStr);
JsonObject resultObject = new Gson().fromJson(bodyStr, JsonObject.class);
if(resultObject.get("error").getAsBoolean()) {
String message = resultObject.get("message").getAsString();
@ -173,10 +173,10 @@ public final class PixivUgoiraBuilder {
private void getUgoiraImageSize() throws IOException {
log.debug("正在从Pixiv获取动图尺寸...");
HttpGet request = new HttpGet(PixivURL.getPixivIllustInfoAPI(illustId));
log.debug("Request Url: {}", request.getURI());
log.trace("Request Url: {}", request.getURI());
HttpResponse response = httpClient.execute(request);
String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
log.debug("ResponseBody: {}", responseBody);
log.trace("ResponseBody: {}", responseBody);
JsonObject resultObject = new Gson().fromJson(responseBody, JsonObject.class);
if(resultObject.get("error").getAsBoolean()) {
String message = resultObject.get("message").getAsString();

View File

@ -34,6 +34,9 @@
</Console>
<RollingFile name="rollingFile" fileName="${logsDir}/latest.log" filePattern="${logsDir}/running.%-d{yyyy-MM-dd_HH-mm-ss}.log.gz">
<Filters>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout charset="${charset}">
<MarkerPatternSelector defaultPattern="${standard_pattern}">
<PatternMatch key="mirai" pattern="${mirai_pattern}" />

View File

@ -1,9 +0,0 @@
#用于访问Pixiv的代理服务器
reptile.proxy.type=socks5/socks4/http
reptile.proxy.host=127.0.0.1
reptile.proxy.port=1080
reptile.proxy.username=
reptile.proxy.password=
#登录用代理, 需要让浏览器使用该代理, 访问Pixiv并登录
login.proxy.host=127.0.0.1
login.proxy.port=1080

View File

@ -8,7 +8,6 @@ public class PixivSearchBuilderTest {
@Test
public void buildTest() {
PixivSearchBuilder builder = new PixivSearchBuilder("hololive");
//builder.addExcludeKeyword("fubuki").addExcludeKeyword("minato");
builder.addIncludeKeyword("35").addIncludeKeyword("okayu").addIncludeKeyword("百鬼あやめ");
System.out.println(builder.buildURL());
}