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
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: '加载的数据为空')]);
|
|
}
|
|
}
|
|
}
|