mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-04-30 06:37:36 +00:00
[Add] AutoSender 增加自动发送器接口;
[Add] RandomIntervalSendTimer 增加随机延迟自动发送器; [Add] RecommendArtworksSender 增加随机排行榜作品发送器; [Change] PixivDownload 重新开发 getRanking 方法;
This commit is contained in:
parent
dd88f2acab
commit
9dfc20a525
30
src/main/java/net/lamgc/cgj/bot/AutoSender.java
Normal file
30
src/main/java/net/lamgc/cgj/bot/AutoSender.java
Normal file
@ -0,0 +1,30 @@
|
||||
package net.lamgc.cgj.bot;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 自动发送器
|
||||
*/
|
||||
public abstract class AutoSender {
|
||||
|
||||
private MessageSender messageSender;
|
||||
|
||||
/**
|
||||
* 构造一个自动发送器
|
||||
* @param messageSender 自动发送器所使用的消息发送器
|
||||
*/
|
||||
public AutoSender(MessageSender messageSender) {
|
||||
this.messageSender = Objects.requireNonNull(messageSender);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设置等等消息发送器
|
||||
* @return 消息发送器
|
||||
*/
|
||||
MessageSender getMessageSender() {
|
||||
return this.messageSender;
|
||||
}
|
||||
|
||||
public abstract void send();
|
||||
|
||||
}
|
70
src/main/java/net/lamgc/cgj/bot/RandomIntervalSendTimer.java
Normal file
70
src/main/java/net/lamgc/cgj/bot/RandomIntervalSendTimer.java
Normal file
@ -0,0 +1,70 @@
|
||||
package net.lamgc.cgj.bot;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* 随机间隔发送器
|
||||
*/
|
||||
public class RandomIntervalSendTimer extends TimerTask {
|
||||
|
||||
private final static Timer timer = new Timer("Thread-RIST");
|
||||
private final static Logger log = LoggerFactory.getLogger("RandomIntervalSendTimer");
|
||||
private final Random timeRandom = new Random();
|
||||
private final AutoSender sender;
|
||||
private final long time;
|
||||
private final int floatTime;
|
||||
private AtomicBoolean loop = new AtomicBoolean();
|
||||
private final AtomicBoolean start = new AtomicBoolean();
|
||||
|
||||
|
||||
public RandomIntervalSendTimer(AutoSender sender, long time, int floatTime) {
|
||||
this.sender = sender;
|
||||
this.time = time;
|
||||
this.floatTime = floatTime;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
start(this.loop.get());
|
||||
}
|
||||
|
||||
public void start(boolean loop) {
|
||||
this.loop.set(loop);
|
||||
long nextDelay = time + timeRandom.nextInt(floatTime);
|
||||
log.info("定时器 {} 下一延迟: {}ms", Integer.toHexString(this.hashCode()), nextDelay);
|
||||
if(start.get()) {
|
||||
try {
|
||||
Field state = this.getClass().getSuperclass().getDeclaredField("state");
|
||||
state.setAccessible(true);
|
||||
state.setInt(this, 0);
|
||||
state.setAccessible(false);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
start.set(true);
|
||||
timer.schedule(this, nextDelay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
sender.send();
|
||||
if (this.loop.get()) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
start.set(false);
|
||||
return super.cancel();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package net.lamgc.cgj.bot;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.lamgc.cgj.pixiv.PixivDownload;
|
||||
import net.lamgc.cgj.pixiv.PixivURL;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 推荐作品发送器
|
||||
*/
|
||||
public class RandomRankingArtworksSender extends AutoSender {
|
||||
|
||||
private final Logger log;
|
||||
private final int rankingStart;
|
||||
private final int rankingStop;
|
||||
private final PixivDownload.PageQuality quality;
|
||||
|
||||
/**
|
||||
* 构造一个推荐作品发送器
|
||||
* @param messageSender 消息发送器
|
||||
* @param rankingStart 排行榜开始范围(从1开始, 名次)
|
||||
* @param rankingStop 排名榜结束范围(包括该名次)
|
||||
* @param quality 图片质量, 详见{@link net.lamgc.cgj.pixiv.PixivDownload.PageQuality}
|
||||
*/
|
||||
public RandomRankingArtworksSender(MessageSender messageSender, int rankingStart, int rankingStop, PixivDownload.PageQuality quality) {
|
||||
super(messageSender);
|
||||
log = LoggerFactory.getLogger("RecommendArtworksSender@" + Integer.toHexString(this.hashCode()));
|
||||
this.rankingStart = rankingStart > 0 ? rankingStart : 1;
|
||||
this.rankingStop = rankingStop > 0 ? rankingStop : 150;
|
||||
this.quality = quality == null ? PixivDownload.PageQuality.REGULAR : quality;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send() {
|
||||
Date queryDate = new Date();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(queryDate);
|
||||
if(calendar.get(Calendar.HOUR_OF_DAY) < 12) {
|
||||
calendar.add(Calendar.DAY_OF_YEAR, -2);
|
||||
} else {
|
||||
calendar.add(Calendar.DAY_OF_YEAR, -1);
|
||||
}
|
||||
queryDate = calendar.getTime();
|
||||
|
||||
int selectRanking = rankingStart + new Random().nextInt(rankingStop + 1);
|
||||
try {
|
||||
List<JsonObject> rankingList = BotCommandProcess.getRankingInfoByCache(
|
||||
PixivURL.RankingContentType.TYPE_ILLUST,
|
||||
PixivURL.RankingMode.MODE_DAILY,
|
||||
queryDate,
|
||||
selectRanking,
|
||||
1, false);
|
||||
|
||||
log.info("RankingResult.size: {}", rankingList.size());
|
||||
if(rankingList.size() != 1) {
|
||||
log.error("排行榜选取失败!(获取到了多个结果)");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject rankingInfo = rankingList.get(0);
|
||||
int illustId = rankingInfo.get("illust_id").getAsInt();
|
||||
if(BotCommandProcess.isNoSafe(illustId, BotCommandProcess.globalProp, false)) {
|
||||
log.warn("作品为r18作品, 取消本次发送.");
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("#美图推送 - 今日排行榜 第 ").append(rankingInfo.get("rank").getAsInt()).append(" 名\n");
|
||||
message.append("标题:").append(rankingInfo.get("title").getAsString()).append("(").append(illustId).append(")\n");
|
||||
message.append("作者:").append(rankingInfo.get("user_name").getAsString()).append("\n");
|
||||
message.append(BotCommandProcess.getImageById(illustId, quality, 1));
|
||||
|
||||
getMessageSender().sendMessage(message.toString());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpHost;
|
||||
@ -256,8 +257,8 @@ public class PixivDownload {
|
||||
public static List<JsonObject> getRanking(List<JsonObject> rankingList, int rankStart, int range) {
|
||||
log.debug("正在读取JsonArray...(rankStart: {}, range: {})", rankStart, range);
|
||||
ArrayList<JsonObject> results = new ArrayList<>(rankingList.size());
|
||||
for (int rankIndex = rankStart; rankIndex < rankingList.size() && rankIndex < range; rankIndex++) {
|
||||
JsonElement jsonElement = rankingList.get(rankIndex);
|
||||
for (int rankIndex = rankStart; rankIndex < rankStart + range; rankIndex++) {
|
||||
JsonElement jsonElement = rankingList.get(rankIndex - rankStart);
|
||||
JsonObject rankInfo = jsonElement.getAsJsonObject();
|
||||
int rank = rankInfo.get("rank").getAsInt();
|
||||
int illustId = rankInfo.get("illust_id").getAsInt();
|
||||
@ -279,21 +280,8 @@ public class PixivDownload {
|
||||
* @return 返回List对象
|
||||
*/
|
||||
public static List<JsonObject> getRanking(JsonArray rankingArray, int rankStart, int range) {
|
||||
log.debug("正在读取JsonArray...(rankStart: {}, range: {})", rankStart, range);
|
||||
ArrayList<JsonObject> results = new ArrayList<>(rankingArray.size());
|
||||
for (int rankIndex = rankStart; rankIndex < rankingArray.size() && rankIndex < range; rankIndex++) {
|
||||
JsonElement jsonElement = rankingArray.get(rankIndex);
|
||||
JsonObject rankInfo = jsonElement.getAsJsonObject();
|
||||
int rank = rankInfo.get("rank").getAsInt();
|
||||
int illustId = rankInfo.get("illust_id").getAsInt();
|
||||
int authorId = rankInfo.get("user_id").getAsInt();
|
||||
String authorName = rankInfo.get("user_name").getAsString();
|
||||
String title = rankInfo.get("title").getAsString();
|
||||
log.debug("Array-当前到第 {}/{} 名(总共 {} 名), IllustID: {}, Author: ({}) {}, Title: {}", rank, rankStart + range, range, illustId, authorId, authorName, title);
|
||||
results.add(rankInfo);
|
||||
}
|
||||
log.debug("JsonArray读取完成.");
|
||||
return results;
|
||||
List<JsonObject> list = new Gson().fromJson(rankingArray, new TypeToken<List<JsonObject>>(){}.getType());
|
||||
return getRanking(list, rankStart, range);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,65 +292,44 @@ public class PixivDownload {
|
||||
* @param rankStart 开始排名, 从1开始
|
||||
* @param range 取范围
|
||||
* @return 成功返回有值List, 失败且无异常返回空
|
||||
* @throws IOException 获取异常时抛出
|
||||
* @throws IllegalArgumentException 当{@linkplain net.lamgc.cgj.pixiv.PixivURL.RankingContentType RankingContentType}
|
||||
* 与{@linkplain net.lamgc.cgj.pixiv.PixivURL.RankingMode RankingMode}互不兼容时抛出
|
||||
* @throws IndexOutOfBoundsException 当排行榜选取范围超出排行榜范围时抛出(排行榜范围为 1 ~ 500 名)
|
||||
* @throws IOException 当Http请求发生异常时抛出, 或Http请求响应码非200时抛出
|
||||
*/
|
||||
public List<JsonObject> getRanking(PixivURL.RankingContentType contentType, PixivURL.RankingMode mode,
|
||||
Date time, int rankStart, int range) throws IOException {
|
||||
if(rankStart <= 0) {
|
||||
throw new IllegalArgumentException("rankStart cannot be less than or equal to zero");
|
||||
}
|
||||
if(range <= 0) {
|
||||
throw new IllegalArgumentException("range cannot be less than or equal to zero");
|
||||
}
|
||||
|
||||
if(!contentType.isSupportedMode(mode)) {
|
||||
if(!Objects.requireNonNull(contentType).isSupportedMode(Objects.requireNonNull(mode))) {
|
||||
throw new IllegalArgumentException("ContentType不支持指定的RankingMode: ContentType: " + contentType.name() + ", Mode: " + mode.name());
|
||||
} else if(rankStart <= 0) {
|
||||
throw new IndexOutOfBoundsException("rankStart cannot be less than or equal to zero: " + rankStart);
|
||||
} else if(range <= 0) {
|
||||
throw new IndexOutOfBoundsException("range cannot be less than or equal to zero:" + range);
|
||||
} else if(rankStart + range - 1 > 500) {
|
||||
throw new IndexOutOfBoundsException("排名选取范围超出了排行榜范围: rankStart=" + rankStart + ", range=" + range + ", length:" + (rankStart + range - 1));
|
||||
}
|
||||
|
||||
int startPage = (int) Math.ceil(rankStart / 50F);
|
||||
int requestFrequency = (int) Math.ceil((rankStart + (range - 1)) / 50F);
|
||||
int surplusQuantity = range;
|
||||
boolean firstRequest = true;
|
||||
int startPages = (int) Math.max(1, Math.floor(rankStart / 50F));
|
||||
int endPages = (int) Math.min(10, Math.ceil((rankStart + range) / 50F));
|
||||
int startIndex = rankStart - 1;
|
||||
int count = 0;
|
||||
Gson gson = new Gson();
|
||||
ArrayList<JsonObject> results = new ArrayList<>();
|
||||
for (int requestCount = startPage; requestCount <= requestFrequency && requestCount <= 10; requestCount++) {
|
||||
int rangeStart = (requestCount - 1) * 50 + 1;
|
||||
log.debug("正在请求第 {} 到 {} 位排名榜 (第{}次请求, 共 {} 次)", rangeStart, rangeStart + 49, requestCount - startPage + 1, requestFrequency - startPage + 1);
|
||||
HttpGet request = createHttpGetRequest(PixivURL.getRankingLink(contentType, mode, time, requestCount, true));
|
||||
log.debug("Request URL: {}", request.getURI());
|
||||
ArrayList<JsonObject> results = new ArrayList<>(range);
|
||||
for (int pageIndex = startPages; pageIndex <= endPages && count < range; pageIndex++) {
|
||||
HttpGet request = createHttpGetRequest(PixivURL.getRankingLink(contentType, mode, time, pageIndex, true));
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
String content = EntityUtils.toString(response.getEntity());
|
||||
log.debug("Content: " + content);
|
||||
JsonObject contentObject = gson.fromJson(content, JsonObject.class);
|
||||
if(contentObject.has("error")) {
|
||||
log.warn("接口报错, 返回信息: {}", contentObject.get("error").getAsString());
|
||||
break;
|
||||
}
|
||||
JsonArray rankingArray = contentObject.getAsJsonArray("contents");
|
||||
log.debug("正在解析数据...");
|
||||
|
||||
//需要添加一个总量, 否则会完整跑完一次.
|
||||
//检查是否为最后一次请求,和剩余量有多少
|
||||
int firstRequestStartIndex = (rankStart % 50) - 1;
|
||||
for (int rankIndex = firstRequest ? firstRequestStartIndex : 0; rankIndex < rankingArray.size() && surplusQuantity > 0; rankIndex++, surplusQuantity--) {
|
||||
JsonElement jsonElement = rankingArray.get(rankIndex);
|
||||
JsonObject rankInfo = jsonElement.getAsJsonObject();
|
||||
int rank = rankInfo.get("rank").getAsInt();
|
||||
int illustId = rankInfo.get("illust_id").getAsInt();
|
||||
int authorId = rankInfo.get("user_id").getAsInt();
|
||||
String authorName = rankInfo.get("user_name").getAsString();
|
||||
String title = rankInfo.get("title").getAsString();
|
||||
log.debug("Download-当前到第 {}/{} 名(总共 {} 名), IllustID: {}, Author: ({}) {}, Title: {}", rank, rankStart + range - 1, range, illustId, authorId, authorName, title);
|
||||
results.add(rankInfo);
|
||||
}
|
||||
firstRequest = false;
|
||||
log.debug("第 {} 到 {} 位排名榜完成. (第{}次请求)", rangeStart, rangeStart + 49, requestCount);
|
||||
if(response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new IOException("Http Response Error: " + response.getStatusLine());
|
||||
}
|
||||
|
||||
if(requestFrequency > 10) {
|
||||
log.warn("请求的排名榜范围超出所支持的范围, 已终止请求.");
|
||||
JsonArray resultArray = gson.fromJson(EntityUtils.toString(response.getEntity()), JsonObject.class).getAsJsonArray("contents");
|
||||
for (int resultIndex = startIndex; resultIndex < resultArray.size() && count < range; resultIndex++, count++) {
|
||||
results.add(resultArray.get(resultIndex).getAsJsonObject());
|
||||
}
|
||||
// 重置索引
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user