diff --git a/lib/eval/dart/bridge/m_provider.dart b/lib/eval/dart/bridge/m_provider.dart index a26b322f..ce1a9b74 100644 --- a/lib/eval/dart/bridge/m_provider.dart +++ b/lib/eval/dart/bridge/m_provider.dart @@ -14,6 +14,7 @@ import 'package:mangayomi/eval/dart/model/m_bridge.dart'; import 'package:mangayomi/eval/dart/model/m_pages.dart'; import 'package:mangayomi/eval/dart/model/m_manga.dart'; import 'package:mangayomi/eval/dart/model/m_provider.dart'; +import 'package:mangayomi/eval/javascript/http.dart'; import 'package:mangayomi/models/video.dart'; import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart'; import 'package:mangayomi/utils/log/log.dart'; @@ -90,6 +91,15 @@ class $MProvider extends MProvider with $Bridge { BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false), ])), + 'getHeaders': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false), + ])), 'getFilterList': BridgeMethodDef(BridgeFunctionDef( returns: BridgeTypeAnnotation(BridgeTypeRef( CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])), @@ -1034,6 +1044,16 @@ class $MProvider extends MProvider with $Bridge { return list.map((e) => (e is $Value ? e.$reified : e) as Video).toList(); } + @override + Map getHeaders(String url) { + final res = $_invoke('getHeaders', [$String(url)]); + Map headers = {}; + if (res is $Map) { + headers = res.$reified.toMapStringString!; + } + return headers; + } + $MVideo _toMVideo(Video e) => $MVideo.wrap(Video(e.url, e.quality, e.originalUrl) ..headers = e.headers diff --git a/lib/eval/dart/model/m_provider.dart b/lib/eval/dart/model/m_provider.dart index 60b0efec..2b0b3e63 100644 --- a/lib/eval/dart/model/m_provider.dart +++ b/lib/eval/dart/model/m_provider.dart @@ -10,6 +10,8 @@ abstract class MProvider { String? get baseUrl; + Map getHeaders(String url); + Future getLatestUpdates(int page); Future getPopular(int page); diff --git a/lib/eval/javascript/service.dart b/lib/eval/javascript/service.dart index 0710038e..830fcdc4 100644 --- a/lib/eval/javascript/service.dart +++ b/lib/eval/javascript/service.dart @@ -30,6 +30,9 @@ class MProvider { get source() { return JSON.parse('${jsonEncode(source!.toMSource().toJson())}'); } + getHeaders(url) { + throw new Error("getHeaders not implemented"); + } async getPopular(page) { throw new Error("getPopular not implemented"); } @@ -64,6 +67,19 @@ var extention = new DefaultExtension(); '''); } + Map getHeaders(String url) { + _init(); + try { + final res = runtime + .evaluate('JSON.stringify(extention.getHeaders(`$url`))') + .stringResult; + + return (jsonDecode(res) as Map).toMapStringString!; + } catch (_) { + return {}; + } + } + Future getPopular(int page) async { _init(); final res = (await runtime.handlePromise(await runtime diff --git a/lib/modules/browse/extension/widgets/create_extension.dart b/lib/modules/browse/extension/widgets/create_extension.dart index ee3e31d8..df3aa10a 100644 --- a/lib/modules/browse/extension/widgets/create_extension.dart +++ b/lib/modules/browse/extension/widgets/create_extension.dart @@ -236,6 +236,11 @@ class TestSource extends MProvider { @override bool get supportsLatest => true; + + @override + Map getHeaders(String url) { + // TODO: implement + } @override Future getPopular(int page) async { @@ -295,13 +300,15 @@ const mangayomiSources = [{ "isManga": ${source.isManga}, "isNsfw": ${source.isNsfw}, "version": "${source.version}", - "apiUrl": "", "dateFormat": "", "dateFormatLocale": "", - "pkgName": "" + "pkgPath": "" }]; class DefaultExtension extends MProvider { + getHeaders(url) { + throw new Error("getHeaders not implemented"); + } async getPopular(page) { throw new Error("getPopular not implemented"); } diff --git a/lib/services/fetch_manga_sources.dart b/lib/services/fetch_manga_sources.dart index f41c6686..1eae7d28 100644 --- a/lib/services/fetch_manga_sources.dart +++ b/lib/services/fetch_manga_sources.dart @@ -2,8 +2,12 @@ import 'dart:convert'; import 'package:dart_eval/stdlib/core.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; +import 'package:mangayomi/eval/dart/bridge/m_source.dart'; import 'package:mangayomi/eval/dart/compiler/compiler.dart'; +import 'package:mangayomi/eval/dart/model/m_provider.dart'; import 'package:mangayomi/eval/dart/runtime/runtime.dart'; +import 'package:mangayomi/eval/javascript/http.dart'; +import 'package:mangayomi/eval/javascript/service.dart'; import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/source.dart'; import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart'; @@ -48,10 +52,10 @@ Future fetchSourcesList( if (id == source.id) { final sourc = isar.sources.getSync(id)!; final req = await http.get(Uri.parse(source.sourceCodeUrl!)); - final headers = await getHeaders(req.body, source.baseUrl!); + final headers = getSourceHeaders(source..sourceCode = req.body); isar.writeTxnSync(() { isar.sources.putSync(sourc - ..headers = headers ?? "" + ..headers = jsonEncode(headers) ..isAdded = true ..sourceCode = req.body ..sourceCodeUrl = source.sourceCodeUrl @@ -85,10 +89,11 @@ Future fetchSourcesList( if (ref.watch(autoUpdateExtensionsStateProvider)) { final req = await http.get(Uri.parse(source.sourceCodeUrl!)); - final headers = await getHeaders(req.body, source.baseUrl!); + final headers = + getSourceHeaders(source..sourceCode = req.body); isar.writeTxnSync(() { isar.sources.putSync(sourc - ..headers = headers ?? "" + ..headers = jsonEncode(headers) ..isAdded = true ..sourceCode = req.body ..sourceCodeUrl = source.sourceCodeUrl @@ -197,22 +202,41 @@ int compareVersions(String version1, String version2) { return 0; } -Future getHeaders(String codeSource, String baseUrl) async { +Map getHeaders(Source source) { + Map headers = {}; try { - final bytecode = compilerEval(codeSource); + final bytecode = compilerEval(source.sourceCode!); final runtime = runtimeEval(bytecode); - runtime.args = [$String(baseUrl)]; - var res = await runtime.executeLib( + runtime.args = [$String(source.baseUrl!)]; + var res = runtime.executeLib( 'package:mangayomi/main.dart', 'getHeader', ); - Map headers = {}; if (res is $Map) { - headers = res.$reified - .map((key, value) => MapEntry(key.toString(), value.toString())); + headers = (res.$reified).toMapStringString!; } - return jsonEncode(headers); + return headers; } catch (_) { - return null; + try { + final bytecode = compilerEval(source.sourceCode!); + final runtime = runtimeEval(bytecode); + + var res = runtime.executeLib('package:mangayomi/main.dart', 'main', + [$MSource.wrap(source.toMSource())]); + headers = (res as MProvider).getHeaders(source.baseUrl!); + } catch (_) { + return {}; + } } + return {}; +} + +Map getSourceHeaders(Source source) { + Map headers = {}; + if (source.sourceCodeLanguage == SourceCodeLanguage.javascript) { + headers = JsExtensionService(source).getHeaders(source.baseUrl ?? ""); + } else { + headers = getHeaders(source); + } + return headers; } diff --git a/lib/sources/source_test.dart b/lib/sources/source_test.dart index af730d3a..2a3b3567 100644 --- a/lib/sources/source_test.dart +++ b/lib/sources/source_test.dart @@ -29,6 +29,11 @@ class TestSource extends MProvider { @override bool get supportsLatest => true; + + @override + Map getHeaders(String url) { + // TODO: implement + } @override Future getPopular(int page) async { diff --git a/lib/utils/headers.dart b/lib/utils/headers.dart index ef5e81be..f3f86417 100644 --- a/lib/utils/headers.dart +++ b/lib/utils/headers.dart @@ -1,4 +1,6 @@ import 'dart:convert'; +import 'package:mangayomi/eval/javascript/http.dart'; +import 'package:mangayomi/services/fetch_manga_sources.dart'; import 'package:mangayomi/services/http/m_client.dart'; import 'package:mangayomi/sources/utils/utils.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -11,8 +13,9 @@ Map headers(HeadersRef ref, if (mSource == null) return {}; Map headers = {}; if (mSource.headers?.isNotEmpty ?? false) { - headers = (jsonDecode(mSource.headers!) as Map) - .map((key, value) => MapEntry(key.toString(), value.toString())); + headers = (jsonDecode(mSource.headers!) as Map).toMapStringString!; + } else { + headers = getSourceHeaders(mSource); } final cookies = MClient.getCookiesPref(mSource.baseUrl!);