mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
add archive download
This commit is contained in:
@@ -215,6 +215,8 @@ class ComicSource {
|
||||
|
||||
final StarRatingFunc? starRatingFunc;
|
||||
|
||||
final ArchiveDownloader? archiveDownloader;
|
||||
|
||||
Future<void> loadData() async {
|
||||
var file = File("${App.dataPath}/comic_source/$key.data");
|
||||
if (await file.exists()) {
|
||||
@@ -284,6 +286,7 @@ class ComicSource {
|
||||
this.enableTagsSuggestions,
|
||||
this.enableTagsTranslate,
|
||||
this.starRatingFunc,
|
||||
this.archiveDownloader,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -465,3 +468,11 @@ class LinkHandler {
|
||||
|
||||
const LinkHandler(this.domains, this.linkToId);
|
||||
}
|
||||
|
||||
class ArchiveDownloader {
|
||||
final Future<Res<List<ArchiveInfo>>> Function(String cid) getArchives;
|
||||
|
||||
final Future<Res<String>> Function(String cid, String aid) getDownloadUrl;
|
||||
|
||||
const ArchiveDownloader(this.getArchives, this.getDownloadUrl);
|
||||
}
|
@@ -232,3 +232,14 @@ class ComicDetails with HistoryMixin {
|
||||
|
||||
ComicType get comicType => ComicType(sourceKey.hashCode);
|
||||
}
|
||||
|
||||
class ArchiveInfo {
|
||||
final String title;
|
||||
final String description;
|
||||
final String id;
|
||||
|
||||
ArchiveInfo.fromJson(Map<String, dynamic> json)
|
||||
: title = json["title"],
|
||||
description = json["description"],
|
||||
id = json["id"];
|
||||
}
|
@@ -153,11 +153,12 @@ class ComicSourceParser {
|
||||
_getValue("search.enableTagsSuggestions") ?? false,
|
||||
_getValue("comic.enableTagsTranslate") ?? false,
|
||||
_parseStarRatingFunc(),
|
||||
_parseArchiveDownloader(),
|
||||
);
|
||||
|
||||
await source.loadData();
|
||||
|
||||
if(_checkExists("init")) {
|
||||
if (_checkExists("init")) {
|
||||
Future.delayed(const Duration(milliseconds: 50), () {
|
||||
JsEngine().runCode("ComicSource.sources.$_key.init()");
|
||||
});
|
||||
@@ -988,4 +989,35 @@ class ComicSourceParser {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ArchiveDownloader? _parseArchiveDownloader() {
|
||||
if (!_checkExists("comic.archive")) {
|
||||
return null;
|
||||
}
|
||||
return ArchiveDownloader(
|
||||
(cid) async {
|
||||
try {
|
||||
var res = await JsEngine().runCode("""
|
||||
ComicSource.sources.$_key.comic.archive.getArchives(${jsonEncode(cid)})
|
||||
""");
|
||||
return Res(
|
||||
(res as List).map((e) => ArchiveInfo.fromJson(e)).toList());
|
||||
} catch (e, s) {
|
||||
Log.error("Network", "$e\n$s");
|
||||
return Res.error(e.toString());
|
||||
}
|
||||
},
|
||||
(cid, aid) async {
|
||||
try {
|
||||
var res = await JsEngine().runCode("""
|
||||
ComicSource.sources.$_key.comic.archive.getDownloadUrl(${jsonEncode(cid)}, ${jsonEncode(aid)})
|
||||
""");
|
||||
return Res(res as String);
|
||||
} catch (e, s) {
|
||||
Log.error("Network", "$e\n$s");
|
||||
return Res.error(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import 'dart:async' show Future, StreamController;
|
||||
import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:venera/network/images.dart';
|
||||
@@ -8,6 +9,8 @@ import 'cached_image.dart' as image_provider;
|
||||
class CachedImageProvider
|
||||
extends BaseImageProvider<image_provider.CachedImageProvider> {
|
||||
/// Image provider for normal image.
|
||||
///
|
||||
/// [url] is the url of the image. Local file path is also supported.
|
||||
const CachedImageProvider(this.url, {this.headers, this.sourceKey, this.cid});
|
||||
|
||||
final String url;
|
||||
@@ -20,6 +23,10 @@ class CachedImageProvider
|
||||
|
||||
@override
|
||||
Future<Uint8List> load(StreamController<ImageChunkEvent> chunkEvents) async {
|
||||
if(url.startsWith("file://")) {
|
||||
var file = File(url.substring(7));
|
||||
return file.readAsBytes();
|
||||
}
|
||||
await for (var progress in ImageDownloader.loadThumbnail(url, sourceKey, cid)) {
|
||||
chunkEvents.add(ImageChunkEvent(
|
||||
cumulativeBytesLoaded: progress.currentBytes,
|
||||
|
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math' as math;
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:dio/io.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:html/parser.dart' as html;
|
||||
import 'package:html/dom.dart' as dom;
|
||||
@@ -184,7 +185,23 @@ class JsEngine with _JSEngineApi {
|
||||
if (headers["user-agent"] == null && headers["User-Agent"] == null) {
|
||||
headers["User-Agent"] = webUA;
|
||||
}
|
||||
response = await _dio!.request(req["url"],
|
||||
var dio = _dio;
|
||||
if (headers['http_client'] == "dart:io") {
|
||||
dio = Dio(BaseOptions(
|
||||
responseType: ResponseType.plain,
|
||||
validateStatus: (status) => true,
|
||||
));
|
||||
var proxy = await AppDio.getProxy();
|
||||
dio.httpClientAdapter = IOHttpClientAdapter(
|
||||
createHttpClient: () {
|
||||
return HttpClient()
|
||||
..findProxy = (uri) => proxy == null ? "DIRECT" : "PROXY $proxy";
|
||||
},
|
||||
);
|
||||
dio.interceptors.add(CookieManagerSql(SingleInstanceCookieJar.instance!));
|
||||
dio.interceptors.add(LogInterceptor());
|
||||
}
|
||||
response = await dio!.request(req["url"],
|
||||
data: req["data"],
|
||||
options: Options(
|
||||
method: req['http_method'],
|
||||
|
Reference in New Issue
Block a user