mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
163 lines
4.2 KiB
Dart
163 lines
4.2 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'package:venera/foundation/favorites.dart';
|
|
import 'package:venera/foundation/log.dart';
|
|
|
|
class ComicUpdateResult {
|
|
final bool updated;
|
|
final String? errorMessage;
|
|
|
|
ComicUpdateResult(this.updated, this.errorMessage);
|
|
}
|
|
|
|
Future<ComicUpdateResult> updateComic(
|
|
FavoriteItemWithUpdateInfo c, String folder) async {
|
|
int retries = 3;
|
|
while (true) {
|
|
try {
|
|
var comicSource = c.type.comicSource;
|
|
if (comicSource == null) {
|
|
return ComicUpdateResult(false, "Comic source not found");
|
|
}
|
|
var newInfo = (await comicSource.loadComicInfo!(c.id)).data;
|
|
|
|
var newTags = <String>[];
|
|
for (var entry in newInfo.tags.entries) {
|
|
const shouldIgnore = ['author', 'artist', 'time'];
|
|
var namespace = entry.key;
|
|
if (shouldIgnore.contains(namespace.toLowerCase())) {
|
|
continue;
|
|
}
|
|
for (var tag in entry.value) {
|
|
newTags.add("$namespace:$tag");
|
|
}
|
|
}
|
|
|
|
var item = FavoriteItem(
|
|
id: c.id,
|
|
name: newInfo.title,
|
|
coverPath: newInfo.cover,
|
|
author: newInfo.subTitle ??
|
|
newInfo.tags['author']?.firstOrNull ??
|
|
c.author,
|
|
type: c.type,
|
|
tags: newTags,
|
|
);
|
|
|
|
LocalFavoritesManager().updateInfo(folder, item, false);
|
|
|
|
var updated = false;
|
|
var updateTime = newInfo.findUpdateTime();
|
|
if (updateTime != null && updateTime != c.updateTime) {
|
|
LocalFavoritesManager().updateUpdateTime(
|
|
folder,
|
|
c.id,
|
|
c.type,
|
|
updateTime,
|
|
);
|
|
updated = true;
|
|
} else {
|
|
LocalFavoritesManager().updateCheckTime(folder, c.id, c.type);
|
|
}
|
|
return ComicUpdateResult(updated, null);
|
|
} catch (e, s) {
|
|
Log.error("Check Updates", e, s);
|
|
retries--;
|
|
if (retries == 0) {
|
|
return ComicUpdateResult(false, e.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class UpdateProgress {
|
|
final int total;
|
|
final int current;
|
|
final int errors;
|
|
final int updated;
|
|
final FavoriteItemWithUpdateInfo? comic;
|
|
final String? errorMessage;
|
|
|
|
UpdateProgress(this.total, this.current, this.errors, this.updated,
|
|
[this.comic, this.errorMessage]);
|
|
}
|
|
|
|
void updateFolderBase(
|
|
String folder,
|
|
StreamController<UpdateProgress> stream,
|
|
bool ignoreCheckTime,
|
|
) async {
|
|
var comics = LocalFavoritesManager().getComicsWithUpdatesInfo(folder);
|
|
int total = comics.length;
|
|
int current = 0;
|
|
int errors = 0;
|
|
int updated = 0;
|
|
|
|
stream.add(UpdateProgress(total, current, errors, updated));
|
|
|
|
var comicsToUpdate = <FavoriteItemWithUpdateInfo>[];
|
|
|
|
for (var comic in comics) {
|
|
if (!ignoreCheckTime) {
|
|
var lastCheckTime = comic.lastCheckTime;
|
|
if (lastCheckTime != null &&
|
|
DateTime.now().difference(lastCheckTime).inDays < 1) {
|
|
current++;
|
|
stream.add(UpdateProgress(total, current, errors, updated));
|
|
continue;
|
|
}
|
|
}
|
|
comicsToUpdate.add(comic);
|
|
}
|
|
|
|
total = comicsToUpdate.length;
|
|
current = 0;
|
|
stream.add(UpdateProgress(total, current, errors, updated));
|
|
|
|
var futures = <Future>[];
|
|
for (var comic in comicsToUpdate) {
|
|
var future = updateComic(comic, folder).then((result) {
|
|
current++;
|
|
if (result.updated) {
|
|
updated++;
|
|
}
|
|
if (result.errorMessage != null) {
|
|
errors++;
|
|
}
|
|
stream.add(
|
|
UpdateProgress(total, current, errors, updated, comic, result.errorMessage));
|
|
});
|
|
futures.add(future);
|
|
}
|
|
|
|
await Future.wait(futures);
|
|
|
|
if (updated > 0) {
|
|
LocalFavoritesManager().notifyChanges();
|
|
}
|
|
|
|
stream.close();
|
|
}
|
|
|
|
|
|
Stream<UpdateProgress> updateFolder(String folder, bool ignoreCheckTime) {
|
|
var stream = StreamController<UpdateProgress>();
|
|
updateFolderBase(folder, stream, ignoreCheckTime);
|
|
return stream.stream;
|
|
}
|
|
|
|
Future<String> getUpdatedComicsAsJson(String folder) async {
|
|
var comics = LocalFavoritesManager().getComicsWithUpdatesInfo(folder);
|
|
var updatedComics = comics.where((c) => c.hasNewUpdate).toList();
|
|
var jsonList = updatedComics.map((c) => {
|
|
'id': c.id,
|
|
'name': c.name,
|
|
'coverUrl': c.coverPath,
|
|
'author': c.author,
|
|
'type': c.type.sourceKey,
|
|
'updateTime': c.updateTime,
|
|
'tags': c.tags,
|
|
}).toList();
|
|
return jsonEncode(jsonList);
|
|
}
|