mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-07-03 05:47:26 +00:00
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
e8fda3214b | |||
fba6d3532c | |||
0075446412 | |||
2388cd419e | |||
7f83b16118 | |||
10cad32efa | |||
22a113ef38 | |||
6824b12e8f | |||
1c556c5b94 | |||
dbc9f4c90b | |||
d3c1975722 | |||
c09b750fe6 | |||
ca479ef1af | |||
c2c49d2355 | |||
22e74e8cd5 | |||
d549c5674d | |||
c6952de84c | |||
410d6c0828 | |||
aaa1bc932b | |||
a1e54e70d9 | |||
16522155e1 | |||
5f796f7da0 | |||
5a52dd9208 | |||
b53aafa81b |
8
Dockerfile.sample
Normal file
8
Dockerfile.sample
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
FROM openjdk:8u252-jre
|
||||||
|
|
||||||
|
ENV jarFileName=ContentGrabbingJi-exec.jar
|
||||||
|
COPY ${jarFileName} /program/CGJ.jar
|
||||||
|
RUN mkdir /program/data
|
||||||
|
|
||||||
|
WORKDIR /program/data
|
||||||
|
CMD java -jar /program/CGJ.jar botMode
|
18
pom.xml
18
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>net.lamgc</groupId>
|
<groupId>net.lamgc</groupId>
|
||||||
<artifactId>ContentGrabbingJi</artifactId>
|
<artifactId>ContentGrabbingJi</artifactId>
|
||||||
<version>2.2.0</version>
|
<version>2.4.0</version>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
@ -19,7 +19,7 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
<mirai.CoreVersion>0.32.0</mirai.CoreVersion>
|
<mirai.CoreVersion>0.39.4</mirai.CoreVersion>
|
||||||
<mirai.JaptVersion>1.1.1</mirai.JaptVersion>
|
<mirai.JaptVersion>1.1.1</mirai.JaptVersion>
|
||||||
<kotlin.version>1.3.71</kotlin.version>
|
<kotlin.version>1.3.71</kotlin.version>
|
||||||
<ktor.version>1.3.2</ktor.version>
|
<ktor.version>1.3.2</ktor.version>
|
||||||
@ -36,6 +36,16 @@
|
|||||||
<target>8</target>
|
<target>8</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>log4j2-test.xml</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
@ -141,12 +151,12 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.mamoe</groupId>
|
<groupId>net.mamoe</groupId>
|
||||||
<artifactId>mirai-core-jvm</artifactId>
|
<artifactId>mirai-core</artifactId>
|
||||||
<version>${mirai.CoreVersion}</version>
|
<version>${mirai.CoreVersion}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.mamoe</groupId>
|
<groupId>net.mamoe</groupId>
|
||||||
<artifactId>mirai-core-qqandroid-jvm</artifactId>
|
<artifactId>mirai-core-qqandroid</artifactId>
|
||||||
<version>${mirai.CoreVersion}</version>
|
<version>${mirai.CoreVersion}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -7,10 +7,11 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.lamgc.cgj.bot.CQConfig;
|
import net.lamgc.cgj.bot.framework.coolq.CQConfig;
|
||||||
import net.lamgc.cgj.bot.MiraiMain;
|
import net.lamgc.cgj.bot.framework.mirai.MiraiMain;
|
||||||
import net.lamgc.cgj.pixiv.*;
|
import net.lamgc.cgj.pixiv.PixivDownload;
|
||||||
import net.lamgc.cgj.proxy.PixivAccessProxyServer;
|
import net.lamgc.cgj.pixiv.PixivSearchBuilder;
|
||||||
|
import net.lamgc.cgj.pixiv.PixivURL;
|
||||||
import net.lamgc.plps.PixivLoginProxyServer;
|
import net.lamgc.plps.PixivLoginProxyServer;
|
||||||
import net.lamgc.utils.base.ArgumentsProperties;
|
import net.lamgc.utils.base.ArgumentsProperties;
|
||||||
import net.lamgc.utils.base.runner.Argument;
|
import net.lamgc.utils.base.runner.Argument;
|
||||||
@ -20,9 +21,7 @@ import org.apache.commons.io.IOUtils;
|
|||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.CookieStore;
|
import org.apache.http.client.CookieStore;
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.message.BasicHeader;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -52,6 +51,8 @@ public class Main {
|
|||||||
public static HttpHost proxy;
|
public static HttpHost proxy;
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||||
|
log.trace("ContentGrabbingJi 正在启动...");
|
||||||
|
log.debug("运行目录: {}", System.getProperty("user.dir"));
|
||||||
ArgumentsProperties argsProp = new ArgumentsProperties(args);
|
ArgumentsProperties argsProp = new ArgumentsProperties(args);
|
||||||
if(argsProp.containsKey("proxy")) {
|
if(argsProp.containsKey("proxy")) {
|
||||||
URL proxyUrl = new URL(argsProp.getValue("proxy"));
|
URL proxyUrl = new URL(argsProp.getValue("proxy"));
|
||||||
@ -353,86 +354,16 @@ public class Main {
|
|||||||
builder,
|
builder,
|
||||||
PixivURL.getPixivRefererLink(illustId)
|
PixivURL.getPixivRefererLink(illustId)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*log.info("正在下载...");
|
|
||||||
List<String> list = PixivDownload.getIllustAllPageDownload(
|
|
||||||
HttpClientBuilder.create()
|
|
||||||
.setProxy(proxy)
|
|
||||||
.build(),
|
|
||||||
illustId, PixivDownload.PageQuality.ORIGINAL);*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
|
|
||||||
if(searchBuilder.getSearchArea().equals(PixivSearchBuilder.SearchArea.TOP)) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
JsonArray illustsArray = resultBody
|
|
||||||
.getAsJsonObject(searchBuilder.getSearchArea().jsonKey).getAsJsonArray("data");
|
|
||||||
log.info("已找到与 {} 相关插图信息:", content);
|
|
||||||
int count = 1;
|
|
||||||
for (JsonElement jsonElement : illustsArray) {
|
|
||||||
JsonObject illustObj = jsonElement.getAsJsonObject();
|
|
||||||
//TODO: 防止数据内混入无效内容, 需要检查对象是否有illustId
|
|
||||||
if(!illustObj.has("illustId")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int illustId = illustObj.get("illustId").getAsInt();
|
|
||||||
StringBuilder builder = new StringBuilder("[");
|
|
||||||
illustObj.get("tags").getAsJsonArray().forEach(el -> builder.append(el.getAsString()).append(", "));
|
|
||||||
builder.replace(builder.length() - 2, builder.length(), "]");
|
|
||||||
log.info("({} / {})\n\t作品id: {}, \n\t作者名(作者id): {} ({}), \n\t作品标题: {}, \n\t作品Tags: {}, \n\t作品链接: {}",
|
|
||||||
count++,
|
|
||||||
illustsArray.size(),
|
|
||||||
illustId,
|
|
||||||
illustObj.get("userName").getAsString(),
|
|
||||||
illustObj.get("userId").getAsInt(),
|
|
||||||
illustObj.get("illustTitle").getAsString(),
|
|
||||||
builder,
|
|
||||||
PixivURL.getPixivRefererLink(illustId)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Command(defaultCommand = true)
|
@Command(defaultCommand = true)
|
||||||
public static void testRun() {
|
public static void testRun() {
|
||||||
/*loadCookieStoreFromFile();
|
|
||||||
|
|
||||||
if(cookieStore == null){
|
|
||||||
startPixivLoginProxyServer();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//accessPixivToFile();
|
|
||||||
|
|
||||||
//startPixivAccessProxyServer();
|
|
||||||
|
|
||||||
//saveCookieStoreToFile();
|
|
||||||
log.info("这里啥都没有哟w");
|
log.info("这里啥都没有哟w");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadCookieStoreFromFile() throws IOException {
|
|
||||||
log.info("正在加载CookieStore...");
|
|
||||||
File storeFile = new File("./cookies.store");
|
|
||||||
if(!storeFile.exists()){
|
|
||||||
log.info("未找到CookieStore, 跳过加载.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ObjectInputStream stream = new ObjectInputStream(new FileInputStream(storeFile));
|
|
||||||
Object result;
|
|
||||||
try {
|
|
||||||
result = stream.readObject();
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
log.error("加载出错", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cookieStore = (CookieStore) result;
|
|
||||||
cookieStore.getCookies().forEach(cookie -> log.debug(cookie.getName() + ": " + cookie.getValue() + ", isExpired: " + cookie.isExpired(new Date())));
|
|
||||||
log.info("CookieStore加载完成.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void saveCookieStoreToFile() throws IOException {
|
private static void saveCookieStoreToFile() throws IOException {
|
||||||
log.info("正在保存CookieStore...");
|
log.info("正在保存CookieStore...");
|
||||||
File outputFile = new File("./cookies.store");
|
File outputFile = new File("./cookies.store");
|
||||||
@ -482,75 +413,4 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void accessPixivToFile() throws IOException {
|
|
||||||
File cookieStoreFile = new File("./cookie.txt");
|
|
||||||
if (!cookieStoreFile.exists() && !cookieStoreFile.createNewFile()) {
|
|
||||||
log.info("Cookie文件存储失败");
|
|
||||||
}
|
|
||||||
/*log.info("正在写出Cookie, Cookie count: " + cookieStore.getCookies().size());
|
|
||||||
FileWriter cookieWriter = new FileWriter(cookieStoreFile);
|
|
||||||
cookieStore.getCookies().forEach(cookie -> {
|
|
||||||
try {
|
|
||||||
StringBuilder sb = new StringBuilder().append(cookie.getName()).append(" = ").append(cookie.getValue());
|
|
||||||
log.info("正在导出Cookie: " + sb.toString());
|
|
||||||
cookieWriter.append(sb.toString()).append("\n").flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
log.info("Cookie写出完成");*/
|
|
||||||
|
|
||||||
log.info("尝试通过捕获的Cookie访问Pixiv...");
|
|
||||||
HttpClient httpClient = new PixivSession(new HttpHost("127.0.0.1", 1080), cookieStore).getHttpClient();
|
|
||||||
HttpGet request = new HttpGet("https://www.pixiv.net");
|
|
||||||
request.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0");
|
|
||||||
request.addHeader(new BasicHeader("accept-encoding", "gzip, deflate, br"));
|
|
||||||
request.addHeader(new BasicHeader("accept-language", "zh-CN,zh;q=0.9"));
|
|
||||||
StringBuilder cookieBuilder = new StringBuilder();
|
|
||||||
cookieStore.getCookies().forEach(cookie -> {
|
|
||||||
if(cookie.isExpired(new Date())){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cookieBuilder.append(cookie.getName()).append("=").append(cookie.getValue()).append("; ");
|
|
||||||
});
|
|
||||||
request.addHeader("cookie", cookieBuilder.toString());
|
|
||||||
|
|
||||||
HttpResponse response = httpClient.execute(request);
|
|
||||||
log.info("正在写入文件...");
|
|
||||||
File outFile = new File("./pixiv.html");
|
|
||||||
if (outFile.createNewFile() && !outFile.exists()) {
|
|
||||||
log.info("文件创建失败!");
|
|
||||||
}else {
|
|
||||||
new FileWriter(outFile).append(EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8)).flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pixiv pixiv = new Pixiv(httpClient);
|
|
||||||
pixiv.getRecommend().forEach(illustMap -> {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
illustMap.forEach((key, value) -> builder.append(key).append(": ").append(value).append("\n"));
|
|
||||||
try {
|
|
||||||
builder.append("download Link: ").append(Arrays.toString(pixiv.getAllDownloadLink(Integer.parseInt(illustMap.get(Pixiv.ATTR_ILLUST_ID)))));
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("获取下载链接时出错!", e);
|
|
||||||
}
|
|
||||||
log.info(builder.append("\n").toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void startPixivAccessProxyServer(){
|
|
||||||
log.info("正在启动访问代理服务器, 将浏览器相关缓存清空后, 使用浏览器进行访问以尝试Cookie正确性.");
|
|
||||||
final PixivAccessProxyServer accessProxyServer = new PixivAccessProxyServer(cookieStore, new ProxyConfig(ProxyType.SOCKS5, "127.0.0.1", 1080));
|
|
||||||
Thread accessProxyServerThread = new Thread(() -> {
|
|
||||||
log.info("正在启动PAPS...");
|
|
||||||
accessProxyServer.start(1007);
|
|
||||||
log.info("PAPS已关闭.");
|
|
||||||
});
|
|
||||||
accessProxyServerThread.setName("AccessProxyServerThread");
|
|
||||||
accessProxyServerThread.start();
|
|
||||||
new Scanner(System.in).nextLine();
|
|
||||||
log.info("关闭PAPS服务器...");
|
|
||||||
accessProxyServer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import com.google.gson.reflect.TypeToken;
|
|||||||
import net.lamgc.cgj.bot.message.MessageSenderBuilder;
|
import net.lamgc.cgj.bot.message.MessageSenderBuilder;
|
||||||
import net.lamgc.cgj.bot.message.MessageSource;
|
import net.lamgc.cgj.bot.message.MessageSource;
|
||||||
import net.lamgc.cgj.pixiv.PixivDownload;
|
import net.lamgc.cgj.pixiv.PixivDownload;
|
||||||
|
import net.lamgc.cgj.pixiv.PixivURL;
|
||||||
import net.lamgc.utils.base.runner.Argument;
|
import net.lamgc.utils.base.runner.Argument;
|
||||||
import net.lamgc.utils.base.runner.Command;
|
import net.lamgc.utils.base.runner.Command;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -104,29 +105,46 @@ public class BotAdminCommandProcess {
|
|||||||
return "操作已完成.";
|
return "操作已完成.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static String RANKING_SETTING_TIME_MIN = "time.min";
|
||||||
|
private final static String RANKING_SETTING_TIME_FLOAT = "time.float";
|
||||||
|
private final static String RANKING_SETTING_RANKING_START = "ranking.start";
|
||||||
|
private final static String RANKING_SETTING_RANKING_END = "ranking.end";
|
||||||
|
private final static String RANKING_SETTING_RANKING_MODE = "ranking.mode";
|
||||||
|
private final static String RANKING_SETTING_RANKING_CONTENT_TYPE = "ranking.contentType";
|
||||||
|
private final static String RANKING_SETTING_PAGE_QUALITY = "page.quality";
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
public static String addPushGroup(@Argument(name = "group") long groupId,
|
public static String addPushGroup(
|
||||||
@Argument(name = "minTime", force = false, defaultValue = "21600000") long minTime,
|
@Argument(name = "$fromGroup") long fromGroup,
|
||||||
@Argument(name = "floatTime", force = false, defaultValue = "10800000") int floatTime,
|
@Argument(name = "group", force = false, defaultValue = "0") long groupId,
|
||||||
@Argument(name = "rankingStart", force = false, defaultValue = "1") int rankingStart,
|
@Argument(name = "minTime", force = false, defaultValue = "21600000") long minTime,
|
||||||
@Argument(name = "rankingStop", force = false, defaultValue = "150") int rankingStop,
|
@Argument(name = "floatTime", force = false, defaultValue = "10800000") int floatTime,
|
||||||
@Argument(name = "original", force = false, defaultValue = "false") boolean original
|
@Argument(name = "rankingStart", force = false, defaultValue = "1") int rankingStart,
|
||||||
|
@Argument(name = "rankingStop", force = false, defaultValue = "150") int rankingStop,
|
||||||
|
@Argument(name = "mode", force = false, defaultValue = "DAILY") String rankingMode,
|
||||||
|
@Argument(name = "type", force = false, defaultValue = "ILLUST") String rankingContentType,
|
||||||
|
@Argument(name = "original", force = false, defaultValue = "false") boolean original
|
||||||
) {
|
) {
|
||||||
|
long group = groupId <= 0 ? fromGroup : groupId;
|
||||||
JsonObject setting = new JsonObject();
|
JsonObject setting = new JsonObject();
|
||||||
setting.addProperty("time.min", minTime);
|
setting.addProperty(RANKING_SETTING_TIME_MIN, minTime);
|
||||||
setting.addProperty("time.float", floatTime);
|
setting.addProperty(RANKING_SETTING_TIME_FLOAT, floatTime);
|
||||||
setting.addProperty("ranking.start", rankingStart);
|
setting.addProperty(RANKING_SETTING_RANKING_START, rankingStart);
|
||||||
setting.addProperty("ranking.end", rankingStop);
|
setting.addProperty(RANKING_SETTING_RANKING_END, rankingStop);
|
||||||
setting.addProperty("pageQuality.original", original);
|
setting.addProperty(RANKING_SETTING_RANKING_MODE, rankingMode);
|
||||||
if(pushInfoMap.containsKey(groupId)) {
|
setting.addProperty(RANKING_SETTING_RANKING_CONTENT_TYPE, rankingContentType);
|
||||||
log.info("群 {} 已存在Timer, 删除Timer...", groupId);
|
setting.addProperty(RANKING_SETTING_PAGE_QUALITY, original ?
|
||||||
removePushGroup(groupId);
|
PixivDownload.PageQuality.ORIGINAL.name() :
|
||||||
|
PixivDownload.PageQuality.REGULAR.name());
|
||||||
|
if(pushInfoMap.containsKey(group)) {
|
||||||
|
log.info("群 {} 已存在Timer, 删除Timer...", group);
|
||||||
|
removePushGroup(fromGroup, groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("正在增加Timer...(Setting: {})", setting);
|
log.info("正在增加Timer...(Setting: {})", setting);
|
||||||
pushInfoMap.put(groupId, setting);
|
pushInfoMap.put(group, setting);
|
||||||
addPushTimer(groupId, setting);
|
addPushTimer(group, setting);
|
||||||
return "已在 " + groupId + " 开启定时推送功能。";
|
return "已在 " + group + " 开启定时推送功能。";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,14 +188,24 @@ public class BotAdminCommandProcess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载所有推送Timer
|
||||||
|
* @param flush 是否完全重载, 如为true则加载前会删除所有已加载的Timer
|
||||||
|
*/
|
||||||
public static void loadAllPushTimer(boolean flush) {
|
public static void loadAllPushTimer(boolean flush) {
|
||||||
if(flush) {
|
if(flush) {
|
||||||
RandomIntervalSendTimer.timerIdSet().forEach(id -> RandomIntervalSendTimer.getTimerById(id).destroy());
|
RandomIntervalSendTimer.timerIdSet().forEach(id -> RandomIntervalSendTimer.getTimerById(id).destroy());
|
||||||
|
} else {
|
||||||
|
cleanPushTimer();
|
||||||
}
|
}
|
||||||
cleanPushTimer();
|
|
||||||
pushInfoMap.forEach(BotAdminCommandProcess::addPushTimer);
|
pushInfoMap.forEach(BotAdminCommandProcess::addPushTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据设置增加Timer
|
||||||
|
* @param id 群组id
|
||||||
|
* @param setting jsonObject设置集
|
||||||
|
*/
|
||||||
private static void addPushTimer(long id, JsonObject setting) {
|
private static void addPushTimer(long id, JsonObject setting) {
|
||||||
try {
|
try {
|
||||||
RandomIntervalSendTimer.getTimerById(id);
|
RandomIntervalSendTimer.getTimerById(id);
|
||||||
@ -185,19 +213,65 @@ public class BotAdminCommandProcess {
|
|||||||
} catch(NoSuchElementException ignored) {
|
} catch(NoSuchElementException ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rankingStart = setting.has(RANKING_SETTING_RANKING_START) ? setting.get(RANKING_SETTING_RANKING_START).getAsInt() : 1;
|
||||||
|
int rankingEnd = setting.has(RANKING_SETTING_RANKING_END) ? setting.get(RANKING_SETTING_RANKING_END).getAsInt() : 150;
|
||||||
|
PixivURL.RankingMode rankingMode = PixivURL.RankingMode.MODE_DAILY;
|
||||||
|
PixivURL.RankingContentType rankingContentType = PixivURL.RankingContentType.TYPE_ILLUST;
|
||||||
|
PixivDownload.PageQuality pageQuality = PixivDownload.PageQuality.REGULAR;
|
||||||
|
|
||||||
|
if(rankingStart <= 0 || rankingStart > 500) {
|
||||||
|
log.warn("群组 [{}] - 无效的RankingStart设定值, 将重置为默认设定值(1): {}", id, rankingStart);
|
||||||
|
rankingStart = 1;
|
||||||
|
} else if(rankingEnd > 500 || rankingEnd <= 0) {
|
||||||
|
log.warn("群组 [{}] - 无效的RankingEnd设定值, 将重置为默认设定值(150): {}", id, rankingEnd);
|
||||||
|
rankingEnd = 150;
|
||||||
|
} else if(rankingStart > rankingEnd) {
|
||||||
|
log.warn("群组 [{}] - 无效的排行榜选取范围, 将重置为默认设定值(1 ~ 150): start={}, end={}", id, rankingStart, rankingEnd);
|
||||||
|
rankingStart = 1;
|
||||||
|
rankingEnd = 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setting.has(RANKING_SETTING_RANKING_MODE)) {
|
||||||
|
String value = setting.get(RANKING_SETTING_RANKING_MODE).getAsString().trim().toUpperCase();
|
||||||
|
try {
|
||||||
|
rankingMode = PixivURL.RankingMode.valueOf(value.startsWith("MODE_") ? value : "MODE_" + value);
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
log.warn("群组ID [{}] - 无效的RankingMode设定值, 将重置为默认值: {}", id, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(setting.has(RANKING_SETTING_RANKING_CONTENT_TYPE)) {
|
||||||
|
String value = setting.get(RANKING_SETTING_RANKING_CONTENT_TYPE).getAsString().trim().toUpperCase();
|
||||||
|
try {
|
||||||
|
rankingContentType = PixivURL.RankingContentType.valueOf(value.startsWith("TYPE_") ? value : "TYPE_" + value);
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
log.warn("群组ID [{}] - 无效的RankingContentType设定值: {}", id, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setting.has(RANKING_SETTING_PAGE_QUALITY)) {
|
||||||
|
String value = setting.get(RANKING_SETTING_PAGE_QUALITY).getAsString().trim().toUpperCase();
|
||||||
|
try {
|
||||||
|
pageQuality = PixivDownload.PageQuality.valueOf(value);
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
log.warn("群组ID [{}] - 无效的PageQuality设定值: {}", id, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AutoSender sender = new RandomRankingArtworksSender(
|
AutoSender sender = new RandomRankingArtworksSender(
|
||||||
MessageSenderBuilder.getMessageSender(MessageSource.Group, id),
|
MessageSenderBuilder.getMessageSender(MessageSource.Group, id),
|
||||||
setting.get("ranking.start").getAsInt(),
|
rankingStart,
|
||||||
setting.get("ranking.end").getAsInt(),
|
rankingEnd,
|
||||||
setting.get("pageQuality.original").getAsBoolean() ? PixivDownload.PageQuality.ORIGINAL : PixivDownload.PageQuality.REGULAR
|
rankingMode, rankingContentType,
|
||||||
|
pageQuality
|
||||||
);
|
);
|
||||||
|
|
||||||
RandomIntervalSendTimer.createTimer(
|
RandomIntervalSendTimer timer = RandomIntervalSendTimer.createTimer(
|
||||||
id,
|
id,
|
||||||
sender,
|
sender,
|
||||||
setting.get("time.min").getAsLong(),
|
setting.get("time.min").getAsLong(),
|
||||||
setting.get("time.float").getAsInt(),
|
setting.get("time.float").getAsInt(),
|
||||||
true, true);
|
true, true);
|
||||||
|
log.info("群组 {} 已创建对应Timer: {}", id, Integer.toHexString(timer.hashCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,10 +280,11 @@ public class BotAdminCommandProcess {
|
|||||||
* @throws NoSuchElementException 当这个群号没有定时器的时候抛出异常
|
* @throws NoSuchElementException 当这个群号没有定时器的时候抛出异常
|
||||||
*/
|
*/
|
||||||
@Command
|
@Command
|
||||||
public static String removePushGroup(@Argument(name = "group") long id) {
|
public static String removePushGroup(@Argument(name = "$fromGroup") long fromGroup, @Argument(name = "group", force = false) long id) {
|
||||||
RandomIntervalSendTimer.getTimerById(id).destroy();
|
long group = id <= 0 ? fromGroup : id;
|
||||||
pushInfoMap.remove(id);
|
RandomIntervalSendTimer.getTimerById(group).destroy();
|
||||||
return "已关闭群 " + id + " 的美图推送功能。";
|
pushInfoMap.remove(group);
|
||||||
|
return "已关闭群 " + group + " 的美图推送功能。";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,14 +304,17 @@ public class BotAdminCommandProcess {
|
|||||||
Set<String> keys = BotCommandProcess.reportStore.keys();
|
Set<String> keys = BotCommandProcess.reportStore.keys();
|
||||||
StringBuilder msgBuilder = new StringBuilder();
|
StringBuilder msgBuilder = new StringBuilder();
|
||||||
msgBuilder.append("当前被报告的作品列表:\n");
|
msgBuilder.append("当前被报告的作品列表:\n");
|
||||||
|
int count = 1;
|
||||||
for(String key : keys) {
|
for(String key : keys) {
|
||||||
String illustIdStr = key.substring(key.indexOf(".") + 1);
|
String illustIdStr = key.substring(key.indexOf(".") + 1);
|
||||||
JsonObject report = BotCommandProcess.reportStore.getCache(illustIdStr).getAsJsonObject();
|
JsonObject report = BotCommandProcess.reportStore.getCache(illustIdStr).getAsJsonObject();
|
||||||
log.debug("{} - Report: {}", illustIdStr, report);
|
log.debug("{} - Report: {}", illustIdStr, report);
|
||||||
String reason = report.get("reason").isJsonNull() ? "" : report.get("reason").getAsString();
|
String reason = report.get("reason").isJsonNull() ? "" : report.get("reason").getAsString();
|
||||||
msgBuilder.append(illustIdStr)
|
msgBuilder.append(count).append(". 作品Id: ").append(illustIdStr)
|
||||||
.append("(").append(dateFormat.format(new Date(report.get("reportTime").getAsLong()))).append("):")
|
.append("(").append(dateFormat.format(new Date(report.get("reportTime").getAsLong()))).append("):\n")
|
||||||
.append(reason).append("\n");
|
.append("报告者QQ:").append(report.get("fromQQ").getAsLong()).append("\n")
|
||||||
|
.append("报告所在群:").append(report.get("fromGroup").getAsLong()).append("\n")
|
||||||
|
.append("报告原因:\n").append(reason).append("\n");
|
||||||
}
|
}
|
||||||
return msgBuilder.toString();
|
return msgBuilder.toString();
|
||||||
}
|
}
|
||||||
|
@ -113,13 +113,31 @@ public class BotCommandProcess {
|
|||||||
public static String help() {
|
public static String help() {
|
||||||
StringBuilder helpStrBuilder = new StringBuilder();
|
StringBuilder helpStrBuilder = new StringBuilder();
|
||||||
helpStrBuilder.append("CGJ Bot使用指南").append("\n");
|
helpStrBuilder.append("CGJ Bot使用指南").append("\n");
|
||||||
|
helpStrBuilder.append("使用方法:.cgj <命令> [参数...]").append("\n");
|
||||||
|
helpStrBuilder.append("例如查询作品信息功能:").append("\n");
|
||||||
|
helpStrBuilder.append(".cgj artwork -id 80846159").append("\n");
|
||||||
helpStrBuilder.append("目前可用的命令:").append("\n");
|
helpStrBuilder.append("目前可用的命令:").append("\n");
|
||||||
helpStrBuilder.append("\t").append("ranking - 获取今天或指定日期排行榜的前10名作品").append("\n");
|
helpStrBuilder.append("\t").append("ranking - 获取今天或指定日期排行榜的前10名作品").append("\n");
|
||||||
helpStrBuilder.append("\t\t").append("-date - 指定查询日期(年-月-日)").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").append("search - 搜索指定关键词并显示前10个作品").append("\n");
|
||||||
helpStrBuilder.append("\t\t").append("-content - 搜索内容").append("\n");
|
helpStrBuilder.append("\t\t").append("-content - 搜索内容").append("\n");
|
||||||
helpStrBuilder.append("\t").append("artworks - 获取作品的Pixiv页面").append("\n");
|
|
||||||
|
helpStrBuilder.append("\t").append("link - 获取作品的Pixiv页面").append("\n");
|
||||||
helpStrBuilder.append("\t\t").append("-id - 作品id").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 helpStrBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,6 +277,18 @@ public class BotCommandProcess {
|
|||||||
return "功能未完成";
|
return "功能未完成";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索命令
|
||||||
|
* @param content 搜索内容
|
||||||
|
* @param type 搜索类型
|
||||||
|
* @param area 搜索区域
|
||||||
|
* @param includeKeywords 包括关键字
|
||||||
|
* @param excludeKeywords 排除关键字
|
||||||
|
* @param contentOption 搜索选项
|
||||||
|
* @param pagesIndex 搜索页索引
|
||||||
|
* @return 返回搜索内容消息
|
||||||
|
* @throws IOException 当搜索发生异常时抛出
|
||||||
|
*/
|
||||||
@Command
|
@Command
|
||||||
public static String search(@Argument(name = "content") String content,
|
public static String search(@Argument(name = "content") String content,
|
||||||
@Argument(name = "type", force = false) String type,
|
@Argument(name = "type", force = false) String type,
|
||||||
@ -438,7 +468,7 @@ public class BotCommandProcess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(commandName = "artwork")
|
@Command(commandName = "link")
|
||||||
public static String artworksLink(@Argument(name = "id") int illustId) {
|
public static String artworksLink(@Argument(name = "id") int illustId) {
|
||||||
try {
|
try {
|
||||||
if (isNoSafe(illustId, globalProp, false)) {
|
if (isNoSafe(illustId, globalProp, false)) {
|
||||||
@ -538,6 +568,12 @@ public class BotCommandProcess {
|
|||||||
return getImageToBotCode(imageCache.get(fileName), false).toString();
|
return getImageToBotCode(imageCache.get(fileName), false).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过文件获取图片的BotCode代码
|
||||||
|
* @param targetFile 图片文件
|
||||||
|
* @param updateCache 是否刷新缓存(只是让机器人重新上传, 如果上传接口有重复检测的话是无法处理的)
|
||||||
|
* @return 返回设定好参数的BotCode
|
||||||
|
*/
|
||||||
private static BotCode getImageToBotCode(File targetFile, boolean updateCache) {
|
private static BotCode getImageToBotCode(File targetFile, boolean updateCache) {
|
||||||
String fileName = targetFile.getName();
|
String fileName = targetFile.getName();
|
||||||
BotCode code = BotCode.parse(CQCode.image(getImageStoreDir().getName() + "/" + fileName));
|
BotCode code = BotCode.parse(CQCode.image(getImageStoreDir().getName() + "/" + fileName));
|
||||||
@ -574,11 +610,13 @@ public class BotCommandProcess {
|
|||||||
* @return 返回提示信息
|
* @return 返回提示信息
|
||||||
*/
|
*/
|
||||||
@Command
|
@Command
|
||||||
public static String report(@Argument(name = "id") int illustId, @Argument(name = "msg", force = false) String reason) {
|
public static String report(@Argument(name = "$fromGroup") long fromGroup, @Argument(name = "$fromQQ") long fromQQ, @Argument(name = "id") int illustId, @Argument(name = "msg", force = false) String reason) {
|
||||||
log.warn("收到作品反馈(IllustId: {}, 原因: {})", illustId, reason);
|
log.warn("收到作品反馈(IllustId: {}, 原因: {})", illustId, reason);
|
||||||
JsonObject reportJson = new JsonObject();
|
JsonObject reportJson = new JsonObject();
|
||||||
reportJson.addProperty("illustId", illustId);
|
reportJson.addProperty("illustId", illustId);
|
||||||
reportJson.addProperty("reportTime", new Date().getTime());
|
reportJson.addProperty("reportTime", new Date().getTime());
|
||||||
|
reportJson.addProperty("fromGroup", fromGroup);
|
||||||
|
reportJson.addProperty("fromQQ", fromQQ);
|
||||||
reportJson.addProperty("reason", reason);
|
reportJson.addProperty("reason", reason);
|
||||||
reportStore.update(String.valueOf(illustId), reportJson, 0);
|
reportStore.update(String.valueOf(illustId), reportJson, 0);
|
||||||
return "色图姬收到了你的报告,将屏蔽该作品并对作品违规情况进行核实,感谢你的反馈!";
|
return "色图姬收到了你的报告,将屏蔽该作品并对作品违规情况进行核实,感谢你的反馈!";
|
||||||
@ -646,7 +684,7 @@ public class BotCommandProcess {
|
|||||||
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
|
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
|
||||||
synchronized (illustIdStr) {
|
synchronized (illustIdStr) {
|
||||||
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
|
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
|
||||||
log.info("IllustId {} 缓存失效, 正在更新...", illustId);
|
log.debug("IllustId {} 缓存失效, 正在更新...", illustId);
|
||||||
JsonObject preLoadDataObj = pixivDownload.getIllustPreLoadDataById(illustId)
|
JsonObject preLoadDataObj = pixivDownload.getIllustPreLoadDataById(illustId)
|
||||||
.getAsJsonObject("illust")
|
.getAsJsonObject("illust")
|
||||||
.getAsJsonObject(Integer.toString(illustId));
|
.getAsJsonObject(Integer.toString(illustId));
|
||||||
@ -662,7 +700,7 @@ public class BotCommandProcess {
|
|||||||
|
|
||||||
result = preLoadDataObj;
|
result = preLoadDataObj;
|
||||||
illustPreLoadDataCache.update(illustIdStr, preLoadDataObj, expire);
|
illustPreLoadDataCache.update(illustIdStr, preLoadDataObj, expire);
|
||||||
log.info("作品Id {} preLoadData缓存已更新(有效时间: {})", illustId, expire);
|
log.debug("作品Id {} preLoadData缓存已更新(有效时间: {})", illustId, expire);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -734,21 +772,22 @@ public class BotCommandProcess {
|
|||||||
if(!rankingCache.exists(requestSign) || flushCache) {
|
if(!rankingCache.exists(requestSign) || flushCache) {
|
||||||
synchronized(requestSign) {
|
synchronized(requestSign) {
|
||||||
if(!rankingCache.exists(requestSign) || flushCache) {
|
if(!rankingCache.exists(requestSign) || flushCache) {
|
||||||
log.info("Ranking缓存失效, 正在更新...(RequestSign: {})", requestSign);
|
log.debug("Ranking缓存失效, 正在更新...(RequestSign: {})", requestSign);
|
||||||
List<JsonObject> rankingResult = pixivDownload.getRanking(contentType, mode, queryDate, 1, 500);
|
List<JsonObject> rankingResult = pixivDownload.getRanking(contentType, mode, queryDate, 1, 500);
|
||||||
|
long expireTime = 0;
|
||||||
if(rankingResult.size() == 0) {
|
if(rankingResult.size() == 0) {
|
||||||
log.info("数据获取失败, 将设置浮动有效时间以准备下次更新.");
|
expireTime = 5400000 + expireTimeFloatRandom.nextInt(1800000);
|
||||||
|
log.warn("数据获取失败, 将设置浮动有效时间以准备下次更新. (ExpireTime: {}ms)", expireTime);
|
||||||
}
|
}
|
||||||
result = new ArrayList<>(rankingResult).subList(start - 1, start + range - 1);
|
result = new ArrayList<>(rankingResult).subList(start - 1, start + range - 1);
|
||||||
rankingCache.update(requestSign, rankingResult,
|
rankingCache.update(requestSign, rankingResult, expireTime);
|
||||||
rankingResult.size() == 0 ? 5400000 + expireTimeFloatRandom.nextInt(1800000) : 0);
|
log.debug("Ranking缓存更新完成.(RequestSign: {})", requestSign);
|
||||||
log.info("Ranking缓存更新完成.(RequestSign: {})", requestSign);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Objects.isNull(result)) {
|
if (Objects.isNull(result)) {
|
||||||
result = rankingCache.getCache(requestSign, start, range);
|
result = rankingCache.getCache(requestSign, start - 1, range);
|
||||||
log.debug("RequestSign [{}] 缓存命中.", requestSign);
|
log.debug("RequestSign [{}] 缓存命中.", requestSign);
|
||||||
}
|
}
|
||||||
log.debug("Result-Length: {}", result.size());
|
log.debug("Result-Length: {}", result.size());
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package net.lamgc.cgj.bot;
|
package net.lamgc.cgj.bot;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@ -89,6 +92,8 @@ public class RandomIntervalSendTimer extends TimerTask {
|
|||||||
start(this.loop.get());
|
start(this.loop.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-ss HH:mm:ss");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动定时器
|
* 启动定时器
|
||||||
* @param loop 是否循环, 如果为true, 则任务完成后会自动调用start方法继续循环, 直到被调用{@code #}或总定时器被销毁;
|
* @param loop 是否循环, 如果为true, 则任务完成后会自动调用start方法继续循环, 直到被调用{@code #}或总定时器被销毁;
|
||||||
@ -96,7 +101,9 @@ public class RandomIntervalSendTimer extends TimerTask {
|
|||||||
public void start(boolean loop) {
|
public void start(boolean loop) {
|
||||||
this.loop.set(loop);
|
this.loop.set(loop);
|
||||||
long nextDelay = time + timeRandom.nextInt(floatTime);
|
long nextDelay = time + timeRandom.nextInt(floatTime);
|
||||||
log.info("定时器 {} 下一延迟: {}ms ({}min)", Integer.toHexString(this.hashCode()), nextDelay, nextDelay / 1000F / 60F);
|
Date nextDate = new Date();
|
||||||
|
nextDate.setTime(nextDate.getTime() + nextDelay);
|
||||||
|
log.info("定时器 {} 下一延迟: {}ms ({})", Integer.toHexString(this.hashCode()), nextDelay, dateFormat.format(nextDate));
|
||||||
if(start.get()) {
|
if(start.get()) {
|
||||||
try {
|
try {
|
||||||
Field state = this.getClass().getSuperclass().getDeclaredField("state");
|
Field state = this.getClass().getSuperclass().getDeclaredField("state");
|
||||||
@ -114,7 +121,11 @@ public class RandomIntervalSendTimer extends TimerTask {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
sender.send();
|
try {
|
||||||
|
sender.send();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("定时器 {} 执行时发生异常:\n{}", Integer.toHexString(this.hashCode()), Throwables.getStackTraceAsString(e));
|
||||||
|
}
|
||||||
if (this.loop.get()) {
|
if (this.loop.get()) {
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
@ -127,6 +138,7 @@ public class RandomIntervalSendTimer extends TimerTask {
|
|||||||
@Override
|
@Override
|
||||||
public boolean cancel() {
|
public boolean cancel() {
|
||||||
start.set(false);
|
start.set(false);
|
||||||
|
loop.set(false);
|
||||||
return super.cancel();
|
return super.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,20 +21,30 @@ public class RandomRankingArtworksSender extends AutoSender {
|
|||||||
private final Logger log;
|
private final Logger log;
|
||||||
private final int rankingStart;
|
private final int rankingStart;
|
||||||
private final int rankingStop;
|
private final int rankingStop;
|
||||||
|
private final PixivURL.RankingMode mode;
|
||||||
|
private final PixivURL.RankingContentType contentType;
|
||||||
private final PixivDownload.PageQuality quality;
|
private final PixivDownload.PageQuality quality;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造一个推荐作品发送器
|
* 构造一个推荐作品发送器
|
||||||
* @param messageSender 消息发送器
|
* @param messageSender 消息发送器
|
||||||
* @param rankingStart 排行榜开始范围(从1开始, 名次)
|
* @param rankingStart 排行榜开始范围(从1开始, 名次),如传入0或负数则为默认值,默认为1
|
||||||
* @param rankingStop 排名榜结束范围(包括该名次)
|
* @param rankingStop 排名榜结束范围(包括该名次),如传入0或负数则为默认值,默认为150
|
||||||
* @param quality 图片质量, 详见{@link net.lamgc.cgj.pixiv.PixivDownload.PageQuality}
|
* @param mode 排行榜模式
|
||||||
|
* @param contentType 排行榜内容类型
|
||||||
|
* @param quality 图片质量, 详见{@link PixivDownload.PageQuality}
|
||||||
|
* @throws IndexOutOfBoundsException 当 rankingStart > rankingStop时抛出
|
||||||
*/
|
*/
|
||||||
public RandomRankingArtworksSender(MessageSender messageSender, int rankingStart, int rankingStop, PixivDownload.PageQuality quality) {
|
public RandomRankingArtworksSender(MessageSender messageSender, int rankingStart, int rankingStop, PixivURL.RankingMode mode, PixivURL.RankingContentType contentType, PixivDownload.PageQuality quality) {
|
||||||
super(messageSender);
|
super(messageSender);
|
||||||
|
this.mode = mode;
|
||||||
|
this.contentType = contentType;
|
||||||
log = LoggerFactory.getLogger("RecommendArtworksSender@" + Integer.toHexString(this.hashCode()));
|
log = LoggerFactory.getLogger("RecommendArtworksSender@" + Integer.toHexString(this.hashCode()));
|
||||||
this.rankingStart = rankingStart > 0 ? rankingStart : 1;
|
this.rankingStart = rankingStart > 0 ? rankingStart : 1;
|
||||||
this.rankingStop = rankingStop > 0 ? rankingStop : 150;
|
this.rankingStop = rankingStop > 0 ? rankingStop : 150;
|
||||||
|
if(this.rankingStart > this.rankingStop) {
|
||||||
|
throw new IndexOutOfBoundsException("rankingStart=" + this.rankingStart + ", rankingStop=" + this.rankingStop);
|
||||||
|
}
|
||||||
this.quality = quality == null ? PixivDownload.PageQuality.REGULAR : quality;
|
this.quality = quality == null ? PixivDownload.PageQuality.REGULAR : quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,16 +60,16 @@ public class RandomRankingArtworksSender extends AutoSender {
|
|||||||
}
|
}
|
||||||
queryDate = calendar.getTime();
|
queryDate = calendar.getTime();
|
||||||
|
|
||||||
int selectRanking = rankingStart + new Random().nextInt(rankingStop + 1);
|
int selectRanking = rankingStart + new Random().nextInt(rankingStop - rankingStart + 1);
|
||||||
try {
|
try {
|
||||||
List<JsonObject> rankingList = BotCommandProcess.getRankingInfoByCache(
|
List<JsonObject> rankingList = BotCommandProcess.getRankingInfoByCache(
|
||||||
PixivURL.RankingContentType.TYPE_ILLUST,
|
contentType,
|
||||||
PixivURL.RankingMode.MODE_DAILY,
|
mode,
|
||||||
queryDate,
|
queryDate,
|
||||||
selectRanking,
|
selectRanking,
|
||||||
1, false);
|
1, false);
|
||||||
|
|
||||||
log.info("RankingResult.size: {}", rankingList.size());
|
log.debug("RankingResult.size: {}", rankingList.size());
|
||||||
if(rankingList.size() != 1) {
|
if(rankingList.size() != 1) {
|
||||||
log.error("排行榜选取失败!(获取到了多个结果)");
|
log.error("排行榜选取失败!(获取到了多个结果)");
|
||||||
return;
|
return;
|
||||||
|
@ -31,7 +31,7 @@ public class RankingUpdateTimer {
|
|||||||
cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + 1);
|
cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + 1);
|
||||||
}
|
}
|
||||||
cal.set(Calendar.HOUR_OF_DAY, 12);
|
cal.set(Calendar.HOUR_OF_DAY, 12);
|
||||||
cal.set(Calendar.MINUTE, 10);
|
cal.set(Calendar.MINUTE, 30);
|
||||||
cal.set(Calendar.SECOND, 0);
|
cal.set(Calendar.SECOND, 0);
|
||||||
cal.set(Calendar.MILLISECOND, 0);
|
cal.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ public class ImageCacheHandler implements EventHandler {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public void getImageToCache(ImageCacheObject event) {
|
public void getImageToCache(ImageCacheObject event) {
|
||||||
if(cacheQueue.contains(event)) {
|
if(cacheQueue.contains(event)) {
|
||||||
log.info("图片 {} 已存在相同缓存任务, 跳过.", event.getStoreFile().getName());
|
log.debug("图片 {} 已存在相同缓存任务, 跳过.", event.getStoreFile().getName());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
cacheQueue.add(event);
|
cacheQueue.add(event);
|
||||||
@ -39,7 +39,7 @@ public class ImageCacheHandler implements EventHandler {
|
|||||||
try {
|
try {
|
||||||
log.info("图片 {} Event正在进行...({})", event.getStoreFile().getName(), Integer.toHexString(event.hashCode()));
|
log.info("图片 {} Event正在进行...({})", event.getStoreFile().getName(), Integer.toHexString(event.hashCode()));
|
||||||
File storeFile = event.getStoreFile();
|
File storeFile = event.getStoreFile();
|
||||||
log.info("正在缓存图片 {} (Path: {})", storeFile.getName(), storeFile.getAbsolutePath());
|
log.debug("正在缓存图片 {} (Path: {})", storeFile.getName(), storeFile.getAbsolutePath());
|
||||||
try {
|
try {
|
||||||
if(!storeFile.exists() && !storeFile.createNewFile()) {
|
if(!storeFile.exists() && !storeFile.createNewFile()) {
|
||||||
log.error("无法创建文件(Path: {})", storeFile.getAbsolutePath());
|
log.error("无法创建文件(Path: {})", storeFile.getAbsolutePath());
|
||||||
@ -64,7 +64,7 @@ public class ImageCacheHandler implements EventHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("正在下载...(Content-Length: {}KB)", response.getEntity().getContentLength() / 1024);
|
log.debug("正在下载...(Content-Length: {}KB)", response.getEntity().getContentLength() / 1024);
|
||||||
try(FileOutputStream fos = new FileOutputStream(storeFile)) {
|
try(FileOutputStream fos = new FileOutputStream(storeFile)) {
|
||||||
IOUtils.copy(response.getEntity().getContent(), fos);
|
IOUtils.copy(response.getEntity().getContent(), fos);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -82,9 +82,7 @@ public abstract class RedisPoolCacheStore<T> implements CacheStore<T> {
|
|||||||
@Override
|
@Override
|
||||||
public boolean clear() {
|
public boolean clear() {
|
||||||
try (Jedis jedis = jedisPool.getResource()) {
|
try (Jedis jedis = jedisPool.getResource()) {
|
||||||
String result = jedis.flushDB();
|
return jedis.flushDB().equalsIgnoreCase("ok");
|
||||||
log.info("flushDB返回结果: {}", result);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,13 +156,4 @@ public abstract class RedisPoolCacheStore<T> implements CacheStore<T> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 替换原本的分隔符(.)为(:).<br/>
|
|
||||||
* 即将启用
|
|
||||||
* @param key 要处理的键名
|
|
||||||
* @return 处理后的键名
|
|
||||||
*/
|
|
||||||
public static String replaceKey(String key) {
|
|
||||||
return key.replaceAll("\\.", ":");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,7 @@ import redis.clients.jedis.JedisPool;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -141,7 +138,7 @@ public class BotEventHandler implements EventHandler {
|
|||||||
|
|
||||||
Pattern pattern = Pattern.compile("/\\s*(\".+?\"|[^:\\s])+((\\s*:\\s*(\".+?\"|[^\\s])+)|)|(\".+?\"|[^\"\\s])+");
|
Pattern pattern = Pattern.compile("/\\s*(\".+?\"|[^:\\s])+((\\s*:\\s*(\".+?\"|[^\\s])+)|)|(\".+?\"|[^\"\\s])+");
|
||||||
Matcher matcher = pattern.matcher(Strings.nullToEmpty(msg));
|
Matcher matcher = pattern.matcher(Strings.nullToEmpty(msg));
|
||||||
ArrayList<String> argsList = new ArrayList<>();
|
List<String> argsList = new ArrayList<>();
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
String arg = matcher.group();
|
String arg = matcher.group();
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
@ -163,6 +160,12 @@ public class BotEventHandler implements EventHandler {
|
|||||||
String[] args = new String[argsList.size()];
|
String[] args = new String[argsList.size()];
|
||||||
argsList.toArray(args);
|
argsList.toArray(args);
|
||||||
log.debug("传入参数: {}", Arrays.toString(args));
|
log.debug("传入参数: {}", Arrays.toString(args));
|
||||||
|
argsList.add("-$fromGroup");
|
||||||
|
argsList.add(String.valueOf(event.getFromGroup()));
|
||||||
|
argsList.add("-$fromQQ");
|
||||||
|
argsList.add(String.valueOf(event.getFromQQ()));
|
||||||
|
args = Arrays.copyOf(args, args.length + 4);
|
||||||
|
argsList.toArray(args);
|
||||||
|
|
||||||
log.info("正在处理命令...");
|
log.info("正在处理命令...");
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
|
@ -56,7 +56,7 @@ public abstract class MessageEvent implements EventObject, MessageSender {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MessageEvent{" +
|
return this.getClass().getSimpleName() + "{" +
|
||||||
"fromGroup=" + getFromGroup() +
|
"fromGroup=" + getFromGroup() +
|
||||||
", fromQQ=" + getFromQQ() +
|
", fromQQ=" + getFromQQ() +
|
||||||
", message='" + getMessage() + '\'' +
|
", message='" + getMessage() + '\'' +
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.lamgc.cgj.bot;
|
package net.lamgc.cgj.bot.framework.coolq;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import net.lz1998.cq.CQGlobal;
|
import net.lz1998.cq.CQGlobal;
|
@ -1,7 +1,7 @@
|
|||||||
package net.lamgc.cgj.bot;
|
package net.lamgc.cgj.bot.framework.coolq;
|
||||||
|
|
||||||
import net.lamgc.cgj.bot.event.BotEventHandler;
|
import net.lamgc.cgj.bot.event.BotEventHandler;
|
||||||
import net.lamgc.cgj.bot.event.SpringCQMessageEvent;
|
import net.lamgc.cgj.bot.framework.coolq.message.SpringCQMessageEvent;
|
||||||
import net.lamgc.utils.event.EventHandler;
|
import net.lamgc.utils.event.EventHandler;
|
||||||
import net.lz1998.cq.event.message.CQDiscussMessageEvent;
|
import net.lz1998.cq.event.message.CQDiscussMessageEvent;
|
||||||
import net.lz1998.cq.event.message.CQGroupMessageEvent;
|
import net.lz1998.cq.event.message.CQGroupMessageEvent;
|
||||||
@ -24,19 +24,16 @@ public class CQPluginMain extends CQPlugin implements EventHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onPrivateMessage(CoolQ cq, CQPrivateMessageEvent event) {
|
public int onPrivateMessage(CoolQ cq, CQPrivateMessageEvent event) {
|
||||||
//log.info("私聊消息到达: 发送者[{}], 消息内容: {}", event.getSender().getUserId(), event.getMessage());
|
|
||||||
return processMessage(cq, event);
|
return processMessage(cq, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onGroupMessage(CoolQ cq, CQGroupMessageEvent event) {
|
public int onGroupMessage(CoolQ cq, CQGroupMessageEvent event) {
|
||||||
//log.info("群消息到达: 群[{}], 发送者[{}], 消息内容: {}", event.getGroupId(), event.getSender().getUserId(), event.getMessage());
|
|
||||||
return processMessage(cq, event);
|
return processMessage(cq, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onDiscussMessage(CoolQ cq, CQDiscussMessageEvent event) {
|
public int onDiscussMessage(CoolQ cq, CQDiscussMessageEvent event) {
|
||||||
//log.info("讨论组消息到达: 群[{}], 发送者[{}], 消息内容: {}", event.getDiscussId(), event.getSender().getUserId(), event.getMessage());
|
|
||||||
return processMessage(cq, event);
|
return processMessage(cq, event);
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package net.lamgc.cgj.bot.event;
|
package net.lamgc.cgj.bot.framework.coolq.message;
|
||||||
|
|
||||||
import net.lamgc.cgj.bot.BotCode;
|
import net.lamgc.cgj.bot.BotCode;
|
||||||
|
import net.lamgc.cgj.bot.event.MessageEvent;
|
||||||
import net.lamgc.cgj.bot.message.MessageSender;
|
import net.lamgc.cgj.bot.message.MessageSender;
|
||||||
import net.lamgc.cgj.bot.message.MessageSource;
|
import net.lamgc.cgj.bot.message.MessageSource;
|
||||||
import net.lamgc.cgj.bot.message.SpringCQMessageSender;
|
|
||||||
import net.lz1998.cq.event.message.CQDiscussMessageEvent;
|
import net.lz1998.cq.event.message.CQDiscussMessageEvent;
|
||||||
import net.lz1998.cq.event.message.CQGroupMessageEvent;
|
import net.lz1998.cq.event.message.CQGroupMessageEvent;
|
||||||
import net.lz1998.cq.event.message.CQMessageEvent;
|
import net.lz1998.cq.event.message.CQMessageEvent;
|
@ -1,5 +1,7 @@
|
|||||||
package net.lamgc.cgj.bot.message;
|
package net.lamgc.cgj.bot.framework.coolq.message;
|
||||||
|
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSender;
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSource;
|
||||||
import net.lz1998.cq.robot.CoolQ;
|
import net.lz1998.cq.robot.CoolQ;
|
||||||
|
|
||||||
public class SpringCQMessageSender implements MessageSender {
|
public class SpringCQMessageSender implements MessageSender {
|
@ -1,5 +1,8 @@
|
|||||||
package net.lamgc.cgj.bot.message;
|
package net.lamgc.cgj.bot.framework.coolq.message;
|
||||||
|
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSender;
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSenderFactory;
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSource;
|
||||||
import net.lz1998.cq.robot.CoolQ;
|
import net.lz1998.cq.robot.CoolQ;
|
||||||
|
|
||||||
public class SpringCQMessageSenderFactory implements MessageSenderFactory {
|
public class SpringCQMessageSenderFactory implements MessageSenderFactory {
|
@ -1,14 +1,14 @@
|
|||||||
package net.lamgc.cgj.bot;
|
package net.lamgc.cgj.bot.framework.mirai;
|
||||||
|
|
||||||
import net.lamgc.cgj.bot.event.BotEventHandler;
|
import net.lamgc.cgj.bot.event.BotEventHandler;
|
||||||
import net.lamgc.cgj.bot.event.MiraiMessageEvent;
|
import net.lamgc.cgj.bot.framework.mirai.message.MiraiMessageEvent;
|
||||||
import net.lamgc.cgj.bot.message.MessageSenderBuilder;
|
import net.lamgc.cgj.bot.message.MessageSenderBuilder;
|
||||||
import net.lamgc.cgj.bot.message.MiraiMessageSenderFactory;
|
import net.lamgc.cgj.bot.framework.mirai.message.MiraiMessageSenderFactory;
|
||||||
import net.mamoe.mirai.Bot;
|
import net.mamoe.mirai.Bot;
|
||||||
|
import net.mamoe.mirai.BotFactoryJvm;
|
||||||
import net.mamoe.mirai.japt.Events;
|
import net.mamoe.mirai.japt.Events;
|
||||||
import net.mamoe.mirai.message.FriendMessage;
|
import net.mamoe.mirai.message.FriendMessage;
|
||||||
import net.mamoe.mirai.message.GroupMessage;
|
import net.mamoe.mirai.message.GroupMessage;
|
||||||
import net.mamoe.mirai.qqandroid.QQAndroid;
|
|
||||||
import net.mamoe.mirai.utils.BotConfiguration;
|
import net.mamoe.mirai.utils.BotConfiguration;
|
||||||
import org.apache.commons.net.util.Base64;
|
import org.apache.commons.net.util.Base64;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -42,7 +42,7 @@ public class MiraiMain implements Closeable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bot = QQAndroid.INSTANCE.newBot(Long.parseLong(botProperties.getProperty("bot.qq", "0")), Base64.decodeBase64(botProperties.getProperty("bot.password", "")), new BotConfiguration());
|
bot = BotFactoryJvm.newBot(Long.parseLong(botProperties.getProperty("bot.qq", "0")), Base64.decodeBase64(botProperties.getProperty("bot.password", "")), new BotConfiguration());
|
||||||
Events.subscribeAlways(GroupMessage.class, (msg) -> BotEventHandler.executor.executor(new MiraiMessageEvent(msg)));
|
Events.subscribeAlways(GroupMessage.class, (msg) -> BotEventHandler.executor.executor(new MiraiMessageEvent(msg)));
|
||||||
Events.subscribeAlways(FriendMessage.class, (msg) -> BotEventHandler.executor.executor(new MiraiMessageEvent(msg)));
|
Events.subscribeAlways(FriendMessage.class, (msg) -> BotEventHandler.executor.executor(new MiraiMessageEvent(msg)));
|
||||||
bot.login();
|
bot.login();
|
@ -1,8 +1,8 @@
|
|||||||
package net.lamgc.cgj.bot.event;
|
package net.lamgc.cgj.bot.framework.mirai.message;
|
||||||
|
|
||||||
|
import net.lamgc.cgj.bot.event.MessageEvent;
|
||||||
import net.lamgc.cgj.bot.message.MessageSender;
|
import net.lamgc.cgj.bot.message.MessageSender;
|
||||||
import net.lamgc.cgj.bot.message.MessageSource;
|
import net.lamgc.cgj.bot.message.MessageSource;
|
||||||
import net.lamgc.cgj.bot.message.MiraiMessageSender;
|
|
||||||
import net.mamoe.mirai.message.ContactMessage;
|
import net.mamoe.mirai.message.ContactMessage;
|
||||||
import net.mamoe.mirai.message.GroupMessage;
|
import net.mamoe.mirai.message.GroupMessage;
|
||||||
import net.mamoe.mirai.message.data.MessageUtils;
|
import net.mamoe.mirai.message.data.MessageUtils;
|
||||||
@ -16,7 +16,7 @@ public class MiraiMessageEvent extends MessageEvent {
|
|||||||
|
|
||||||
public MiraiMessageEvent(ContactMessage message) {
|
public MiraiMessageEvent(ContactMessage message) {
|
||||||
super(message instanceof GroupMessage ? ((GroupMessage) message).getGroup().getId() : 0,
|
super(message instanceof GroupMessage ? ((GroupMessage) message).getGroup().getId() : 0,
|
||||||
message.getSender().getId(), message.getMessage().toString());
|
message.getSender().getId(), message.getMessage().contentToString());
|
||||||
this.messageObject = Objects.requireNonNull(message);
|
this.messageObject = Objects.requireNonNull(message);
|
||||||
if(message instanceof GroupMessage) {
|
if(message instanceof GroupMessage) {
|
||||||
messageSender = new MiraiMessageSender(((GroupMessage) message).getGroup(), MessageSource.Group);
|
messageSender = new MiraiMessageSender(((GroupMessage) message).getGroup(), MessageSource.Group);
|
@ -1,4 +1,4 @@
|
|||||||
package net.lamgc.cgj.bot.message;
|
package net.lamgc.cgj.bot.framework.mirai.message;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import net.lamgc.cgj.bot.BotCode;
|
import net.lamgc.cgj.bot.BotCode;
|
||||||
@ -7,11 +7,13 @@ import net.lamgc.cgj.bot.cache.HotDataCacheStore;
|
|||||||
import net.lamgc.cgj.bot.cache.LocalHashCacheStore;
|
import net.lamgc.cgj.bot.cache.LocalHashCacheStore;
|
||||||
import net.lamgc.cgj.bot.cache.StringRedisCacheStore;
|
import net.lamgc.cgj.bot.cache.StringRedisCacheStore;
|
||||||
import net.lamgc.cgj.bot.event.BotEventHandler;
|
import net.lamgc.cgj.bot.event.BotEventHandler;
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSender;
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSource;
|
||||||
import net.mamoe.mirai.Bot;
|
import net.mamoe.mirai.Bot;
|
||||||
import net.mamoe.mirai.contact.Contact;
|
import net.mamoe.mirai.contact.Contact;
|
||||||
import net.mamoe.mirai.message.data.CombinedMessage;
|
|
||||||
import net.mamoe.mirai.message.data.Image;
|
import net.mamoe.mirai.message.data.Image;
|
||||||
import net.mamoe.mirai.message.data.Message;
|
import net.mamoe.mirai.message.data.Message;
|
||||||
|
import net.mamoe.mirai.message.data.MessageChain;
|
||||||
import net.mamoe.mirai.message.data.MessageUtils;
|
import net.mamoe.mirai.message.data.MessageUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -78,7 +80,7 @@ public class MiraiMessageSender implements MessageSender {
|
|||||||
.replaceAll("&38", "&")
|
.replaceAll("&38", "&")
|
||||||
.split("\\|");
|
.split("\\|");
|
||||||
|
|
||||||
CombinedMessage chain = MessageUtils.newChain().plus("");
|
MessageChain messages = MessageUtils.newChain().plus("");
|
||||||
int codeIndex = 0;
|
int codeIndex = 0;
|
||||||
for(String text : texts) {
|
for(String text : texts) {
|
||||||
if(text.equals("{BotCode}")) {
|
if(text.equals("{BotCode}")) {
|
||||||
@ -89,25 +91,32 @@ public class MiraiMessageSender implements MessageSender {
|
|||||||
log.warn("解析待发送消息内的BotCode时发生异常, 请检查错误格式BotCode的来源并尽快排错!", e);
|
log.warn("解析待发送消息内的BotCode时发生异常, 请检查错误格式BotCode的来源并尽快排错!", e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
chain = chain.plus(processBotCode(code));
|
messages = messages.plus(processBotCode(code));
|
||||||
} else {
|
} else {
|
||||||
chain = chain.plus(text);
|
messages = messages.plus(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return chain;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Message processBotCode(BotCode code) {
|
private Message processBotCode(BotCode code) {
|
||||||
switch(code.getFunctionName().toLowerCase()) {
|
switch(code.getFunctionName().toLowerCase()) {
|
||||||
case "image":
|
case "image":
|
||||||
|
Image img;
|
||||||
if(code.containsParameter("id")) {
|
if(code.containsParameter("id")) {
|
||||||
return MessageUtils.newImage(code.getParameter("id"));
|
img = MessageUtils.newImage(code.getParameter("id"));
|
||||||
} else if(code.containsParameter("absolutePath")) {
|
} else if(code.containsParameter("absolutePath")) {
|
||||||
return uploadImage(code);
|
img = uploadImage(code);
|
||||||
} else {
|
} else {
|
||||||
return MessageUtils.newChain("(参数不存在)");
|
return MessageUtils.newChain("(参数不存在)");
|
||||||
}
|
}
|
||||||
|
if(Strings.nullToEmpty(code.getParameter("flashImage"))
|
||||||
|
.equalsIgnoreCase("true")) {
|
||||||
|
return MessageUtils.flash(img);
|
||||||
|
} else {
|
||||||
|
return img;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
log.warn("解析到不支持的BotCode: {}", code);
|
log.warn("解析到不支持的BotCode: {}", code);
|
||||||
return MessageUtils.newChain("(不支持的BotCode)");
|
return MessageUtils.newChain("(不支持的BotCode)");
|
||||||
@ -138,7 +147,7 @@ public class MiraiMessageSender implements MessageSender {
|
|||||||
log.debug("imageName [{}] 缓存失效或强制更新, 正在更新缓存...", imageName);
|
log.debug("imageName [{}] 缓存失效或强制更新, 正在更新缓存...", imageName);
|
||||||
image = uploadImage0(new File(absolutePath));
|
image = uploadImage0(new File(absolutePath));
|
||||||
String cacheExpireAt;
|
String cacheExpireAt;
|
||||||
long expireTime = 0;
|
long expireTime = 864000000; // 10d
|
||||||
if(!Strings.isNullOrEmpty(cacheExpireAt = code.getParameter("cacheExpireAt"))) {
|
if(!Strings.isNullOrEmpty(cacheExpireAt = code.getParameter("cacheExpireAt"))) {
|
||||||
try {
|
try {
|
||||||
expireTime = Integer.parseInt(cacheExpireAt);
|
expireTime = Integer.parseInt(cacheExpireAt);
|
||||||
@ -147,7 +156,7 @@ public class MiraiMessageSender implements MessageSender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
imageIdCache.update(imageName, image.getImageId(), expireTime);
|
imageIdCache.update(imageName, image.getImageId(), expireTime);
|
||||||
log.info("imageName [{}] 缓存更新完成.(有效时间: {})", imageName, expireTime);
|
log.debug("imageName [{}] 缓存更新完成.(有效时间: {})", imageName, expireTime);
|
||||||
} else {
|
} else {
|
||||||
log.debug("ImageName: [{}] 缓存命中.", imageName);
|
log.debug("ImageName: [{}] 缓存命中.", imageName);
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package net.lamgc.cgj.bot.message;
|
package net.lamgc.cgj.bot.framework.mirai.message;
|
||||||
|
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSender;
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSenderFactory;
|
||||||
|
import net.lamgc.cgj.bot.message.MessageSource;
|
||||||
import net.mamoe.mirai.Bot;
|
import net.mamoe.mirai.Bot;
|
||||||
|
|
||||||
public class MiraiMessageSenderFactory implements MessageSenderFactory {
|
public class MiraiMessageSenderFactory implements MessageSenderFactory {
|
33
src/main/java/net/lamgc/cgj/pixiv/AdultContentDetector.java
Normal file
33
src/main/java/net/lamgc/cgj/pixiv/AdultContentDetector.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package net.lamgc.cgj.pixiv;
|
||||||
|
|
||||||
|
public interface AdultContentDetector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查某一作品的成人内容判断指数
|
||||||
|
* @param illustId 作品Id
|
||||||
|
* @param isUgoira 是否为动图
|
||||||
|
* @param pageIndex 指定页数, 设为0或负数则视为单页面作品
|
||||||
|
* @return 返回成人作品判断指数(0 ~ 1), 需按照情况设置阀值.
|
||||||
|
*/
|
||||||
|
double detect(int illustId, boolean isUgoira, int pageIndex) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查某一作品是否为成人内容
|
||||||
|
* @param illustId 作品Id
|
||||||
|
* @param isUgoira 是否为动图
|
||||||
|
* @param pageIndex 指定页数, 设为0或负数则视为单页面作品
|
||||||
|
* @return 如果为true则为成人作品, 该方法将由检测器决定如何为成人作品.
|
||||||
|
*/
|
||||||
|
boolean isAdultContent(int illustId, boolean isUgoira, int pageIndex) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查某一作品是否为成人内容
|
||||||
|
* @param illustId 作品Id
|
||||||
|
* @param isUgoira 是否为动图
|
||||||
|
* @param pageIndex 指定页数, 设为0或负数则视为单页面作品
|
||||||
|
* @param threshold 指数阀值, 当等于或大于该阀值时返回true.
|
||||||
|
* @return 如果为true则为成人作品, 该方法将由 threshold 参数决定是否为成人作品.
|
||||||
|
*/
|
||||||
|
boolean isAdultContent(int illustId, boolean isUgoira, int pageIndex, double threshold) throws Exception;
|
||||||
|
|
||||||
|
}
|
@ -1,69 +0,0 @@
|
|||||||
package net.lamgc.cgj.pixiv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插图(集)的信息
|
|
||||||
*/
|
|
||||||
public class IllustInfo{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插图(集)ID
|
|
||||||
*/
|
|
||||||
public final int illustID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 第几页
|
|
||||||
*/
|
|
||||||
public final int page;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插图标题
|
|
||||||
*/
|
|
||||||
public final String title;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插图说明
|
|
||||||
*/
|
|
||||||
public final String description;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插图标签
|
|
||||||
*/
|
|
||||||
public final String[] tags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插图图片长度
|
|
||||||
*/
|
|
||||||
public final int width;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插图图片高度
|
|
||||||
*/
|
|
||||||
public final int height;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 作者名
|
|
||||||
*/
|
|
||||||
public final String authorName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 作者用户ID
|
|
||||||
*/
|
|
||||||
public final int authorUserID;
|
|
||||||
|
|
||||||
public IllustInfo(int illustID, String title, String description, String[] tags, int width, int height, String authorName, int authorUserID){
|
|
||||||
this(illustID, 0, title, description, tags, width, height, authorName, authorUserID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IllustInfo(int illustID, int p, String title, String description, String[] tags, int width, int height, String authorName, int authorUserID){
|
|
||||||
this.illustID = illustID;
|
|
||||||
this.page = p;
|
|
||||||
this.title = title;
|
|
||||||
this.description = description;
|
|
||||||
this.tags = tags;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
this.authorName = authorName;
|
|
||||||
this.authorUserID = authorUserID;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,65 @@
|
|||||||
|
package net.lamgc.cgj.pixiv;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用ModerateContent服务开发的检测器.<br/>
|
||||||
|
* ModerateContent: www.moderatecontent.com
|
||||||
|
*/
|
||||||
|
public class ModerateContentDetector implements AdultContentDetector {
|
||||||
|
|
||||||
|
private final static HttpClient httpClient = HttpClientBuilder.create().build();
|
||||||
|
private final static Gson gson = new Gson();
|
||||||
|
private final String requestUrl;
|
||||||
|
|
||||||
|
private final static String API_URL = "https://www.moderatecontent.com/api/v2?key={key}&url=https://pixiv.cat/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个使用ModerateContent鉴黄服务的检测器
|
||||||
|
* @param apiKey API密钥
|
||||||
|
*/
|
||||||
|
public ModerateContentDetector(String apiKey) {
|
||||||
|
requestUrl = API_URL.replace("{key}", apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonObject accessInterface(int illustId, boolean isUgoira, int pageIndex) throws IOException {
|
||||||
|
HttpResponse response;
|
||||||
|
if(pageIndex <= 0) {
|
||||||
|
response = httpClient.execute(new HttpGet(requestUrl + illustId + (isUgoira ? ".gif" : ".jpg")));
|
||||||
|
} else {
|
||||||
|
response = httpClient.execute(new HttpGet(requestUrl + illustId + "-" + pageIndex + (isUgoira ? ".gif" : ".jpg")));
|
||||||
|
}
|
||||||
|
if(response.getStatusLine().getStatusCode() != 200) {
|
||||||
|
throw new IOException("Http response error: " + response.getStatusLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject result = gson.fromJson(EntityUtils.toString(response.getEntity()), JsonObject.class);
|
||||||
|
if (result.get("error_code").getAsInt() != 0) {
|
||||||
|
throw new IOException("Interface result error: " + (result.has("error") ? result.get("error").getAsString() : "(error message is empty)"));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double detect(int illustId, boolean isUgoira, int pageIndex) throws IOException {
|
||||||
|
return accessInterface(illustId, isUgoira, pageIndex).getAsJsonObject("predictions").get("adult").getAsDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAdultContent(int illustId, boolean isUgoira, int pageIndex) throws IOException {
|
||||||
|
return accessInterface(illustId, isUgoira, pageIndex).get("rating_index").getAsInt() == 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAdultContent(int illustId, boolean isUgoira, int pageIndex, double threshold) throws IOException {
|
||||||
|
return detect(illustId, isUgoira, pageIndex) >= threshold;
|
||||||
|
}
|
||||||
|
}
|
@ -1,267 +0,0 @@
|
|||||||
package net.lamgc.cgj.pixiv;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import org.apache.http.HttpHost;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.config.RequestConfig;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.conn.ConnectionPoolTimeoutException;
|
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class Pixiv {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* illust Link
|
|
||||||
*/
|
|
||||||
public final static String ATTR_LINK = "link";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* illust Id
|
|
||||||
*/
|
|
||||||
public final static String ATTR_ILLUST_ID = "illustId";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* illust Title
|
|
||||||
*/
|
|
||||||
public final static String ATTR_TITLE = "title";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* illust Author Name
|
|
||||||
*/
|
|
||||||
public final static String ATTR_AUTHOR_NAME = "authorName";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* illust Author UserID
|
|
||||||
*/
|
|
||||||
public final static String ATTR_AUTHOR_ID = "authorId";
|
|
||||||
|
|
||||||
private final HttpClient httpClient;
|
|
||||||
|
|
||||||
public Pixiv(HttpClient client){
|
|
||||||
this.httpClient = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用帐号密码登录Pixiv
|
|
||||||
* @param PixivID Pixiv账户登录名
|
|
||||||
* @param Password Pixiv帐号密码
|
|
||||||
* @throws IOException 当登录连接出现异常时抛出
|
|
||||||
* @deprecated {@link PixivSession#Login(String, String)} 已经废除, 故本方法不可用
|
|
||||||
*/
|
|
||||||
public Pixiv(String PixivID, String Password) throws IOException {
|
|
||||||
this(PixivID, Password, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用帐号密码登录Pixiv
|
|
||||||
* @param PixivID Pixiv账户登录名
|
|
||||||
* @param Password Pixiv帐号密码
|
|
||||||
* @param proxy 代理设置
|
|
||||||
* @throws IOException 当登录连接出现异常时抛出
|
|
||||||
* @deprecated {@link PixivSession#Login(String, String)} 已经废除, 故本方法不可用
|
|
||||||
*/
|
|
||||||
public Pixiv(String PixivID, String Password, HttpHost proxy) throws IOException {
|
|
||||||
PixivSession pixivSession = new PixivSession(proxy, null);
|
|
||||||
if(pixivSession.Login(PixivID, Password)){
|
|
||||||
System.out.println("P站登录成功!");
|
|
||||||
}else{
|
|
||||||
System.out.println("P站登录失败!错误信息: " + pixivSession.getErrMsg());
|
|
||||||
throw new RuntimeException(pixivSession.getErrMsg());
|
|
||||||
}
|
|
||||||
//httpClient = pixivSession.getHttpClient();
|
|
||||||
httpClient = HttpClientBuilder.create()
|
|
||||||
.setDefaultCookieStore(pixivSession.getCookieStore())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取首页推荐列表
|
|
||||||
* @return 首页推荐列表, 一个Map对应一个推荐项, 使用<code>ATTR_</code>开头常量访问即可
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public List<Map<String, String>> getRecommend() throws IOException {
|
|
||||||
HttpGet getRequest = new HttpGet(PixivURL.PIXIV_INDEX_URL);
|
|
||||||
HttpResponse response = httpClient.execute(getRequest);
|
|
||||||
String pageAsXML = EntityUtils.toString(response.getEntity(),"utf-8");
|
|
||||||
|
|
||||||
//获取推荐图列表(li)
|
|
||||||
//System.out.println(pageAsXML);
|
|
||||||
|
|
||||||
Document document = Jsoup.parse(pageAsXML);
|
|
||||||
|
|
||||||
List<String> links = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-thumbnail-link").eachAttr("href");
|
|
||||||
List<String> illustId = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-thumbnail-link").eachAttr("data-gtm-recommend-illust-id");
|
|
||||||
List<String> title = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-title>h1").eachAttr("title");
|
|
||||||
List<String> authorName = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-user-name").eachText();
|
|
||||||
List<String> authorId = document.select("._image-items.gtm-illust-recommend-zone>li>.gtm-illust-recommend-user-name").eachAttr("data-user_id");
|
|
||||||
|
|
||||||
List<Map<String, String>> recommendList = new ArrayList<>();
|
|
||||||
for(int i = 0; i < links.size(); i++){
|
|
||||||
//System.out.println(links.get(i));
|
|
||||||
Map<String, String> info = new HashMap<>();
|
|
||||||
info.put(ATTR_LINK, PixivURL.PIXIV_INDEX_URL + links.get(i));
|
|
||||||
info.put(ATTR_ILLUST_ID, illustId.get(i));
|
|
||||||
info.put(ATTR_TITLE, title.get(i));
|
|
||||||
info.put(ATTR_AUTHOR_NAME, authorName.get(i));
|
|
||||||
info.put(ATTR_AUTHOR_ID, authorId.get(i));
|
|
||||||
recommendList.add(info);
|
|
||||||
}
|
|
||||||
return recommendList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getAllDownloadLink(int illustID) throws IOException {
|
|
||||||
HttpGet illustPage = new HttpGet(PixivURL.PIXIV_ILLUST_API_URL.replaceAll("\\{illustId}", String.valueOf(illustID)));
|
|
||||||
HttpResponse response = httpClient.execute(illustPage);
|
|
||||||
String pageAsXML = EntityUtils.toString(response.getEntity(),"utf-8");
|
|
||||||
//System.out.println(pageAsXML);
|
|
||||||
JsonObject resultObj = (JsonObject) new JsonParser().parse(pageAsXML);
|
|
||||||
if(!resultObj.get("error").getAsBoolean()){
|
|
||||||
JsonArray bodyArray = resultObj.get("body").getAsJsonArray();
|
|
||||||
int length = bodyArray.size();
|
|
||||||
String[] result = new String[length];
|
|
||||||
for(int i = 0; i < length; i++){
|
|
||||||
JsonObject childObj = bodyArray.get(i).getAsJsonObject();
|
|
||||||
result[i] = childObj.get("urls").getAsJsonObject().get("original").getAsString();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}else{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载P站图片
|
|
||||||
* @param illustID 插图ID
|
|
||||||
* @return 成功返回图片输入流,失败或为多图则返回null
|
|
||||||
*/
|
|
||||||
public InputStream[] downloadIllustImage(int illustID) throws IOException {
|
|
||||||
String[] links = getAllDownloadLink(illustID);
|
|
||||||
List<InputStream> inputStreamList = new ArrayList<>();
|
|
||||||
int count = 1;
|
|
||||||
boolean retry = false;
|
|
||||||
for(int i = 0; i < links.length; i++){
|
|
||||||
try {
|
|
||||||
long sleepTime = (new Random().nextInt(4) + 2) * 1000;
|
|
||||||
System.out.println("nextTime: " + (float)(sleepTime / 1000));
|
|
||||||
Thread.sleep(sleepTime);
|
|
||||||
} catch (InterruptedException ignored) {}
|
|
||||||
String link = links[i];
|
|
||||||
System.out.print("page:" + count++ + "/" + links.length + " ...");
|
|
||||||
HttpGet imgGet = new HttpGet(link);
|
|
||||||
//关键!如果不加上Referer的话,会返回403
|
|
||||||
imgGet.setHeader("Referer", PixivURL.PIXIV_ILLUST_MEDIUM_URL.replaceAll("\\{illustId}", String.valueOf(illustID)));
|
|
||||||
RequestConfig config = RequestConfig.custom()
|
|
||||||
.setConnectTimeout(20 * 1000)
|
|
||||||
.setConnectionRequestTimeout(20 * 1000)
|
|
||||||
.setSocketTimeout(30 * 1000)
|
|
||||||
.build();
|
|
||||||
imgGet.setConfig(config);
|
|
||||||
HttpResponse response;
|
|
||||||
try {
|
|
||||||
response = httpClient.execute(imgGet);
|
|
||||||
}catch(ConnectionPoolTimeoutException e){
|
|
||||||
if(retry){
|
|
||||||
retry = false;
|
|
||||||
System.out.println("获取失败,跳过...");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
System.out.println("连接超时,重新获取...");
|
|
||||||
retry = true;
|
|
||||||
i--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
retry = false;
|
|
||||||
|
|
||||||
ByteArrayOutputStream cacheOutputStream = new ByteArrayOutputStream((int)response.getEntity().getContentLength());
|
|
||||||
InputStream content = response.getEntity().getContent();
|
|
||||||
int readLength;
|
|
||||||
byte[] cache = new byte[4096];
|
|
||||||
while((readLength = content.read(cache)) != -1){
|
|
||||||
cacheOutputStream.write(cache, 0, readLength);
|
|
||||||
}
|
|
||||||
byte[] data = cacheOutputStream.toByteArray();
|
|
||||||
//System.out.println("读到数据: " + data.length);
|
|
||||||
inputStreamList.add(new ByteArrayInputStream(data));
|
|
||||||
System.out.println("done!(length: " + response.getEntity().getContentLength() + ")");
|
|
||||||
|
|
||||||
}
|
|
||||||
return inputStreamList.toArray(new InputStream[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载P站图片
|
|
||||||
* @param illustID 插图ID
|
|
||||||
* @return 成功返回图片输入流,失败或为多图则返回null
|
|
||||||
*/
|
|
||||||
public InputStream downloadIllustImages(int illustID){
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过解析插图详情页获取
|
|
||||||
* - 插图标题
|
|
||||||
* - 插图作者(及其UserId)
|
|
||||||
* - 插图上传时间
|
|
||||||
* - 插图标签(原始标签)
|
|
||||||
* ...
|
|
||||||
* @return 成功返回IllustInfo对象,失败返回null
|
|
||||||
*/
|
|
||||||
public IllustInfo[] getIllustInfo(int[] illustIDs) throws IOException {
|
|
||||||
//获取Api
|
|
||||||
HttpGet apiRequest = new HttpGet(PixivURL.getPixivIllustInfoAPI(illustIDs));
|
|
||||||
HttpResponse response = httpClient.execute(apiRequest);
|
|
||||||
String resultText = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
|
||||||
System.out.println(resultText);
|
|
||||||
JsonObject resultObj = ((JsonObject) new JsonParser().parse(resultText));
|
|
||||||
if(resultObj.get("error").getAsBoolean()){
|
|
||||||
System.err.println("获取失败!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
List<IllustInfo> illustInfoList = new ArrayList<>();
|
|
||||||
JsonArray illustArray = resultObj.get("body").getAsJsonObject().get("illusts").getAsJsonArray();
|
|
||||||
illustArray.forEach(jsonElement -> {
|
|
||||||
JsonObject illustInfoObj = jsonElement.getAsJsonObject();
|
|
||||||
JsonArray tagsArray = illustInfoObj.get("tags").getAsJsonArray();
|
|
||||||
String[] tags = new String[tagsArray.size()];
|
|
||||||
for(int i = 0; i < tags.length; i++){
|
|
||||||
tags[i] = tagsArray.get(i).getAsString();
|
|
||||||
}
|
|
||||||
//TODO: 通过不需要作者id就能获取图片信息的api无法获取图片尺寸
|
|
||||||
IllustInfo illustInfo = new IllustInfo(
|
|
||||||
illustInfoObj.get("workId").getAsInt(),
|
|
||||||
illustInfoObj.get("title").getAsString(),
|
|
||||||
null,
|
|
||||||
tags,
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
illustInfoObj.get("userName").getAsString(),
|
|
||||||
illustInfoObj.get("userId").getAsInt()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定用户的所有插画
|
|
||||||
*/
|
|
||||||
public void getUserAllIllustTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -299,6 +299,7 @@ public class PixivDownload {
|
|||||||
*/
|
*/
|
||||||
public List<JsonObject> getRanking(PixivURL.RankingContentType contentType, PixivURL.RankingMode mode,
|
public List<JsonObject> getRanking(PixivURL.RankingContentType contentType, PixivURL.RankingMode mode,
|
||||||
Date time, int rankStart, int range) throws IOException {
|
Date time, int rankStart, int range) throws IOException {
|
||||||
|
Objects.requireNonNull(time);
|
||||||
if(!Objects.requireNonNull(contentType).isSupportedMode(Objects.requireNonNull(mode))) {
|
if(!Objects.requireNonNull(contentType).isSupportedMode(Objects.requireNonNull(mode))) {
|
||||||
throw new IllegalArgumentException("ContentType不支持指定的RankingMode: ContentType: " + contentType.name() + ", Mode: " + mode.name());
|
throw new IllegalArgumentException("ContentType不支持指定的RankingMode: ContentType: " + contentType.name() + ", Mode: " + mode.name());
|
||||||
} else if(rankStart <= 0) {
|
} else if(rankStart <= 0) {
|
||||||
@ -317,13 +318,15 @@ public class PixivDownload {
|
|||||||
ArrayList<JsonObject> results = new ArrayList<>(range);
|
ArrayList<JsonObject> results = new ArrayList<>(range);
|
||||||
for (int pageIndex = startPages; pageIndex <= endPages && count < range; pageIndex++) {
|
for (int pageIndex = startPages; pageIndex <= endPages && count < range; pageIndex++) {
|
||||||
HttpGet request = createHttpGetRequest(PixivURL.getRankingLink(contentType, mode, time, pageIndex, true));
|
HttpGet request = createHttpGetRequest(PixivURL.getRankingLink(contentType, mode, time, pageIndex, true));
|
||||||
|
log.debug("RequestUri: {}", request.getURI());
|
||||||
HttpResponse response = httpClient.execute(request);
|
HttpResponse response = httpClient.execute(request);
|
||||||
|
String responseBody = EntityUtils.toString(response.getEntity());
|
||||||
|
log.debug("ResponseBody: {}", responseBody);
|
||||||
if(response.getStatusLine().getStatusCode() != 200) {
|
if(response.getStatusLine().getStatusCode() != 200) {
|
||||||
throw new IOException("Http Response Error: " + response.getStatusLine());
|
throw new IOException("Http Response Error: '" + response.getStatusLine() + "', ResponseBody: '" + responseBody + '\'');
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray resultArray = gson.fromJson(EntityUtils.toString(response.getEntity()), JsonObject.class).getAsJsonArray("contents");
|
JsonArray resultArray = gson.fromJson(responseBody, JsonObject.class).getAsJsonArray("contents");
|
||||||
for (int resultIndex = startIndex; resultIndex < resultArray.size() && count < range; resultIndex++, count++) {
|
for (int resultIndex = startIndex; resultIndex < resultArray.size() && count < range; resultIndex++, count++) {
|
||||||
results.add(resultArray.get(resultIndex).getAsJsonObject());
|
results.add(resultArray.get(resultIndex).getAsJsonObject());
|
||||||
}
|
}
|
||||||
@ -430,13 +433,14 @@ public class PixivDownload {
|
|||||||
THUMB_MINI
|
THUMB_MINI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取帐号所有的收藏插画,并以输入流形式提供
|
* 获取帐号所有的收藏插画,并以输入流形式提供
|
||||||
* @return 获取所有链接的InputStream, 请注意关闭InputStream
|
* @return 获取所有链接的InputStream, 请注意关闭InputStream
|
||||||
* @throws IOException 当获取时发生异常则直接抛出
|
* @throws IOException 当获取时发生异常则直接抛出
|
||||||
|
* @deprecated 该方法可能会导致已经打开的InputStream超时, 使图片获取失败,
|
||||||
|
* 请直接使用{@linkplain #getCollectionAsInputStream(PageQuality, BiConsumer)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Set<Map.Entry<String, InputStream>> getCollectionAsInputStream(PageQuality quality) throws IOException {
|
public Set<Map.Entry<String, InputStream>> getCollectionAsInputStream(PageQuality quality) throws IOException {
|
||||||
HashSet<Map.Entry<String, InputStream>> illustInputStreamSet = new HashSet<>();
|
HashSet<Map.Entry<String, InputStream>> illustInputStreamSet = new HashSet<>();
|
||||||
getCollectionAsInputStream(quality, (link, inputStream) -> illustInputStreamSet.add(new AbstractMap.SimpleEntry<>(link, inputStream)));
|
getCollectionAsInputStream(quality, (link, inputStream) -> illustInputStreamSet.add(new AbstractMap.SimpleEntry<>(link, inputStream)));
|
||||||
@ -597,12 +601,29 @@ public class PixivDownload {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过预加载数据获取作品类型
|
||||||
|
* @param illustId 作品Id
|
||||||
|
* @param preLoadDataObject 预加载数据(IllustInfo也可以)
|
||||||
|
* @return 如果存在illustType属性, 则返回对应项, 如没有, 或数据内不存在指定作品id的数据, 返回null
|
||||||
|
*/
|
||||||
public static PixivIllustType getIllustTypeByPreLoadData(int illustId, JsonObject preLoadDataObject) {
|
public static PixivIllustType getIllustTypeByPreLoadData(int illustId, JsonObject preLoadDataObject) {
|
||||||
JsonObject illustData;
|
JsonObject illustData = null;
|
||||||
if(preLoadDataObject.has("illust")) {
|
if(preLoadDataObject.has("illust")) {
|
||||||
illustData = preLoadDataObject.getAsJsonObject("illust").getAsJsonObject(String.valueOf(illustId));
|
illustData = preLoadDataObject.getAsJsonObject("illust").getAsJsonObject(String.valueOf(illustId));
|
||||||
} else if(preLoadDataObject.has(String.valueOf(illustId))) {
|
} else if(preLoadDataObject.has(String.valueOf(illustId))) {
|
||||||
illustData = preLoadDataObject.getAsJsonObject(String.valueOf(illustId));
|
illustData = preLoadDataObject.getAsJsonObject(String.valueOf(illustId));
|
||||||
|
} else if(preLoadDataObject.has("body")) { // 解析IllustInfo
|
||||||
|
for (JsonElement jsonElement : preLoadDataObject.getAsJsonObject("body").getAsJsonArray("illusts")) {
|
||||||
|
JsonObject illustInfo = jsonElement.getAsJsonObject();
|
||||||
|
if (illustInfo.get("illustId").getAsInt() == illustId) {
|
||||||
|
illustData = illustInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(illustData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
illustData = preLoadDataObject;
|
illustData = preLoadDataObject;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,13 @@ import java.util.Date;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pixiv搜索URL构造器
|
||||||
|
* <p>该构造器通过分析Pixiv搜索链接可用的参数而开发, 对搜索链接的构造有高度自定义能力.</p>
|
||||||
|
* @author LamGC
|
||||||
|
* @see PixivURL#PIXIV_SEARCH_CONTENT_URL
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("ALL")
|
||||||
public class PixivSearchBuilder {
|
public class PixivSearchBuilder {
|
||||||
|
|
||||||
private final String content;
|
private final String content;
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
package net.lamgc.cgj.pixiv;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import org.apache.http.Header;
|
|
||||||
import org.apache.http.HttpHost;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.NameValuePair;
|
|
||||||
import org.apache.http.client.CookieStore;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.impl.client.BasicCookieStore;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.message.BasicHeader;
|
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PixivSession {
|
|
||||||
|
|
||||||
public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 全登陆过程的关键,
|
|
||||||
* 保存会话用的cookieStore!
|
|
||||||
*/
|
|
||||||
private CookieStore cookieStore = new BasicCookieStore();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 可以直接使用的HttpClient对象
|
|
||||||
*/
|
|
||||||
private HttpClient httpClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 最后一次登录的错误信息
|
|
||||||
*/
|
|
||||||
private String errMsg;
|
|
||||||
|
|
||||||
public PixivSession(){
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PixivSession(CookieStore cookieStore){
|
|
||||||
this(null, cookieStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一个Pixiv登录会话
|
|
||||||
*/
|
|
||||||
public PixivSession(HttpHost proxy, CookieStore cookieStore) {
|
|
||||||
if(cookieStore != null){
|
|
||||||
this.cookieStore = cookieStore;
|
|
||||||
}
|
|
||||||
List<Header> defaultHeader = new ArrayList<>();
|
|
||||||
defaultHeader.add(new BasicHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"));
|
|
||||||
defaultHeader.add(new BasicHeader("user-agent", PixivSession.USER_AGENT));
|
|
||||||
defaultHeader.add(new BasicHeader("accept-encoding", "gzip, deflate, br"));
|
|
||||||
defaultHeader.add(new BasicHeader("accept-language", "zh-CN,zh;q=0.9"));
|
|
||||||
|
|
||||||
/*defaultHeader.add(new BasicHeader("sec-fetch-mode", "navigate"));
|
|
||||||
defaultHeader.add(new BasicHeader("sec-fetch-site", "same-origin"));
|
|
||||||
defaultHeader.add(new BasicHeader("upgrade-insecure-requests", "1"));*/
|
|
||||||
//创建一个Http访问器
|
|
||||||
httpClient = HttpClients.custom()
|
|
||||||
.setDefaultCookieStore(cookieStore)
|
|
||||||
.setDefaultHeaders(defaultHeader)
|
|
||||||
.setProxy(proxy)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 程序自行通过帐号密码登录Pixiv.
|
|
||||||
* @param PixivID Pixiv帐号
|
|
||||||
* @param Password Pixiv密码
|
|
||||||
* @return 登录成功返回true
|
|
||||||
* @throws IOException 当登录抛出异常时返回
|
|
||||||
* @deprecated Pixiv已经新增Google人机验证, 程序已无法自行登录Pixiv
|
|
||||||
*/
|
|
||||||
public boolean Login(String PixivID, String Password) throws IOException {
|
|
||||||
// 获取登录接口所需的PostKey
|
|
||||||
String post_key = getPostKey();
|
|
||||||
HttpPost postRequest = new HttpPost(PixivURL.PIXIV_LOGIN_URL); //https://accounts.pixiv.net/api/login?lang=zh
|
|
||||||
List<NameValuePair> params = new ArrayList<>();
|
|
||||||
params.add(new BasicNameValuePair("pixiv_id", PixivID));
|
|
||||||
params.add(new BasicNameValuePair("password", Password));
|
|
||||||
params.add(new BasicNameValuePair("post_key", post_key));
|
|
||||||
//Form编码表单,作为Post的数据
|
|
||||||
postRequest.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
|
|
||||||
//启动访问
|
|
||||||
HttpResponse response = httpClient.execute(postRequest);
|
|
||||||
//获取接口返回数据
|
|
||||||
String httpXML = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
|
||||||
System.out.println(httpXML);
|
|
||||||
JsonObject responseJson = (JsonObject) new JsonParser().parse(httpXML);
|
|
||||||
if(!responseJson.get("error").getAsBoolean() && !responseJson.get("body").getAsJsonObject().has("validation_errors")){
|
|
||||||
errMsg = null;
|
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
errMsg = responseJson.get("body").getAsJsonObject().get("validation_errors").toString();
|
|
||||||
//System.err.println("登录失败!MSG: " + errMsg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录前准备, 获取PostKey
|
|
||||||
* @return Post_Key
|
|
||||||
*/
|
|
||||||
private String getPostKey() throws IOException {
|
|
||||||
//创建请求,获取PostKey
|
|
||||||
HttpGet getRequest = new HttpGet(PixivURL.PIXIV_LOGIN_PAGE_URL);
|
|
||||||
//设置请求
|
|
||||||
//getRequest.setConfig(config);
|
|
||||||
getRequest.setHeader("User-Agent", USER_AGENT);
|
|
||||||
//启动访问
|
|
||||||
HttpResponse response = httpClient.execute(getRequest);
|
|
||||||
//获取网页内容
|
|
||||||
String pageAsXML = EntityUtils.toString(response.getEntity(),"utf-8");
|
|
||||||
//创建Http解析器
|
|
||||||
Document document = Jsoup.parse(pageAsXML);
|
|
||||||
//获取init-config内容
|
|
||||||
String init_config = document.getElementById("init-config").val();
|
|
||||||
//System.out.println(init_config);
|
|
||||||
//创建Json解析器解析init-config
|
|
||||||
JsonObject initConfigObj = (JsonObject) new JsonParser().parse(init_config);
|
|
||||||
//检查是否有postKey
|
|
||||||
if(!initConfigObj.has("pixivAccount.postKey")){
|
|
||||||
throw new RuntimeException("postKey获取失败!可能是Pixiv修改了登录过程!");
|
|
||||||
}
|
|
||||||
//获取postKey
|
|
||||||
return initConfigObj.get("pixivAccount.postKey").getAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取CookieStore
|
|
||||||
* @return CookieStore
|
|
||||||
*/
|
|
||||||
public CookieStore getCookieStore(){
|
|
||||||
return cookieStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取可直接使用的HttpClient对象
|
|
||||||
* @return 已配置好的HttpClient对象
|
|
||||||
*/
|
|
||||||
public HttpClient getHttpClient(){
|
|
||||||
return this.httpClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasError(){
|
|
||||||
return errMsg == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取错误信息
|
|
||||||
* @return 返回登录错误信息
|
|
||||||
* @deprecated {@link #Login(String, String)}已经废除, 故本接口废除
|
|
||||||
*/
|
|
||||||
public String getErrMsg(){
|
|
||||||
return errMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package net.lamgc.cgj.pixiv;
|
|
||||||
|
|
||||||
public class PixivTag {
|
|
||||||
|
|
||||||
public static PixivTag create(String tagName) {
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PixivTag() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -9,6 +9,7 @@ import java.util.GregorianCalendar;
|
|||||||
/**
|
/**
|
||||||
* 目前已整理的一些Pixiv接口列表
|
* 目前已整理的一些Pixiv接口列表
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public class PixivURL {
|
public class PixivURL {
|
||||||
|
|
||||||
|
|
||||||
@ -186,7 +187,7 @@ public class PixivURL {
|
|||||||
public static String getRankingLink(RankingContentType contentType, RankingMode mode, Date time, int pageIndex, boolean json){
|
public static String getRankingLink(RankingContentType contentType, RankingMode mode, Date time, int pageIndex, boolean json){
|
||||||
StringBuilder linkBuilder = new StringBuilder(PIXIV_RANKING_LINK);
|
StringBuilder linkBuilder = new StringBuilder(PIXIV_RANKING_LINK);
|
||||||
linkBuilder.append("mode=").append(mode == null ? RankingMode.MODE_DAILY.modeParam : mode.modeParam);
|
linkBuilder.append("mode=").append(mode == null ? RankingMode.MODE_DAILY.modeParam : mode.modeParam);
|
||||||
if(contentType != null && !contentType.equals(RankingContentType.ALL)){
|
if(contentType != null && !contentType.equals(RankingContentType.TYPE_ALL)){
|
||||||
linkBuilder.append("&content=").append(contentType.typeName);
|
linkBuilder.append("&content=").append(contentType.typeName);
|
||||||
}
|
}
|
||||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
|
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
|
||||||
@ -278,7 +279,7 @@ public class PixivURL {
|
|||||||
* 排名榜类型
|
* 排名榜类型
|
||||||
*/
|
*/
|
||||||
public enum RankingContentType{
|
public enum RankingContentType{
|
||||||
ALL("", RankingMode.values()),
|
TYPE_ALL("", RankingMode.values()),
|
||||||
/**
|
/**
|
||||||
* 插画
|
* 插画
|
||||||
* 支持的时间类型: 每天, 每周, 每月, 新人
|
* 支持的时间类型: 每天, 每周, 每月, 新人
|
||||||
@ -336,7 +337,7 @@ public class PixivURL {
|
|||||||
* @return 如果支持返回true
|
* @return 如果支持返回true
|
||||||
*/
|
*/
|
||||||
public boolean isSupportedMode(RankingMode mode) {
|
public boolean isSupportedMode(RankingMode mode) {
|
||||||
return Arrays.binarySearch(supportedMode, mode) != -1;
|
return Arrays.binarySearch(supportedMode, mode) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,7 @@ import java.util.zip.ZipEntry;
|
|||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pixiv动图构建器.
|
* Pixiv动图构建器
|
||||||
* 可便捷的接收并处理动图.
|
|
||||||
*/
|
*/
|
||||||
public final class PixivUgoiraBuilder {
|
public final class PixivUgoiraBuilder {
|
||||||
|
|
||||||
@ -135,7 +134,7 @@ public final class PixivUgoiraBuilder {
|
|||||||
image.getRGB(0, 0, image.getWidth(), image.getHeight(), rgb, 0, image.getWidth());
|
image.getRGB(0, 0, image.getWidth(), image.getHeight(), rgb, 0, image.getWidth());
|
||||||
log.trace("帧解析完成, 正在插入...");
|
log.trace("帧解析完成, 正在插入...");
|
||||||
encoder.addImage(Image.fromRgb(rgb, image.getWidth()), new ImageOptions().setDelay(frameInfo.get("delay").getAsLong(), TimeUnit.MILLISECONDS));
|
encoder.addImage(Image.fromRgb(rgb, image.getWidth()), new ImageOptions().setDelay(frameInfo.get("delay").getAsLong(), TimeUnit.MILLISECONDS));
|
||||||
log.debug("帧 {} 插入完成.", frameFileName);
|
log.trace("帧 {} 插入完成.", frameFileName);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("解析帧图片数据时发生异常", e);
|
log.error("解析帧图片数据时发生异常", e);
|
||||||
}
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
package net.lamgc.cgj.util;
|
|
||||||
|
|
||||||
import org.apache.http.client.CookieStore;
|
|
||||||
import org.apache.http.impl.client.BasicCookieStore;
|
|
||||||
import org.apache.http.impl.cookie.BasicClientCookie;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class CookieUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将{@link java.net.CookieStore}转换到{@link CookieStore}
|
|
||||||
* @param netCookieStore java.net.CookieStore
|
|
||||||
* @return org.apache.http.client.CookieStore
|
|
||||||
*/
|
|
||||||
public static CookieStore NAParse(java.net.CookieStore netCookieStore){
|
|
||||||
CookieStore apacheCookieStore = new BasicCookieStore();
|
|
||||||
netCookieStore.getCookies().forEach(netCookie -> {
|
|
||||||
BasicClientCookie aCookie = new BasicClientCookie(netCookie.getName(), netCookie.getValue());
|
|
||||||
aCookie.setComment(netCookie.getComment());
|
|
||||||
aCookie.setDomain(netCookie.getDomain());
|
|
||||||
aCookie.setExpiryDate(new Date(netCookie.getMaxAge()));
|
|
||||||
aCookie.setPath(netCookie.getPath());
|
|
||||||
aCookie.setSecure(netCookie.getSecure());
|
|
||||||
aCookie.setVersion(netCookie.getVersion());
|
|
||||||
apacheCookieStore.addCookie(aCookie);
|
|
||||||
});
|
|
||||||
return apacheCookieStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ import net.lamgc.utils.base.runner.StringParameterParser;
|
|||||||
public class PagesQualityParser implements StringParameterParser<PixivDownload.PageQuality> {
|
public class PagesQualityParser implements StringParameterParser<PixivDownload.PageQuality> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PixivDownload.PageQuality parse(String strValue) throws Exception {
|
public PixivDownload.PageQuality parse(String strValue) {
|
||||||
return PixivDownload.PageQuality.valueOf(strValue.toUpperCase());
|
return PixivDownload.PageQuality.valueOf(strValue.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
src/main/resources/log4j2-test.xml
Normal file
39
src/main/resources/log4j2-test.xml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration status="WARN">
|
||||||
|
<properties>
|
||||||
|
<property name="logStorePath">./logs</property>
|
||||||
|
<property name="charset">UTF-8</property>
|
||||||
|
<property name="pattern">[%-d{HH:mm:ss.SSS} %5level][%logger.%method():%-3L][%thread]: %msg%n</property>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<Appenders>
|
||||||
|
<Console name="CONSOLE_STDOUT" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="${pattern}" charset="${charset}"/>
|
||||||
|
<Filters>
|
||||||
|
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT"/>
|
||||||
|
</Filters>
|
||||||
|
</Console>
|
||||||
|
<Console name="CONSOLE_STDERR" target="SYSTEM_ERR">
|
||||||
|
<PatternLayout pattern="${pattern}" charset="${charset}"/>
|
||||||
|
<Filters>
|
||||||
|
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
</Filters>
|
||||||
|
</Console>
|
||||||
|
|
||||||
|
<RollingFile name="rollingFile" fileName="logs/latest.log" filePattern="logs/running.%-d{yyyy-MM-dd_HH-mm-ss}.log.gz">
|
||||||
|
<PatternLayout pattern="${pattern}" charset="${charset}"/>
|
||||||
|
<Policies>
|
||||||
|
<OnStartupTriggeringPolicy />
|
||||||
|
</Policies>
|
||||||
|
</RollingFile>
|
||||||
|
</Appenders>
|
||||||
|
|
||||||
|
<Loggers>
|
||||||
|
<Logger level="INFO" name="org.apache.http"/>
|
||||||
|
<Root level="TRACE">
|
||||||
|
<AppenderRef ref="CONSOLE_STDOUT"/>
|
||||||
|
<AppenderRef ref="CONSOLE_STDERR"/>
|
||||||
|
<AppenderRef ref="rollingFile"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</configuration>
|
@ -10,7 +10,7 @@
|
|||||||
<Console name="CONSOLE_STDOUT" target="SYSTEM_OUT">
|
<Console name="CONSOLE_STDOUT" target="SYSTEM_OUT">
|
||||||
<PatternLayout pattern="${pattern}" charset="${charset}"/>
|
<PatternLayout pattern="${pattern}" charset="${charset}"/>
|
||||||
<Filters>
|
<Filters>
|
||||||
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT"/>
|
<LevelRangeFilter minLevel="INFO" maxLevel="INFO" />
|
||||||
</Filters>
|
</Filters>
|
||||||
</Console>
|
</Console>
|
||||||
<Console name="CONSOLE_STDERR" target="SYSTEM_ERR">
|
<Console name="CONSOLE_STDERR" target="SYSTEM_ERR">
|
||||||
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<Loggers>
|
<Loggers>
|
||||||
<Logger level="INFO" name="org.apache.http"/>
|
<Logger level="INFO" name="org.apache.http"/>
|
||||||
<Root level="INFO">
|
<Root level="TRACE">
|
||||||
<AppenderRef ref="CONSOLE_STDOUT"/>
|
<AppenderRef ref="CONSOLE_STDOUT"/>
|
||||||
<AppenderRef ref="CONSOLE_STDERR"/>
|
<AppenderRef ref="CONSOLE_STDERR"/>
|
||||||
<AppenderRef ref="rollingFile"/>
|
<AppenderRef ref="rollingFile"/>
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package net.lamgc.cgj.pixiv;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
public class ModerateContentDetectorTest {
|
||||||
|
|
||||||
|
private final static AdultContentDetector acd = new ModerateContentDetector("d91b6c3fa2bba9ee8f9e68827ba0d937");
|
||||||
|
private final static Logger log = LoggerFactory.getLogger(ModerateContentDetector.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkTest() throws Exception {
|
||||||
|
log.info("Detect: {}, isAdult: {}",
|
||||||
|
acd.detect(80840411, false, 0),
|
||||||
|
acd.isAdultContent(80840411, false, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,15 @@
|
|||||||
package net.lamgc.cgj.pixiv;
|
package net.lamgc.cgj.pixiv;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.apache.http.client.CookieStore;
|
import org.apache.http.client.CookieStore;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
@ -174,19 +181,6 @@ public class PixivDownloadTest {
|
|||||||
log.info("正在调用方法...");
|
log.info("正在调用方法...");
|
||||||
try {
|
try {
|
||||||
pixivDownload.getRankingAsInputStream(null, null, queryDate, 5, 50, PixivDownload.PageQuality.ORIGINAL, (rank, link, rankInfo, inputStream) -> {
|
pixivDownload.getRankingAsInputStream(null, null, queryDate, 5, 50, PixivDownload.PageQuality.ORIGINAL, (rank, link, rankInfo, inputStream) -> {
|
||||||
/*try {
|
|
||||||
|
|
||||||
ZipEntry entry = new ZipEntry("Rank" + rank + "-" + link.substring(link.lastIndexOf("/") + 1));
|
|
||||||
entry.setComment(rankInfo.toString());
|
|
||||||
log.info("正在写入: " + entry.getName());
|
|
||||||
zos.putNextEntry(entry);
|
|
||||||
IOUtils.copy(inputStream, zos);
|
|
||||||
zos.flush();
|
|
||||||
log.info("已成功写入 {}", entry.getName());
|
|
||||||
inputStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("写入文件项时发生异常", e);
|
|
||||||
}*/
|
|
||||||
log.info("空操作");
|
log.info("空操作");
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
@ -202,4 +196,17 @@ public class PixivDownloadTest {
|
|||||||
log.info(new PixivDownload(cookieStore, proxy).getIllustPreLoadDataById(64076261).toString());
|
log.info(new PixivDownload(cookieStore, proxy).getIllustPreLoadDataById(64076261).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void illustInfoTest() throws IOException {
|
||||||
|
CloseableHttpClient httpClient = HttpClientBuilder.create().setProxy(new HttpHost("127.0.0.1", 1001)).build();
|
||||||
|
HttpGet request = new HttpGet(PixivURL.getPixivIllustInfoAPI(80880547));
|
||||||
|
CloseableHttpResponse response = httpClient.execute(request);
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
JsonObject illustInfoResult = new Gson().fromJson(body, JsonObject.class);
|
||||||
|
log.info("IllustInfoJsonResult: {}", illustInfoResult);
|
||||||
|
PixivDownload.PixivIllustType illustType = PixivDownload.PixivIllustType.getIllustTypeByPreLoadData(80880547, illustInfoResult);
|
||||||
|
log.info("IllustType: {}", illustType);
|
||||||
|
Assert.assertEquals(PixivDownload.PixivIllustType.UGOIRA, illustType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user