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.

219 lines
6.4 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", query: query);
if (!mwRes.ok) {
return MWResponse(errorList: mwRes.errorList);
}
if (mwRes.data != null) {
var rcRes = RecentChangesResponse.fromJson(mwRes.data!);
return MWResponse(
ok: true,
data: rcRes.recentchanges,
continueInfo: mwRes.continueInfo);
} else {
return MWResponse(
errorList: [MWError(code: 'response_data_empty', info: '加载的数据为空')]);
}
}
/// 获取合并的最近更改列表(包括新页面和最近更新)
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>>(ok: true, data: []))
: getRecentChanges("new",
limit: limit, continueInfo: continueInfoNew),
ignoreRcEdit
? Future.value(
MWResponse<List<RecentChangesItem>>(ok: true, data: []))
: getRecentChanges("edit",
limit: limit, continueInfo: continueInfoEdit),
]);
var rcNewRes = rcResList[0];
var rcEditRes = rcResList[1];
if (!rcNewRes.ok) {
return MWResponse(errorList: rcNewRes.errorList);
} else if (!rcEditRes.ok) {
return MWResponse(errorList: rcNewRes.errorList);
}
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(
ok: true,
data: 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", query: query);
if (!mwRes.ok) {
return MWResponse(errorList: mwRes.errorList);
}
if (mwRes.data != null) {
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 MWResponse(
ok: true, data: sortedPages, continueInfo: mwRes.continueInfo);
} else {
return MWResponse(
errorList: [MWError(code: 'response_data_empty', info: '加载的数据为空')]);
}
}
}