You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
5.3 KiB
Dart

import 'package:isekai_wiki/api/mw/mw_api.dart';
import 'package:isekai_wiki/api/response/page_info.dart';
import 'package:isekai_wiki/api/response/recent_changes.dart';
class MWApiList {
/// 获取最近更改列表
static Future<MWResponse<List<RecentChangesItem>>> getRecentChanges(String type,
{int? limit, Map<String, String>? continueInfo}) async {
var query = {
"list": "recentchanges",
"rctype": type,
"rcnamespace": 0,
"rclimit": limit,
};
if (continueInfo != null && continueInfo.containsKey("rccontinue")) {
query["rccontinue"] = continueInfo["rccontinue"];
}
var mwRes = await MWApi.get("query", params: query);
var rcRes = RecentChangesResponse.fromJson(mwRes.data);
return mwRes.replaceData(rcRes.recentchanges);
}
/// 获取合并的最近更改列表(包括新页面和最近更新)
static Future<MWResponse<List<RecentChangesItem>>> getMixedRecentChanges(
{int? limit, Map<String, String>? continueInfo}) async {
Map<String, String> continueInfoNew = {};
Map<String, String> continueInfoEdit = {};
bool ignoreRcNew = false;
bool ignoreRcEdit = false;
if (continueInfo != null) {
ignoreRcNew = true;
ignoreRcEdit = true;
if (continueInfo.containsKey("rcnewcontinue")) {
continueInfoNew["rccontinue"] = continueInfo["rcnewcontinue"]!;
ignoreRcNew = false;
}
if (continueInfo.containsKey("rceditcontinue")) {
continueInfoEdit["rccontinue"] = continueInfo["rceditcontinue"]!;
ignoreRcEdit = false;
}
}
var rcResList = await Future.wait([
ignoreRcNew
? Future.value(MWResponse<List<RecentChangesItem>>([]))
: getRecentChanges("new", limit: limit, continueInfo: continueInfoNew),
ignoreRcEdit
? Future.value(MWResponse<List<RecentChangesItem>>([]))
: getRecentChanges("edit", limit: limit, continueInfo: continueInfoEdit),
]);
var rcNewRes = rcResList[0];
var rcEditRes = rcResList[1];
List<RecentChangesItem> mergedList = [...rcNewRes.data, ...rcEditRes.data];
mergedList.sort((a, b) {
// 为新页面添加7天的保护期
var timeA = a.type == "new" ? a.timestamp.add(const Duration(days: 7)) : a.timestamp;
var timeB = b.type == "new" ? b.timestamp.add(const Duration(days: 7)) : b.timestamp;
return timeB.compareTo(timeA);
});
List<RecentChangesItem> uniqueMergedList = [];
for (var page in mergedList) {
if (uniqueMergedList.indexWhere((element) => element.pageid == page.pageid) == -1) {
uniqueMergedList.add(page);
}
}
Map<String, String> mergedContinueInfo = {};
if (rcNewRes.continueInfo != null && rcNewRes.continueInfo!.containsKey("rccontinue")) {
mergedContinueInfo["rcnewcontinue"] = rcNewRes.continueInfo!["rccontinue"]!;
}
if (rcEditRes.continueInfo != null && rcEditRes.continueInfo!.containsKey("rccontinue")) {
mergedContinueInfo["rceditcontinue"] = rcEditRes.continueInfo!["rccontinue"]!;
}
return MWResponse(
uniqueMergedList,
continueInfo: mergedContinueInfo.isNotEmpty ? mergedContinueInfo : null,
);
}
static Future<MWResponse<List<PageInfo>>> getPageInfoList(
{List<int>? pageids,
List<String>? titles,
List<String>? prop,
Map<String, dynamic>? extraParams,
bool getInWatchlist = false,
int extractChars = 200}) async {
prop ??= ["extracts", "info", "pageimages"];
Map<String, dynamic> query = {
"redirects": 1,
"converttitles": 1,
"exintro": 1,
"explaintext": 1,
"exchars": extractChars,
"inprop": "url",
"piprop": "thumbnail",
"pithumbsize": 640,
"pilicense": "any"
};
if (getInWatchlist) {
prop.add("inwatchlist");
}
query["prop"] = prop.join("|");
if (pageids != null) {
query["pageids"] = pageids.join("|");
}
if (titles != null) {
query["titles"] = titles.join("|");
}
if (extraParams != null) {
query.addAll(extraParams);
}
var mwRes = await MWApi.get("query", params: query);
var pagesRes = PagesResponse.fromJson(mwRes.data);
var pageList = pagesRes.pages.map((pageInfo) {
if (pageInfo.description != null) {
pageInfo.description = pageInfo.description!.replaceAll(RegExp(r"\n\n"), "\n");
}
if (pageInfo.title.contains("/")) {
var splitPos = pageInfo.title.lastIndexOf("/");
pageInfo.displayTitle = pageInfo.title.substring(splitPos + 1);
pageInfo.subtitle = pageInfo.title.substring(0, splitPos);
} else {
pageInfo.displayTitle = pageInfo.title;
}
return pageInfo;
}).toList();
// 按照传入顺序对页面进行排序
List<PageInfo> sortedPages = [];
if (pageids != null) {
for (var pageid in pageids) {
var index = pageList.indexWhere((element) => element.pageid == pageid);
if (index != -1) {
sortedPages.add(pageList[index]);
}
}
}
if (titles != null) {
for (var title in titles) {
var index = pagesRes.pages.indexWhere((element) => element.title == title);
if (index != -1) {
sortedPages.add(pagesRes.pages[index]);
}
}
}
return mwRes.replaceData(sortedPages);
}
}