mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-04-30 06:37:36 +00:00
[Add] 为搜索命令优化翻页功能;
[Change] BotCommandProcess 重制search命令, 增加用于获取范围相关搜索结果页面的`getSearchResult`方法, 调整消息格式;
This commit is contained in:
parent
d23bae5306
commit
2f3417705d
@ -13,8 +13,10 @@ import net.lamgc.cgj.bot.sort.PreLoadDataAttribute;
|
|||||||
import net.lamgc.cgj.bot.sort.PreLoadDataAttributeComparator;
|
import net.lamgc.cgj.bot.sort.PreLoadDataAttributeComparator;
|
||||||
import net.lamgc.cgj.pixiv.PixivDownload;
|
import net.lamgc.cgj.pixiv.PixivDownload;
|
||||||
import net.lamgc.cgj.pixiv.PixivDownload.PageQuality;
|
import net.lamgc.cgj.pixiv.PixivDownload.PageQuality;
|
||||||
|
import net.lamgc.cgj.pixiv.PixivSearchAttribute;
|
||||||
import net.lamgc.cgj.pixiv.PixivSearchLinkBuilder;
|
import net.lamgc.cgj.pixiv.PixivSearchLinkBuilder;
|
||||||
import net.lamgc.cgj.pixiv.PixivURL;
|
import net.lamgc.cgj.pixiv.PixivURL;
|
||||||
|
import net.lamgc.cgj.util.PixivUtils;
|
||||||
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;
|
||||||
@ -40,6 +42,8 @@ public class BotCommandProcess {
|
|||||||
|
|
||||||
private final static RankingUpdateTimer updateTimer = new RankingUpdateTimer();
|
private final static RankingUpdateTimer updateTimer = new RankingUpdateTimer();
|
||||||
|
|
||||||
|
private final static int SEARCH_PAGE_MAX_ITEM = 60;
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
log.info("正在初始化...");
|
log.info("正在初始化...");
|
||||||
|
|
||||||
@ -321,12 +325,9 @@ public class BotCommandProcess {
|
|||||||
@Argument(name = "option", force = false) String contentOption,
|
@Argument(name = "option", force = false) String contentOption,
|
||||||
@Argument(name = "p", force = false, defaultValue = "1") int pagesIndex
|
@Argument(name = "p", force = false, defaultValue = "1") int pagesIndex
|
||||||
) throws IOException, InterruptedException {
|
) throws IOException, InterruptedException {
|
||||||
|
PixivSearchLinkBuilder searchLinkBuilder = PixivUtils.buildSearchLinkBuilderFromString(content, type, area,
|
||||||
|
includeKeywords, excludeKeywords, contentOption, pagesIndex);
|
||||||
log.debug("正在执行搜索...");
|
log.debug("正在执行搜索...");
|
||||||
JsonObject resultBody = CacheStoreCentral.getCentral()
|
|
||||||
.getSearchBody(content, type, area, includeKeywords, excludeKeywords, contentOption, pagesIndex);
|
|
||||||
|
|
||||||
StringBuilder result = new StringBuilder("内容 " + content + " 的搜索结果:\n");
|
|
||||||
log.debug("正在处理信息...");
|
|
||||||
int limit = 8;
|
int limit = 8;
|
||||||
try {
|
try {
|
||||||
limit = Integer.parseInt(SettingProperties.
|
limit = Integer.parseInt(SettingProperties.
|
||||||
@ -334,95 +335,121 @@ public class BotCommandProcess {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("参数转换异常!将使用默认值(" + limit + ")", e);
|
log.warn("参数转换异常!将使用默认值(" + limit + ")", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
for (PixivSearchLinkBuilder.SearchArea searchArea : PixivSearchLinkBuilder.SearchArea.values()) {
|
StringBuilder result = new StringBuilder("内容 " + content + " 的搜索结果:\n");
|
||||||
if (!resultBody.has(searchArea.jsonKey) ||
|
List<JsonObject> artworkList = getSearchResult(searchLinkBuilder, fromGroup, limit, pagesIndex);
|
||||||
resultBody.getAsJsonObject(searchArea.jsonKey).getAsJsonArray("data").size() == 0) {
|
artworkList.sort(new PreLoadDataAttributeComparator(PreLoadDataAttribute.LIKE));
|
||||||
log.debug("返回数据不包含 {}", searchArea.jsonKey);
|
int startIndex = limit * pagesIndex - limit + 1;
|
||||||
continue;
|
int pageStartIndex = startIndex % SEARCH_PAGE_MAX_ITEM;
|
||||||
}
|
for(int index = pageStartIndex; totalCount < limit && index < artworkList.size(); index++) {
|
||||||
JsonArray illustsArray = resultBody
|
int illustId = artworkList.get(index - 1).get("illustId").getAsInt();
|
||||||
.getAsJsonObject(searchArea.jsonKey).getAsJsonArray("data");
|
// 预加载数据有更多信息可以提供
|
||||||
ArrayList<JsonElement> illustsList = new ArrayList<>();
|
JsonObject artworkPreLoadData = CacheStoreCentral.getCentral()
|
||||||
illustsArray.forEach(illustsList::add);
|
|
||||||
illustsList.sort(new PreLoadDataAttributeComparator(PreLoadDataAttribute.BOOKMARK));
|
|
||||||
|
|
||||||
log.debug("已找到与 {} 相关插图信息({}):", content, searchArea.name().toLowerCase());
|
|
||||||
int count = 1;
|
|
||||||
for (JsonElement jsonElement : illustsList) {
|
|
||||||
if (count > limit) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
JsonObject illustObj = jsonElement.getAsJsonObject();
|
|
||||||
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.debug("{} ({} / {})\n\t作品id: {}, \n\t作者名(作者id): {} ({}), \n\t" +
|
|
||||||
"作品标题: {}, \n\t作品Tags: {}, \n\t页数: {}页, \n\t作品链接: {}",
|
|
||||||
searchArea.name(),
|
|
||||||
count,
|
|
||||||
illustsList.size(),
|
|
||||||
illustId,
|
|
||||||
illustObj.get("userName").getAsString(),
|
|
||||||
illustObj.get("userId").getAsInt(),
|
|
||||||
illustObj.get("illustTitle").getAsString(),
|
|
||||||
builder,
|
|
||||||
illustObj.get("pageCount").getAsInt(),
|
|
||||||
PixivURL.getPixivRefererLink(illustId)
|
|
||||||
);
|
|
||||||
|
|
||||||
String imageMsg;
|
|
||||||
try {
|
|
||||||
imageMsg = CacheStoreCentral.getCentral()
|
|
||||||
.getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1);
|
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
if(e.getMessage().startsWith("No work found: ")) {
|
|
||||||
log.warn("作品 {} 不存在, 跳过该作品...", illustId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
if (isNoSafe(illustId, SettingProperties.getProperties(fromGroup), false)) {
|
|
||||||
log.warn("作品Id {} 为R-18作品, 跳过.", illustId);
|
|
||||||
continue;
|
|
||||||
} else if(isReported(illustId)) {
|
|
||||||
log.warn("作品Id {} 被报告, 正在等待审核, 跳过该作品.", illustId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject illustPreLoadData = CacheStoreCentral.getCentral()
|
|
||||||
.getIllustPreLoadData(illustId, false);
|
.getIllustPreLoadData(illustId, false);
|
||||||
result.append(searchArea.name()).append(" (").append(count).append(" / ")
|
|
||||||
.append(limit).append(")\n\t作品id: ").append(illustId)
|
// 构造消息内容
|
||||||
.append(", \n\t作者名: ").append(illustObj.get("userName").getAsString())
|
result.append(startIndex++).append(". (").append(artworkPreLoadData.get("illustId").getAsInt()).append(") ")
|
||||||
.append("\n\t作品标题: ").append(illustObj.get("illustTitle").getAsString())
|
.append(artworkPreLoadData.get("illustTitle").getAsString());
|
||||||
.append("\n\t作品页数: ").append(illustObj.get("pageCount").getAsInt()).append("页")
|
result.append("\n\t").append("作者:").append(artworkPreLoadData.get("userName").getAsString());
|
||||||
.append("\n\t点赞数:")
|
result.append("\n\t").append("作品页数:").append(artworkPreLoadData.get("pageCount").getAsInt()).append(" 页");
|
||||||
.append(illustPreLoadData.get(PreLoadDataAttribute.LIKE.attrName).getAsInt())
|
result.append("\n\t").append("点赞数:")
|
||||||
.append("\n\t收藏数:")
|
.append(artworkPreLoadData.get(PreLoadDataAttribute.LIKE.attrName).getAsInt()).append(" 页");
|
||||||
.append(illustPreLoadData.get(PreLoadDataAttribute.BOOKMARK.attrName).getAsInt())
|
result.append("\n\t").append("收藏数:")
|
||||||
.append("\n\t围观数:")
|
.append(artworkPreLoadData.get(PreLoadDataAttribute.BOOKMARK.attrName).getAsInt()).append(" 页");
|
||||||
.append(illustPreLoadData.get(PreLoadDataAttribute.VIEW.attrName).getAsInt())
|
result.append("\n\t").append("围观数:")
|
||||||
.append("\n\t评论数:")
|
.append(artworkPreLoadData.get(PreLoadDataAttribute.VIEW.attrName).getAsInt()).append(" 页");
|
||||||
.append(illustPreLoadData.get(PreLoadDataAttribute.COMMENT.attrName).getAsInt())
|
result.append("\n\t").append("评论数:")
|
||||||
.append("\n").append(imageMsg).append("\n");
|
.append(artworkPreLoadData.get(PreLoadDataAttribute.COMMENT.attrName).getAsInt()).append(" 页");
|
||||||
count++;
|
result.append(CacheStoreCentral.getCentral()
|
||||||
|
.getImageById(fromGroup, illustId, PageQuality.REGULAR, 1)).append("\n");
|
||||||
totalCount++;
|
totalCount++;
|
||||||
}
|
}
|
||||||
if (count > limit) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalCount <= 0 ?
|
return totalCount <= 0 ?
|
||||||
"搜索完成,未找到相关作品。" :
|
"搜索完成,未找到相关作品。" :
|
||||||
Strings.nullToEmpty(result.toString()) + "预览图片并非原图,使用“.cgj image -id 作品id”获取原图\n" +
|
Strings.nullToEmpty(result.toString()) + "预览图片并非原图,使用“.cgj image -id 作品id”获取原图\n" +
|
||||||
"如有不当作品,可使用\".cgj report -id 作品id\"向色图姬反馈。";
|
"如有不当作品,可使用\".cgj report -id 作品id\"向色图姬反馈。";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 length 涉及的多个页的搜索结果.
|
||||||
|
* 例如:
|
||||||
|
* pageMaxItem = 60;
|
||||||
|
* length = 150;
|
||||||
|
* page = 3;
|
||||||
|
* 那么:
|
||||||
|
* endItemIndex = length * page = 450;
|
||||||
|
* startItemIndex = endItemIndex - length + 1 = 301;
|
||||||
|
* startPageIndex = ceil(startItemIndex / pageMaxItem) = 6;
|
||||||
|
* pageRange = ceil((endItemIndex - length + 1) / pageMaxItem) = 3;
|
||||||
|
* endPageIndex = startPageIndex - pageRange - 1 = 8;
|
||||||
|
* 该方法将会取搜索结果的 6 ~ 8 页结果并返回;
|
||||||
|
* @param searchLinkBuilder 已构造好除 Page 参数外其他参数的 {@link PixivSearchLinkBuilder}
|
||||||
|
* @param length 所需结果的范围
|
||||||
|
* @param page 所需结果的页数
|
||||||
|
* @return 返回包含范围的涉及页面所有搜索结果.
|
||||||
|
* @throws IOException 如获取发生异常则抛出.
|
||||||
|
*/
|
||||||
|
private static List<JsonObject> getSearchResult(PixivSearchLinkBuilder searchLinkBuilder, long groupId, int length, int page) throws IOException {
|
||||||
|
List<JsonObject> artworkList = new ArrayList<>(length);
|
||||||
|
|
||||||
|
int endsItemIndex = length * page;
|
||||||
|
int startsItemIndex = endsItemIndex - length + 1;
|
||||||
|
int startPageIndex = (int) Math.ceil(startsItemIndex / (double) SEARCH_PAGE_MAX_ITEM);
|
||||||
|
int pageRange = (int) Math.ceil((endsItemIndex - startsItemIndex) / (double) SEARCH_PAGE_MAX_ITEM);
|
||||||
|
PixivSearchAttribute areaAttribute = PixivSearchAttribute.valueOf(searchLinkBuilder.getSearchArea().toString());
|
||||||
|
Properties properties = SettingProperties.getProperties(groupId);
|
||||||
|
int expectedQuantity = pageRange * SEARCH_PAGE_MAX_ITEM;
|
||||||
|
// 一个可能不算最好的去重方法?我已经对Pixiv搜索结果完全重复的情况感到无语了 :(
|
||||||
|
Set<Integer> artworkIdSet = new HashSet<>();
|
||||||
|
int addItemCount = 0;
|
||||||
|
for(int pageIndex = startPageIndex;
|
||||||
|
pageIndex <= startPageIndex + pageRange - 1 || artworkList.size() < length || artworkList.size() < expectedQuantity;
|
||||||
|
pageIndex++) {
|
||||||
|
searchLinkBuilder.setPage(pageIndex);
|
||||||
|
JsonObject searchBody = CacheStoreCentral.getCentral().getSearchBody(searchLinkBuilder);
|
||||||
|
for(String areaAttributeName : areaAttribute.attributeNames) {
|
||||||
|
JsonObject areaResult = searchBody.getAsJsonObject(areaAttributeName);
|
||||||
|
if(areaResult == null || !areaResult.has("data")) {
|
||||||
|
log.debug("作品类型属性 {} 无搜索结果, 跳过...", areaAttributeName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray areaArray = areaResult.getAsJsonArray("data");
|
||||||
|
for(JsonElement element : areaArray) {
|
||||||
|
JsonObject artworkInfo = element.getAsJsonObject();
|
||||||
|
if(!artworkInfo.has("illustId")) {
|
||||||
|
log.warn("发现未含有illustId的JsonObject: '{}'", artworkInfo.toString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final int illustId = artworkInfo.get("illustId").getAsInt();
|
||||||
|
if(isNoSafe(illustId, properties, false)) {
|
||||||
|
log.warn("作品 {} 为R18作品, 跳过.", illustId);
|
||||||
|
continue;
|
||||||
|
} else if(isReported(illustId)) {
|
||||||
|
log.warn("作品 {} 被报告, 跳过.", illustId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(artworkIdSet.contains(illustId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
artworkIdSet.add(illustId);
|
||||||
|
artworkList.add(artworkInfo);
|
||||||
|
addItemCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(addItemCount == 0) {
|
||||||
|
log.warn("已无法获取更多作品, 停止搜索.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
addItemCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return artworkList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取作品页面的下载链接
|
* 获取作品页面的下载链接
|
||||||
* @param illustId 作品Id
|
* @param illustId 作品Id
|
||||||
|
Loading…
Reference in New Issue
Block a user