This commit is contained in:
kodjomoustapha 2023-10-24 21:20:41 +01:00
parent 7afafc11e4
commit 243962c6bb
32 changed files with 1347 additions and 1665 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,164 +1,19 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
class $MangaModel implements MangaModel, $Instance {
$MangaModel.wrap(this.$value) : _superclass = $Object($value);
class $MManga implements MManga, $Instance {
$MManga.wrap(this.$value) : _superclass = $Object($value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MangaModel'));
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MManga'));
static const $declaration = BridgeClassDef(BridgeClassType($type),
constructors: {
'': BridgeConstructorDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type),
params: [],
namedParams: [
BridgeParameter(
'source',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'author',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'status',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.intType)),
false),
BridgeParameter(
'genre',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
false),
BridgeParameter(
'imageUrl',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'lang',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'name',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'link',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'description',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'baseUrl',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'dateFormat',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'dateFormatLocale',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'apiUrl',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'page',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.intType)),
false),
BridgeParameter(
'query',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'sourceId',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.intType)),
false),
BridgeParameter(
'names',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'urls',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'chaptersScanlators',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'chaptersDateUploads',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'chaptersVolumes',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'chaptersChaps',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'images',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'statusList',
BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
false),
BridgeParameter(
'hasNextPage',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.boolType)),
false),
]))
returns: BridgeTypeAnnotation($type),
))
},
// Specify class fields
fields: {
@ -201,49 +56,43 @@ class $MangaModel implements MangaModel, $Instance {
'names': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
),
'urls': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
),
'chaptersScanlators': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
),
'chaptersDateUploads': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
),
'chaptersVolumes': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
),
'chaptersChaps': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
),
'images': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
),
),
'statusList': BridgeFieldDef(
BridgeTypeAnnotation(
BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
),
),
'hasNextPage': BridgeFieldDef(
@ -255,14 +104,14 @@ class $MangaModel implements MangaModel, $Instance {
wrap: true);
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $MangaModel.wrap(MangaModel());
return $MManga.wrap(MManga());
}
@override
final MangaModel $value;
final MManga $value;
@override
MangaModel get $reified => $value;
MManga get $reified => $value;
final $Instance _superclass;
@ -363,10 +212,7 @@ class $MangaModel implements MangaModel, $Instance {
return e;
}
}).toList());
case 'statusList':
return $List.wrap($value.statusList!.map((e) {
return $int(e);
}).toList());
case 'hasNextPage':
return $bool($value.hasNextPage!);
default:
@ -387,7 +233,7 @@ class $MangaModel implements MangaModel, $Instance {
case 'status':
$value.status = value.$reified;
case 'genre':
$value.genre = value.$reified as List<dynamic>;
$value.genre = value.$reified;
case 'imageUrl':
$value.imageUrl = value.$reified;
case 'lang':
@ -413,21 +259,19 @@ class $MangaModel implements MangaModel, $Instance {
case 'sourceId':
$value.sourceId = value.$reified;
case 'names':
$value.names = value.$reified as List<dynamic>;
$value.names = value.$reified;
case 'chaptersDateUploads':
$value.chaptersDateUploads = value.$reified as List<dynamic>;
$value.chaptersDateUploads = value.$reified;
case 'chaptersScanlators':
$value.chaptersScanlators = value.$reified as List<dynamic>;
$value.chaptersScanlators = value.$reified;
case 'urls':
$value.urls = value.$reified as List<dynamic>;
$value.urls = value.$reified;
case 'chaptersVolumes':
$value.chaptersVolumes = value.$reified as List<dynamic>;
$value.chaptersVolumes = value.$reified;
case 'chaptersChaps':
$value.chaptersChaps = value.$reified as List<dynamic>;
$value.chaptersChaps = value.$reified;
case 'images':
$value.images = value.$reified as List<dynamic>;
case 'statusList':
$value.statusList = value.$reified as List<dynamic>;
$value.images = value.$reified;
case 'hasNextPage':
$value.hasNextPage = value.$reified;
default:

View file

@ -0,0 +1,50 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/models/manga.dart';
class $MStatus implements $Instance {
static $MStatus $wrap(Runtime runtime, $Value? target, List<$Value?> args) =>
$MStatus.wrap(args[0]!.$value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MStatus'));
static const $declaration = BridgeEnumDef($type, values: [
'ongoing',
'completed',
'canceled',
'unknown',
'onHiatus',
'publishingFinished'
], methods: {}, getters: {}, setters: {}, fields: {});
static final $values = Status.values.asNameMap().map(
(key, value) => MapEntry(key, $MStatus.wrap(value)),
);
const $MStatus.wrap(this.$value);
@override
final Status $value;
@override
$Value? $getProperty(Runtime runtime, String identifier) {
switch (identifier) {
case 'index':
return $int($value.index);
case 'name':
return $String($value.name);
case 'hashCode':
return $int($value.hashCode);
}
throw UnimplementedError();
}
@override
void $setProperty(Runtime runtime, String identifier, $Value value) {
throw UnimplementedError('Cannot set property on an enum');
}
@override
get $reified => $value;
@override
int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!);
}

View file

@ -1,31 +1,19 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/model/m_track.dart';
class $TrackModel implements TrackModel, $Instance {
$TrackModel.wrap(this.$value) : _superclass = $Object($value);
class $MTrack implements MTrack, $Instance {
$MTrack.wrap(this.$value) : _superclass = $Object($value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'TrackModel'));
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MTrack'));
static const $declaration = BridgeClassDef(BridgeClassType($type),
constructors: {
'': BridgeConstructorDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type),
params: [],
namedParams: [
BridgeParameter(
'file',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'label',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
]))
returns: BridgeTypeAnnotation($type),
))
},
// Specify class fields
fields: {
@ -37,14 +25,14 @@ class $TrackModel implements TrackModel, $Instance {
wrap: true);
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $TrackModel.wrap(TrackModel());
return $MTrack.wrap(MTrack());
}
@override
final TrackModel $value;
final MTrack $value;
@override
TrackModel get $reified => $value;
MTrack get $reified => $value;
final $Instance _superclass;

View file

@ -1,52 +1,21 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/bridge_class/track_model.dart';
import 'package:mangayomi/eval/model/m_track.dart';
import 'package:mangayomi/eval/model/m_video.dart';
import 'package:mangayomi/eval/bridge/m_track.dart';
class $VideoModel implements VideoModel, $Instance {
$VideoModel.wrap(this.$value) : _superclass = $Object($value);
class $MVideo implements MVideo, $Instance {
$MVideo.wrap(this.$value) : _superclass = $Object($value);
static const $type = BridgeTypeRef(
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'VideoModel'));
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MVideo'));
static const $declaration = BridgeClassDef(BridgeClassType($type),
constructors: {
'': BridgeConstructorDef(BridgeFunctionDef(
returns: BridgeTypeAnnotation($type),
params: [],
namedParams: [
BridgeParameter(
'url',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'quality',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'originalUrl',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.stringType)),
false),
BridgeParameter(
'headers',
BridgeTypeAnnotation(
BridgeTypeRef.type(RuntimeTypes.mapType)),
false),
BridgeParameter(
'subtitles',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)])),
false),
BridgeParameter(
'audios',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list,
[BridgeTypeRef.type(RuntimeTypes.dynamicType)])),
false),
]))
returns: BridgeTypeAnnotation($type),
))
},
// Specify class fields
fields: {
@ -57,23 +26,26 @@ class $VideoModel implements VideoModel, $Instance {
'originalUrl': BridgeFieldDef(
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.stringType))),
'headers': BridgeFieldDef(
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.mapType))),
'subtitles': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]))),
'audios': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]))),
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.mapType, [
BridgeTypeRef.type(RuntimeTypes.stringType),
BridgeTypeRef.type(RuntimeTypes.stringType)
]))),
'subtitles': BridgeFieldDef(BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
'audios': BridgeFieldDef(BridgeTypeAnnotation(
BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
},
wrap: true);
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $VideoModel.wrap(VideoModel());
return $MVideo.wrap(MVideo());
}
@override
final VideoModel $value;
final MVideo $value;
@override
VideoModel get $reified => $value;
MVideo get $reified => $value;
final $Instance _superclass;
@ -91,12 +63,12 @@ class $VideoModel implements VideoModel, $Instance {
case 'subtitles':
return $List.wrap($value.subtitles!
.map((e) =>
$TrackModel.wrap(TrackModel(file: e.file, label: e.label)))
$MTrack.wrap(MTrack(file: e.file, label: e.label)))
.toList());
case 'audios':
return $List.wrap($value.audios!
.map((e) =>
$TrackModel.wrap(TrackModel(file: e.file, label: e.label)))
$MTrack.wrap(MTrack(file: e.file, label: e.label)))
.toList());
default:
@ -124,7 +96,7 @@ class $VideoModel implements VideoModel, $Instance {
case 'subtitles':
$value.subtitles = (value.$reified as List).isNotEmpty
? (value.$reified as List)
.map((e) => TrackModel()
.map((e) => MTrack()
..file = e.file
..label = e.label)
.toList()
@ -132,7 +104,7 @@ class $VideoModel implements VideoModel, $Instance {
case 'audios':
$value.audios = (value.$reified as List).isNotEmpty
? (value.$reified as List)
.map((e) => TrackModel()
.map((e) => MTrack()
..file = e.file
..label = e.label)
.toList()
@ -147,10 +119,10 @@ class $VideoModel implements VideoModel, $Instance {
String? get url => $value.url;
@override
List<TrackModel>? get subtitles => $value.subtitles;
List<MTrack>? get subtitles => $value.subtitles;
@override
List<TrackModel>? get audios => $value.audios;
List<MTrack>? get audios => $value.audios;
@override
String? get quality => $value.quality;

View file

@ -1,19 +1,21 @@
import 'dart:typed_data';
import 'package:dart_eval/dart_eval.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge_class/track_model.dart';
import 'package:mangayomi/eval/bridge_class/video_model.dart';
import 'package:mangayomi/eval/m_bridge.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/bridge/m_status.dart';
import 'package:mangayomi/eval/bridge/m_track.dart';
import 'package:mangayomi/eval/bridge/m_video.dart';
import 'package:mangayomi/eval/bridge/m_bridge.dart';
import 'package:mangayomi/eval/utils.dart';
Uint8List compilerEval(String sourceCode) {
final compiler = Compiler();
compiler.defineBridgeClasses([
$MBridge.$declaration,
$MangaModel.$declaration,
$VideoModel.$declaration,
$TrackModel.$declaration
$MManga.$declaration,
$MVideo.$declaration,
$MTrack.$declaration
]);
compiler.defineBridgeEnum($MStatus.$declaration);
final program = compiler.compile({
'mangayomi': {'source_code.dart': sourceCode, 'utils.dart': utils}
});

View file

@ -0,0 +1,991 @@
import 'dart:convert';
import 'dart:io';
import 'package:bot_toast/bot_toast.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:js_packer/js_packer.dart';
import 'package:json_path/json_path.dart';
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
import 'package:mangayomi/services/anime_extractors/filemoon.dart';
import 'package:mangayomi/services/anime_extractors/gogocdn_extractor.dart';
import 'package:mangayomi/services/anime_extractors/mp4upload_extractor.dart';
import 'package:mangayomi/services/anime_extractors/mytv_extractor.dart';
import 'package:mangayomi/services/anime_extractors/okru_extractor.dart';
import 'package:mangayomi/services/anime_extractors/rapidcloud_extractor.dart';
import 'package:mangayomi/services/anime_extractors/sendvid_extractor.dart';
import 'package:mangayomi/services/anime_extractors/sibnet_extractor.dart';
import 'package:mangayomi/services/anime_extractors/streamlare_extractor.dart';
import 'package:mangayomi/services/anime_extractors/streamtape_extractor.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/models/video.dart';
import 'package:mangayomi/modules/webview/webview.dart';
import 'package:mangayomi/services/anime_extractors/streamwish_extractor.dart';
import 'package:mangayomi/services/anime_extractors/vidbom_extractor.dart';
import 'package:mangayomi/services/anime_extractors/voe_extractor.dart';
import 'package:mangayomi/services/anime_extractors/your_upload_extractor.dart';
import 'package:mangayomi/services/http_service/cloudflare/cloudflare_bypass.dart';
import 'package:mangayomi/utils/constant.dart';
import 'package:mangayomi/utils/cryptoaes/crypto_aes.dart';
import 'package:mangayomi/utils/cryptoaes/deobfuscator.dart';
import 'package:mangayomi/utils/extensions.dart';
import 'package:mangayomi/utils/reg_exp_matcher.dart';
import 'package:mangayomi/utils/xpath_selector.dart';
import 'package:xpath_selector_html_parser/xpath_selector_html_parser.dart';
import 'package:html/parser.dart' as parser;
import 'package:http/http.dart' as hp;
import 'package:encrypt/encrypt.dart' as encrypt;
class WordSet {
final List<String> words;
WordSet(this.words);
bool anyWordIn(String dateString) {
return words
.any((word) => dateString.toLowerCase().contains(word.toLowerCase()));
}
bool startsWith(String dateString) {
return words
.any((word) => dateString.toLowerCase().startsWith(word.toLowerCase()));
}
bool endsWith(String dateString) {
return words
.any((word) => dateString.toLowerCase().endsWith(word.toLowerCase()));
}
}
class MBridge {
///Seaches for the first descendant node matching the given selectors, using a preorder traversal.
static String querySelector(
String html,
String selector,
int typeElement,
String attributes,
) {
try {
var parse = parser.parse(html);
// return querySelector text
if (typeElement == 0) {
return parse
.querySelector(selector)!
.text
.trim()
.trimLeft()
.trimRight();
// return querySelector innerHtml
} else if (typeElement == 1) {
return parse
.querySelector(selector)!
.innerHtml
.trim()
.trimLeft()
.trimRight();
// return querySelector outerHtml
} else if (typeElement == 2) {
return parse
.querySelector(selector)!
.outerHtml
.trim()
.trimLeft()
.trimRight();
}
// return querySelector attributes
return parse
.querySelector(selector)!
.attributes[attributes]!
.trim()
.trimLeft()
.trimRight();
} catch (e) {
botToast(e.toString());
throw Exception(e);
}
}
///Returns all descendant nodes matching the given selectors, using a preorder traversal.
static List<String> querySelectorAll(String html, String selector,
int typeElement, String attributes, int typeRegExp) {
try {
var parse = parser.parse(html);
final a = parse.querySelectorAll(selector);
List<String> res = [];
for (var element in a) {
//text
if (typeElement == 0) {
res.add(element.text.trim().trimLeft().trimRight());
}
//innerHtml
else if (typeElement == 1) {
res.add(element.innerHtml.trim().trimLeft().trimRight());
}
//outerHtml
else if (typeElement == 2) {
res.add(element.outerHtml.trim().trimLeft().trimRight());
}
//attributes
else if (typeElement == 3) {
res.add(
element.attributes[attributes]!.trim().trimLeft().trimRight());
}
}
// if (typeRegExp == 0) is the default parameter
if (typeRegExp == 0) {
return res;
}
List<String> resRegExp = [];
for (var element in res) {
//get first element of href that match
if (typeRegExp == 1) {
resRegExp.add(regHrefMatcher(element.trim().trimLeft().trimRight()));
}
//get first element of src that match
else if (typeRegExp == 2) {
resRegExp.add(regSrcMatcher(element.trim().trimLeft().trimRight()));
}
//get first element of datasrc that match
else if (typeRegExp == 3) {
resRegExp
.add(regDataSrcMatcher(element.trim().trimLeft().trimRight()));
}
//get first element of img that match
else if (typeRegExp == 4) {
resRegExp.add(regImgMatcher(element.trim().trimLeft().trimRight()));
}
}
return resRegExp;
} catch (e) {
botToast(e.toString());
throw Exception(e);
}
}
///Create query by html string
static List<String> xpath(String html, String xpath) {
List<String> attrs = [];
try {
var htmlXPath = HtmlXPath.html(html);
var query = htmlXPath.query(xpath);
if (query.nodes.length > 1) {
for (var element in query.attrs) {
attrs.add(element!.trim().trimLeft().trimRight());
}
}
//Return one attr
else if (query.nodes.length == 1) {
String attr =
query.attr != null ? query.attr!.trim().trimLeft().trimRight() : "";
if (attr.isNotEmpty) {
attrs = [attr];
}
}
return attrs;
} catch (e) {
// botToast(e.toString());
return attrs;
}
}
///A list utility function
static List listParse(List value, int type) {
List<dynamic> val = [];
for (var element in value) {
if (element is $Value) {
val.add(element.$reified.toString());
} else {
val.add(element);
}
}
if (type == 3) {
return val.toSet().toList();
} else if (type == 1) {
return [val.first];
} else if (type == 2) {
return [val.last];
} else if (type == 4) {
return val.where((element) => element.toString().isNotEmpty).toList();
} else if (type == 5) {
return val.reversed.toList();
} else if (type == 6) {
return [val.join()];
}
return val;
}
///Convert serie status to int
///[status] contains the current status of the serie
///[statusList] contains a list of map of many static status
static int parseStatus(String status, List statusList) {
for (var element in statusList) {
Map statusMap = {};
if (element is $Map<$Value, $Value>) {
statusMap = element.$reified;
} else {
statusMap = element;
}
for (var element in statusMap.entries) {
if (element.key
.toString()
.toLowerCase()
.contains(status.toLowerCase().trim().trimLeft().trimRight())) {
return element.value as int;
}
}
}
return 5;
}
///Get Html content via webview when http request not working
static Future<String> getHtmlViaWebview(String url, String rule) async {
bool isOk = false;
String? html;
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
final webview = await WebviewWindow.create(
configuration: CreateConfiguration(
windowHeight: 500,
windowWidth: 500,
userDataFolderWindows: await getWebViewPath(),
),
);
webview
..setApplicationNameForUserAgent(defaultUserAgent)
..launch(url);
await Future.doWhile(() async {
await Future.delayed(const Duration(seconds: 3));
html = await decodeHtml(
webview,
);
if (html == null || xpathSelector(html!).query(rule).attrs.isEmpty) {
html = await decodeHtml(webview);
return true;
}
return false;
});
html = await decodeHtml(webview);
webview.close();
} else {
HeadlessInAppWebView? headlessWebView;
headlessWebView = HeadlessInAppWebView(
onLoadStop: (controller, u) async {
html = await controller.evaluateJavascript(
source:
"window.document.getElementsByTagName('html')[0].outerHTML;");
await Future.doWhile(() async {
html = await controller.evaluateJavascript(
source:
"window.document.getElementsByTagName('html')[0].outerHTML;");
if (xpathSelector(html!).query(rule).attrs.isEmpty) {
html = await controller.evaluateJavascript(
source:
"window.document.getElementsByTagName('html')[0].outerHTML;");
return true;
}
return false;
});
html = await controller.evaluateJavascript(
source:
"window.document.getElementsByTagName('html')[0].outerHTML;");
isOk = true;
headlessWebView!.dispose();
},
initialUrlRequest: URLRequest(
url: Uri.parse(url),
),
);
headlessWebView.run();
await Future.doWhile(() async {
await Future.delayed(const Duration(seconds: 1));
if (isOk == true) {
return false;
}
return true;
});
}
return html!;
}
///Utility to decode json to List
static List<dynamic> jsonDecodeToList(String source, int type) {
return type == 0
? jsonDecode(source) as List
: (jsonDecode(source) as List).map((e) => jsonEncode(e)).toList();
}
///Deobfuscate a JS code
static String evalJs(String code) {
try {
// JavascriptRuntime? flutterJs;
// flutterJs = getJavascriptRuntime();
// final res = flutterJs.evaluate(code).stringResult;
// flutterJs.dispose();
// return res;
final jsPacker = JSPacker(code);
return jsPacker.unpack() ?? "";
} catch (e) {
botToast(e.toString());
throw Exception(e);
}
}
///Read values in parsed JSON object and return resut to List<String>
static List<String> jsonPathToList(
String source, String expression, int type) {
try {
//Check jsonDecode(source) is list value
if (jsonDecode(source) is List) {
List<dynamic> values = [];
final val = jsonDecode(source) as List;
for (var element in val) {
final mMap = element as Map?;
Map<String, dynamic> map = {};
if (mMap != null) {
map = mMap.map((key, value) => MapEntry(key.toString(), value));
}
values.add(map);
}
List<String> list = [];
for (var data in values) {
final jsonRes = JsonPath(expression).read(data);
String val = "";
//Get jsonRes first string value
if (type == 0) {
val = jsonRes.first.value.toString();
}
//Decode jsonRes first map value
else {
val = jsonEncode(jsonRes.first.value);
}
list.add(val);
}
return list;
}
// else jsonDecode(source) is Map value
else {
var map = json.decode(source);
var values = JsonPath(expression).readValues(map);
return values.map((e) {
return e == null ? "{}" : json.encode(e);
}).toList();
}
} catch (e) {
botToast(e.toString());
throw Exception(e);
}
}
///GetMapValue
static String getMapValue(String source, String attr, bool encode) {
try {
var map = json.decode(source) as Map<String, dynamic>;
if (!encode) {
return map[attr] != null ? map[attr].toString() : "";
}
return map[attr] != null ? jsonEncode(map[attr]) : "";
} catch (_) {
return "";
}
}
///Read values in parsed JSON object and return resut to String
static String jsonPathToString(
String source, String expression, String join) {
try {
List<dynamic> values = [];
//Check jsonDecode(source) is list value
if (jsonDecode(source) is List) {
final val = jsonDecode(source) as List;
for (var element in val) {
final mMap = element as Map?;
Map<String, dynamic> map = {};
if (mMap != null) {
map = mMap.map((key, value) => MapEntry(key.toString(), value));
}
values.add(map);
}
}
// else jsonDecode(source) is Map value
else {
final mMap = jsonDecode(source) as Map?;
Map<String, dynamic> map = {};
if (mMap != null) {
map = mMap.map((key, value) => MapEntry(key.toString(), value));
}
values.add(map);
}
List<String> listRg = [];
for (var data in values) {
final jsonRes = JsonPath(expression).readValues(data);
List list = [];
for (var element in jsonRes) {
list.add(element);
}
//join the list into listRg
listRg.add(list.join(join));
}
return listRg.first;
} catch (e) {
botToast(e.toString());
throw Exception(e);
}
}
//Utility to decode json values as Map<String,dynamic>
static Map jsonPathToMap(String source) {
final mMap = jsonDecode(source) as Map?;
Map<String, dynamic> map = {};
if (mMap != null) {
map = mMap.map((key, value) => MapEntry(key.toString(), value));
}
return map;
}
//Parse a list of dates to millisecondsSinceEpoch
static List listParseDateTime(
List value, String dateFormat, String dateFormatLocale) {
List<dynamic> val = [];
for (var element in value) {
if (element is $Value) {
val.add(element.$reified.toString());
} else {
val.add(element);
}
}
List<dynamic> valD = [];
for (var date in val) {
if (date.toString().isNotEmpty) {
valD.add(parseChapterDate(date, dateFormat, dateFormatLocale));
}
}
return valD;
}
static List sortMapList(List list, String value, int type) {
if (type == 0) {
list.sort((a, b) => a[value].compareTo(b[value]));
} else if (type == 1) {
list.sort((a, b) => b[value].compareTo(a[value]));
}
return list;
}
//Utility to use RegExp
static String regExp(
//RegExp(r'\[a\]'), "[123]")
String expression,
String source,
String replace,
int type,
int group) {
if (type == 0) {
return expression.replaceAll(RegExp(source), replace);
}
return regCustomMatcher(expression, source, group);
}
//Utility to parse $int to int
static int intParse(String value) {
return int.parse(value);
}
//Utility to check if list contains a value
static bool listContain(List value, String element) {
List<dynamic> val = [];
for (var element in value) {
val.add(element.$reified);
}
return val.contains(element);
}
//Http request for MultiparFormData
static Future<String> httpMultiparFormData(String url, int method) async {
try {
hp.StreamedResponse? res;
String result = "";
final headersMap = jsonDecode(url)["headers"] as Map?;
final fieldsMap = jsonDecode(url)["fields"] as Map?;
Map<String, String> fields = {};
if (fieldsMap != null) {
fields = fieldsMap
.map((key, value) => MapEntry(key.toString(), value.toString()));
}
Map<String, String> headers = {};
if (headersMap != null) {
headers = headersMap
.map((key, value) => MapEntry(key.toString(), value.toString()));
}
var request = hp.MultipartRequest(
method == 0
? 'GET'
: method == 1
? 'POST'
: method == 2
? 'PUT'
: 'DELETE',
Uri.parse(url));
request.fields.addAll(fields);
request.headers.addAll(headers);
res = await request.send();
if (res.statusCode != 200) {
result = "400";
} else if (res.statusCode == 200) {
result = await res.stream.bytesToString();
} else {
result = res.reasonPhrase!;
}
return result;
} catch (e) {
botToast(e.toString());
return "";
}
}
//http request and also webview
static Future<String> http(String method, String datas) async {
try {
hp.StreamedResponse? res;
String result = "";
//Get headers
final headersMap = jsonDecode(datas)["headers"] as Map?;
//Get sourceId
final sourceId = jsonDecode(datas)["sourceId"] as int?;
//Get body
final bodyMap = jsonDecode(datas)["body"] as Map?;
final url = jsonDecode(datas)["url"] as String;
//Convert body Map<dynamic,dynamic> to Map<String,String>
Map<String, dynamic> body = {};
if (bodyMap != null) {
body = bodyMap.map((key, value) => MapEntry(key.toString(), value));
}
//Convert headers Map<dynamic,dynamic> to Map<String,String>
Map<String, String> headers = {};
if (headersMap != null) {
headers = headersMap
.map((key, value) => MapEntry(key.toString(), value.toString()));
}
//Get the serie source
final source = sourceId != null ? isar.sources.getSync(sourceId) : null;
//Check the serie if has cloudflare
// if (source != null && source.hasCloudflare!) {
// final res = await cloudflareBypass(
// url: url, sourceId: source.id.toString(), method: method);
// return res;
// }
//Do the http request if the serie hasn't cloudflare
var request = hp.Request(method, Uri.parse(url));
if (bodyMap != null) {
request.body = json.encode(body);
}
request.headers.addAll(headers);
res = await request.send();
if (res.statusCode != 200 && source != null && source.hasCloudflare!) {
result = await cloudflareBypass(
url: url, sourceId: source.id.toString(), method: 0);
} else if (res.statusCode != 200) {
result = "400";
} else if (res.statusCode == 200) {
result = await res.stream.bytesToString();
} else {
result = res.reasonPhrase!;
}
return result;
} catch (e) {
botToast(e.toString());
return "";
}
}
static Future<List<Video>> gogoCdnExtractor(String url) async {
return await GogoCdnExtractor().videosFromUrl(
url,
);
}
static Future<List<Video>> doodExtractor(String url, String? quality) async {
return await DoodExtractor().videosFromUrl(url, quality: quality);
}
static Future<List<Video>> streamWishExtractor(
String url, String prefix) async {
return await StreamWishExtractor().videosFromUrl(url, prefix);
}
static Future<List<Video>> filemoonExtractor(
String url, String prefix) async {
return await FilemoonExtractor().videosFromUrl(url, prefix);
}
static Future<List<Video>> mp4UploadExtractor(
String url, String? headers, String prefix, String suffix) async {
Map<String, String> newHeaders = {};
if (headers != null) {
newHeaders = (jsonDecode(headers) as Map)
.map((key, value) => MapEntry(key.toString(), value.toString()));
}
return await Mp4uploadExtractor()
.videosFromUrl(url, newHeaders, prefix: prefix, suffix: suffix);
}
static Future<List<Video>> streamTapeExtractor(
String url, String? quality) async {
return await StreamTapeExtractor()
.videosFromUrl(url, quality: quality ?? "StreamTape");
}
//Utility to use substring
static String substringAfter(String text, String pattern) {
return text.substringAfter(pattern);
}
//Utility to use substring
static String substringBefore(String text, String pattern) {
return text.substringBefore(pattern);
}
//Utility to use substring
static String substringBeforeLast(String text, String pattern) {
return text.substringBeforeLast(pattern);
}
static String substringAfterLast(String text, String pattern) {
return text.split(pattern).last;
}
//Parse a chapter date to millisecondsSinceEpoch
static String parseChapterDate(
String date, String dateFormat, String dateFormatLocale) {
int parseRelativeDate(String date) {
final number = int.tryParse(RegExp(r"(\d+)").firstMatch(date)!.group(0)!);
if (number == null) return 0;
final cal = DateTime.now();
if (WordSet([
"hari",
"gün",
"jour",
"día",
"dia",
"day",
"วัน",
"ngày",
"giorni",
"أيام",
""
]).anyWordIn(date)) {
return cal.subtract(Duration(days: number)).millisecondsSinceEpoch;
} else if (WordSet([
"jam",
"saat",
"heure",
"hora",
"hour",
"ชั่วโมง",
"giờ",
"ore",
"ساعة",
"小时"
]).anyWordIn(date)) {
return cal.subtract(Duration(hours: number)).millisecondsSinceEpoch;
} else if (WordSet(
["menit", "dakika", "min", "minute", "minuto", "นาที", "دقائق"])
.anyWordIn(date)) {
return cal.subtract(Duration(minutes: number)).millisecondsSinceEpoch;
} else if (WordSet(["detik", "segundo", "second", "วินาที", "sec"])
.anyWordIn(date)) {
return cal.subtract(Duration(seconds: number)).millisecondsSinceEpoch;
} else if (WordSet(["week", "semana"]).anyWordIn(date)) {
return cal.subtract(Duration(days: number * 7)).millisecondsSinceEpoch;
} else if (WordSet(["month", "mes"]).anyWordIn(date)) {
return cal.subtract(Duration(days: number * 30)).millisecondsSinceEpoch;
} else if (WordSet(["year", "año"]).anyWordIn(date)) {
return cal
.subtract(Duration(days: number * 365))
.millisecondsSinceEpoch;
} else {
return 0;
}
}
try {
if (WordSet(["yesterday", "يوم واحد"]).startsWith(date)) {
DateTime cal = DateTime.now().subtract(const Duration(days: 1));
cal = DateTime(cal.year, cal.month, cal.day);
return cal.millisecondsSinceEpoch.toString();
} else if (WordSet(["today"]).startsWith(date)) {
DateTime cal = DateTime.now();
cal = DateTime(cal.year, cal.month, cal.day);
return cal.millisecondsSinceEpoch.toString();
} else if (WordSet(["يومين"]).startsWith(date)) {
DateTime cal = DateTime.now().subtract(const Duration(days: 2));
cal = DateTime(cal.year, cal.month, cal.day);
return cal.millisecondsSinceEpoch.toString();
} else if (WordSet(["ago", "atrás", "önce", "قبل"]).endsWith(date)) {
return parseRelativeDate(date).toString();
} else if (WordSet(["hace"]).startsWith(date)) {
return parseRelativeDate(date).toString();
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
final cleanedDate = date
.split(" ")
.map((it) => it.contains(RegExp(r"\d\D\D"))
? it.replaceAll(RegExp(r"\D"), "")
: it)
.join(" ");
return DateFormat(dateFormat, dateFormatLocale)
.parse(cleanedDate)
.millisecondsSinceEpoch
.toString();
} else {
return DateFormat(dateFormat, dateFormatLocale)
.parse(date)
.millisecondsSinceEpoch
.toString();
}
} catch (e) {
final supportedLocales = DateFormat.allLocalesWithSymbols();
for (var locale in supportedLocales) {
for (var dateFormat in _dateFormats) {
try {
initializeDateFormatting(locale);
if (WordSet(["yesterday", "يوم واحد"]).startsWith(date)) {
DateTime cal = DateTime.now().subtract(const Duration(days: 1));
cal = DateTime(cal.year, cal.month, cal.day);
return cal.millisecondsSinceEpoch.toString();
} else if (WordSet(["today"]).startsWith(date)) {
DateTime cal = DateTime.now();
cal = DateTime(cal.year, cal.month, cal.day);
return cal.millisecondsSinceEpoch.toString();
} else if (WordSet(["يومين"]).startsWith(date)) {
DateTime cal = DateTime.now().subtract(const Duration(days: 2));
cal = DateTime(cal.year, cal.month, cal.day);
return cal.millisecondsSinceEpoch.toString();
} else if (WordSet(["ago", "atrás", "önce", "قبل"])
.endsWith(date)) {
return parseRelativeDate(date).toString();
} else if (WordSet(["hace"]).startsWith(date)) {
return parseRelativeDate(date).toString();
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
final cleanedDate = date
.split(" ")
.map((it) => it.contains(RegExp(r"\d\D\D"))
? it.replaceAll(RegExp(r"\D"), "")
: it)
.join(" ");
return DateFormat(dateFormat, locale)
.parse(cleanedDate)
.millisecondsSinceEpoch
.toString();
} else {
return DateFormat(dateFormat, locale)
.parse(date)
.millisecondsSinceEpoch
.toString();
}
} catch (_) {}
}
}
botToast(e.toString());
throw Exception(e);
}
}
static String deobfuscateJsPassword(String inputString) {
return Deobfuscator.deobfuscateJsPassword(inputString);
}
static Future<List<Video>> sibnetExtractor(String url) async {
return await SibnetExtractor().videosFromUrl(
url,
);
}
static Future<List<Video>> sendVidExtractor(
String url, String? headers, String prefix) async {
Map<String, String> newHeaders = {};
if (headers != null) {
newHeaders = (jsonDecode(headers) as Map)
.map((key, value) => MapEntry(key.toString(), value.toString()));
}
return await SendvidExtractor(newHeaders)
.videosFromUrl(url, prefix: prefix);
}
static Future<List<Video>> myTvExtractor(String url) async {
return await MytvExtractor().videosFromUrl(
url,
);
}
static Future<List<Video>> okruExtractor(String url) async {
return await OkruExtractor().videosFromUrl(
url,
);
}
static Future<List<Video>> yourUploadExtractor(
String url, String? headers, String? name, String prefix) async {
Map<String, String> newHeaders = {};
if (headers != null) {
newHeaders = (jsonDecode(headers) as Map)
.map((key, value) => MapEntry(key.toString(), value.toString()));
}
return await YourUploadExtractor().videosFromUrl(url, newHeaders,
prefix: prefix, name: name ?? "YourUpload");
}
static Future<List<Video>> voeExtractor(String url, String? quality) async {
return await VoeExtractor().videosFromUrl(url, quality);
}
static Future<List<Video>> vidBomExtractor(String url) async {
return await VidBomExtractor().videosFromUrl(
url,
);
}
static Future<List<Video>> streamlareExtractor(
String url, String prefix, String suffix) async {
return await StreamlareExtractor()
.videosFromUrl(url, prefix: prefix, suffix: suffix);
}
static Future<List<Video>> rapidCloudExtractor(
String url, String prefix) async {
return await RapidCloudExtractor().videosFromUrl(url, prefix);
}
static String encryptAESCryptoJS(String plainText, String passphrase) {
return CryptoAES.encryptAESCryptoJS(plainText, passphrase);
}
static String decryptAESCryptoJS(String encrypted, String passphrase) {
return CryptoAES.decryptAESCryptoJS(encrypted, passphrase);
}
static Video toVideo(String url, String quality, String originalUrl,
String? headers, List<Track>? subtitles, List<Track>? audios) {
Map<String, String> newHeaders = {};
if (headers != null) {
newHeaders = (jsonDecode(headers) as Map)
.map((key, value) => MapEntry(key.toString(), value.toString()));
}
return Video(url, quality, originalUrl,
headers: newHeaders, subtitles: subtitles ?? [], audios: audios ?? []);
}
static String cryptoHandler(
String text, String iv, String secretKeyString, bool encrypt) {
if (encrypt) {
final encryptt = _encrypt(secretKeyString, iv);
final en = encryptt.$1.encrypt(text, iv: encryptt.$2);
return en.base64;
} else {
final encryptt = _encrypt(secretKeyString, iv);
final en = encryptt.$1.decrypt64(text, iv: encryptt.$2);
return en;
}
}
}
final List<String> _dateFormats = [
'dd/MM/yyyy',
'MM/dd/yyyy',
'yyyy/MM/dd',
'dd-MM-yyyy',
'MM-dd-yyyy',
'yyyy-MM-dd',
'dd.MM.yyyy',
'MM.dd.yyyy',
'yyyy.MM.dd',
'dd MMMM yyyy',
'MMMM dd, yyyy',
'yyyy MMMM dd',
'dd MMM yyyy',
'MMM dd yyyy',
'yyyy MMM dd',
'dd MMMM, yyyy',
'yyyy, MMMM dd',
'MMMM dd yyyy',
'MMM dd, yyyy',
'dd LLLL yyyy',
'LLLL dd, yyyy',
'yyyy LLLL dd',
'LLLL dd yyyy',
"MMMMM dd, yyyy",
"MMM d, yyy",
"MMM d, yyyy",
"dd/mm/yyyy",
"d MMMM yyyy",
"dd 'de' MMMM 'de' yyyy",
"d MMMM'،' yyyy",
"yyyy'年'M'月'd",
"d MMMM, yyyy",
"dd 'de' MMMMM 'de' yyyy",
"dd MMMMM, yyyy",
"MMMM d, yyyy",
"MMM dd,yyyy"
];
void botToast(String title) {
BotToast.showSimpleNotification(
onlyOne: true,
dismissDirections: [DismissDirection.horizontal, DismissDirection.down],
align: const Alignment(0, 0.99),
duration: const Duration(seconds: 10),
title: title);
}
(encrypt.Encrypter, encrypt.IV) _encrypt(String keyy, String ivv) {
final key = encrypt.Key.fromUtf8(keyy);
final iv = encrypt.IV.fromUtf8(ivv);
final encrypter = encrypt.Encrypter(
encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'));
return (encrypter, iv);
}

View file

@ -1,4 +1,4 @@
class MangaModel {
class MManga {
String? name;
String? link;
@ -41,7 +41,7 @@ class MangaModel {
List<dynamic>? chaptersChaps;
List<dynamic>? images;
List<dynamic>? statusList;
MangaModel(
MManga(
{this.source = "",
this.author = "",
this.genre,
@ -68,26 +68,3 @@ class MangaModel {
this.statusList,
this.hasNextPage = true});
}
class VideoModel {
String? url;
String? quality;
String? originalUrl;
Map<String, String>? headers;
List<TrackModel>? subtitles;
List<TrackModel>? audios;
VideoModel(
{this.url,
this.quality,
this.originalUrl,
this.headers,
this.subtitles,
this.audios});
}
class TrackModel {
String? file;
String? label;
TrackModel({this.file, this.label});
}

View file

@ -0,0 +1,6 @@
class MTrack {
String? file;
String? label;
MTrack({this.file, this.label});
}

View file

@ -0,0 +1,17 @@
import 'package:mangayomi/eval/model/m_track.dart';
class MVideo {
String? url;
String? quality;
String? originalUrl;
Map<String, String>? headers;
List<MTrack>? subtitles;
List<MTrack>? audios;
MVideo(
{this.url,
this.quality,
this.originalUrl,
this.headers,
this.subtitles,
this.audios});
}

View file

@ -1,10 +1,11 @@
import 'dart:typed_data';
import 'package:dart_eval/dart_eval.dart';
import 'package:mangayomi/eval/bridge_class/track_model.dart';
import 'package:mangayomi/eval/bridge_class/video_model.dart';
import 'package:mangayomi/eval/m_bridge.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge/m_status.dart';
import 'package:mangayomi/eval/bridge/m_track.dart';
import 'package:mangayomi/eval/bridge/m_video.dart';
import 'package:mangayomi/eval/bridge/m_bridge.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
Runtime runtimeEval(Uint8List bytecode) {
final runtime = Runtime(bytecode.buffer.asByteData());
@ -12,19 +13,20 @@ Runtime runtimeEval(Uint8List bytecode) {
'package:bridge_lib/bridge_lib.dart', 'MBridge.', $MBridge.$construct,
isBridge: true);
runtime.registerBridgeFunc(
'package:bridge_lib/bridge_lib.dart', 'MangaModel.', $MangaModel.$new);
'package:bridge_lib/bridge_lib.dart', 'MManga.', $MManga.$new);
runtime.registerBridgeFunc(
'package:bridge_lib/bridge_lib.dart', 'VideoModel.', $VideoModel.$new);
'package:bridge_lib/bridge_lib.dart', 'MVideo.', $MVideo.$new);
runtime.registerBridgeFunc(
'package:bridge_lib/bridge_lib.dart', 'TrackModel.', $TrackModel.$new);
'package:bridge_lib/bridge_lib.dart', 'MTrack.', $MTrack.$new);
runtime.registerBridgeEnumValues(
'package:bridge_lib/bridge_lib.dart', 'MStatus', $MStatus.$values);
runtime.registerBridgeFunc(
'package:bridge_lib/bridge_lib.dart', 'MBridge.http', $MBridge.$http);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.listParseDateTime', $MBridge.$listParseDateTime);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.httpMultiparFormData', $MBridge.$httpMultiparFormData);
runtime.registerBridgeFunc(
'package:bridge_lib/bridge_lib.dart', 'MBridge.bAse64', $MBridge.$bAse64);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.gogoCdnExtractor', $MBridge.$gogoCdnExtractor);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
@ -63,8 +65,6 @@ Runtime runtimeEval(Uint8List bytecode) {
'MBridge.jsonPathToString', $MBridge.$jsonPathToString);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.toVideo', $MBridge.$toVideo);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.isEmptyOrIsNotEmpty', $MBridge.$isEmptyOrIsNotEmpty);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.jsonPathToList', $MBridge.$jsonPathToList);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
@ -73,16 +73,12 @@ Runtime runtimeEval(Uint8List bytecode) {
'MBridge.jsonPathToMap', $MBridge.$jsonPathToMap);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.parseStatus', $MBridge.$parseStatus);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.stringParseValue', $MBridge.$stringParseValue);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.getMapValue', $MBridge.$getMapValue);
runtime.registerBridgeFunc(
'package:bridge_lib/bridge_lib.dart', 'MBridge.regExp', $MBridge.$regExp);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.parseChapterDate', $MBridge.$parseChapterDate);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.stringParse', $MBridge.$stringParse);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
'MBridge.substringAfter', $MBridge.$substringAfter);
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',

View file

@ -1,5 +1,7 @@
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/source.dart';
part 'manga.g.dart';
@collection
@ -64,6 +66,30 @@ class Manga {
this.lastRead = 0,
this.isLocalArchive = false,
this.customCoverImage});
MManga toMManga(Source source) {
return MManga(
name: name,
link: link,
genre: genre,
author: author,
status: switch (status) {
Status.ongoing => 0,
Status.completed => 1,
Status.onHiatus => 2,
Status.canceled => 3,
Status.publishingFinished => 4,
_ => 5,
},
description: description,
imageUrl: imageUrl,
baseUrl: source.baseUrl,
apiUrl: source.apiUrl,
lang: lang,
dateFormat: source.dateFormat,
source: source.name,
dateFormatLocale: source.dateFormatLocale);
}
}
enum Status {
@ -74,4 +100,3 @@ enum Status {
onHiatus,
publishingFinished
}

View file

@ -1,4 +1,5 @@
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
part 'source.g.dart';
@collection
@ -92,4 +93,17 @@ class Source {
isFullData = json['isFullData'] ?? false;
appMinVerReq = json['appMinVerReq'];
}
MManga toMManga({int page = 1, String? query = "", String link = ""}) {
return MManga(
page: page,
query: query,
link: link,
lang: lang,
baseUrl: baseUrl,
apiUrl: apiUrl,
sourceId: id,
source: name,
dateFormat: dateFormat,
dateFormatLocale: dateFormatLocale);
}
}

View file

@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/router/router.dart';
@ -173,7 +173,7 @@ class SourceSearchScreen extends ConsumerWidget {
}
class MangaGlobalImageCard extends ConsumerStatefulWidget {
final MangaModel manga;
final MManga manga;
final Source source;
const MangaGlobalImageCard({

View file

@ -1,4 +1,3 @@
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';
@ -15,64 +14,23 @@ Future<dynamic> updateMangaDetail(UpdateMangaDetailRef ref,
return;
}
final source = getSource(manga.lang!, manga.source!);
final mangaS = MangaModel(
name: manga.name,
link: manga.link,
genre: manga.genre,
author: manga.author,
status: switch (manga.status) {
Status.ongoing => 0,
Status.completed => 1,
Status.onHiatus => 2,
Status.canceled => 3,
Status.publishingFinished => 4,
_ => 5,
},
description: manga.description,
imageUrl: manga.imageUrl,
baseUrl: source!.baseUrl,
apiUrl: source.apiUrl,
lang: manga.lang,
dateFormat: source.dateFormat,
dateFormatLocale: source.dateFormatLocale);
final getManga = await ref
.watch(getMangaDetailProvider(manga: mangaS, source: source).future);
final imageUrl = getManga.imageUrl != null && getManga.imageUrl!.isNotEmpty
? getManga.imageUrl
: manga.imageUrl ?? "";
final name = getManga.name != null && getManga.name!.isNotEmpty
? getManga.name!.trim().trimLeft().trimRight()
: manga.name ?? "";
final genre = getManga.genre != null && getManga.genre!.isNotEmpty
? getManga.genre!
.map((e) => e.toString().trim().trimLeft().trimRight())
.toList()
.toSet()
.toList()
: manga.genre ?? [];
final getManga = await ref.watch(
getMangaDetailProvider(manga: manga.toMManga(source!), source: source)
.future);
final author = getManga.author != null && getManga.author!.isNotEmpty
? getManga.author!.trim().trimLeft().trimRight()
: manga.author ?? "";
final description =
getManga.description != null && getManga.description!.isNotEmpty
? getManga.description!.trim().trimLeft().trimRight()
: manga.description ?? "";
final link = getManga.link != null && getManga.link!.isNotEmpty
? getManga.link!.trim().trimLeft().trimRight()
: manga.link ?? "";
final sourceA = getManga.source != null && getManga.source!.isNotEmpty
? getManga.source!.trim().trimLeft().trimRight()
: manga.source ?? "";
final lang = getManga.lang != null && getManga.lang!.isNotEmpty
? getManga.lang!.trim().trimLeft().trimRight()
: manga.lang ?? "";
manga
..imageUrl = imageUrl
..name = name
..genre = genre
..author = author
..imageUrl = getManga.imageUrl ?? manga.imageUrl
..name = getManga.name?.trim().trimLeft().trimRight() ?? manga.name
..genre = getManga.genre
?.map((e) => e.toString().trim().trimLeft().trimRight())
.toList()
.toSet()
.toList() ??
manga.genre ??
[]
..author =
getManga.author?.trim().trimLeft().trimRight() ?? manga.author ?? ""
..status = switch (getManga.status) {
0 => Status.ongoing,
1 => Status.completed,
@ -81,10 +39,12 @@ Future<dynamic> updateMangaDetail(UpdateMangaDetailRef ref,
4 => Status.publishingFinished,
_ => Status.unknown,
}
..description = description
..link = link
..source = sourceA
..lang = lang
..description = getManga.description?.trim().trimLeft().trimRight() ??
manga.description ??
""
..link = getManga.link?.trim().trimLeft().trimRight() ?? manga.link
..source = getManga.source?.trim().trimLeft().trimRight() ?? manga.source
..lang = manga.lang
..isManga = source.isManga
..lastUpdate = DateTime.now().millisecondsSinceEpoch;
final checkManga = isar.mangas.getSync(mangaId);

View file

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/services/get_latest_updates_manga.dart';
import 'package:mangayomi/services/get_popular_manga.dart';
@ -53,8 +53,8 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
];
}
Future<List<MangaModel?>> _loadMore() async {
List<MangaModel?> mangaResList = [];
Future<List<MManga?>> _loadMore() async {
List<MManga?> mangaResList = [];
if (_isLoading) {
if (widget.source.isFullData!) {
@ -91,7 +91,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
late final _textEditingController = TextEditingController(text: widget.query);
late String _query = widget.query;
late bool _isSearch = widget.isSearch;
AsyncValue<List<MangaModel?>>? _getManga;
AsyncValue<List<MManga?>>? _getManga;
int _length = 0;
@override
Widget build(BuildContext context) {
@ -398,7 +398,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
}
class MangaHomeImageCard extends ConsumerStatefulWidget {
final MangaModel manga;
final MManga manga;
final bool isManga;
final Source source;
const MangaHomeImageCard({

View file

@ -7,7 +7,7 @@ import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/modules/manga/detail/manga_detail_main.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/router/router.dart';
@ -21,7 +21,7 @@ class MangaImageCardWidget extends ConsumerWidget {
final String lang;
final bool isManga;
final MangaModel? getMangaDetail;
final MManga? getMangaDetail;
const MangaImageCardWidget(
{required this.lang,
@ -103,7 +103,7 @@ class MangaImageCardWidget extends ConsumerWidget {
}
void pushToMangaReaderDetail(
{MangaModel? getManga,
{MManga? getManga,
required String lang,
required BuildContext context,
int? archiveId,

View file

@ -1,5 +1,5 @@
import 'package:http/http.dart' as http;
import 'package:mangayomi/eval/m_bridge.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/models/video.dart';
import 'package:mangayomi/utils/extensions.dart';
import 'package:mangayomi/utils/xpath_selector.dart';

View file

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:html/dom.dart';
import 'package:http/http.dart' as http;
import 'package:mangayomi/eval/m_bridge.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/models/video.dart';
import 'package:html/parser.dart' as parser;
import 'package:mangayomi/utils/extensions.dart';

View file

@ -1,5 +1,5 @@
import 'package:http/http.dart' as http;
import 'package:mangayomi/eval/m_bridge.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/models/video.dart';
import 'package:mangayomi/utils/extensions.dart';
import 'package:mangayomi/utils/xpath_selector.dart';

View file

@ -1,5 +1,5 @@
import 'package:http/http.dart' as http;
import 'package:mangayomi/eval/m_bridge.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/models/video.dart';
import 'package:mangayomi/utils/extensions.dart';
import 'package:mangayomi/utils/xpath_selector.dart';

View file

@ -1,8 +1,8 @@
import 'dart:async';
import 'dart:io';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/model/m_track.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/video.dart';
@ -34,16 +34,7 @@ Future<(List<Video>, bool)> getAnimeServers(
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
runtime.args = [
$MangaModel.wrap(MangaModel(
lang: source.lang,
link: episode.url,
baseUrl: source.baseUrl,
source: source.name,
apiUrl: source.apiUrl,
sourceId: source.id,
))
];
runtime.args = [$MManga.wrap(source.toMManga(link: episode.url!))];
var res = await runtime.executeLib(
'package:mangayomi/source_code.dart', 'getVideoList');
if (res is $List) {
@ -55,7 +46,7 @@ Future<(List<Video>, bool)> getAnimeServers(
subtitles = subs.map((e) => Track(e.file, e.label)).toList();
} else {
try {
subtitles = (subs as List<TrackModel>).map((e) {
subtitles = (subs as List<MTrack>).map((e) {
return Track(e.file, e.label);
}).toList();
} catch (_) {}
@ -66,7 +57,7 @@ Future<(List<Video>, bool)> getAnimeServers(
audios = auds.map((e) => Track(e.file, e.label)).toList();
} else {
try {
audios = (subs as List<TrackModel>).map((e) {
audios = (subs as List<MTrack>).map((e) {
return Track(e.file, e.label);
}).toList();
} catch (_) {}

View file

@ -3,8 +3,7 @@ import 'dart:io';
import 'dart:typed_data';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart';
@ -67,18 +66,9 @@ Future<GetChapterUrlModel> getChapterUrl(
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
runtime.args = [
$MangaModel.wrap(MangaModel(
lang: source.lang,
link: chapter.url,
baseUrl: source.baseUrl,
source: source.name,
apiUrl: source.apiUrl,
sourceId: source.id,
))
];
runtime.args = [$MManga.wrap(source.toMManga(link: chapter.url!))];
var res = await runtime.executeLib(
'package:mangayomi/source_code.dart', 'getChapterUrl');
'package:mangayomi/source_code.dart', 'getChapterPages');
if (res is $List) {
for (var element in res.$reified) {
if (element is $Value) {

View file

@ -1,45 +1,35 @@
import 'dart:async';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_latest_updates_manga.g.dart';
@riverpod
Future<List<MangaModel?>> getLatestUpdatesManga(
Future<List<MManga?>> getLatestUpdatesManga(
GetLatestUpdatesMangaRef ref, {
required Source source,
required int page,
}) async {
List<MangaModel?>? latestUpdatesManga = [];
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
runtime.args = [
$MangaModel.wrap(MangaModel(
page: page,
lang: source.lang,
baseUrl: source.baseUrl,
apiUrl: source.apiUrl,
sourceId: source.id,
source: source.name,
dateFormat: source.dateFormat,
dateFormatLocale: source.dateFormatLocale))
];
var res = await runtime.executeLib(
'package:mangayomi/source_code.dart',
source.isManga! ? 'getLatestUpdatesManga' : 'getLatestUpdatesAnime',
);
List<MManga?>? latestUpdatesManga = [];
try {
if (res is $MangaModel) {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
runtime.args = [$MManga.wrap(source.toMManga(page: page))];
var res = await runtime.executeLib(
'package:mangayomi/source_code.dart',
source.isManga! ? 'getLatestUpdatesManga' : 'getLatestUpdatesAnime',
);
if (res is $MManga) {
final value = res.$reified;
List<MangaModel> newManga = [];
List<MManga> newManga = [];
for (var i = 0; i < value.names!.length; i++) {
MangaModel newMangaa = MangaModel(
MManga newMangaa = MManga(
name: value.names![i],
link: value.urls![i],
imageUrl: value.images!.isEmpty ? "" : value.images![i],
@ -55,7 +45,7 @@ Future<List<MangaModel?>> getLatestUpdatesManga(
latestUpdatesManga = newManga;
} else {
latestUpdatesManga =
(res.$reified as List<dynamic>).map((e) => e as MangaModel).toList();
(res.$reified as List<dynamic>).map((e) => e as MManga).toList();
}
} catch (e) {
throw Exception(e);

View file

@ -36,7 +36,7 @@ const getLatestUpdatesMangaProvider = GetLatestUpdatesMangaFamily();
/// See also [getLatestUpdatesManga].
class GetLatestUpdatesMangaFamily
extends Family<AsyncValue<List<MangaModel?>>> {
extends Family<AsyncValue<List<MManga?>>> {
/// See also [getLatestUpdatesManga].
const GetLatestUpdatesMangaFamily();
@ -78,7 +78,7 @@ class GetLatestUpdatesMangaFamily
/// See also [getLatestUpdatesManga].
class GetLatestUpdatesMangaProvider
extends AutoDisposeFutureProvider<List<MangaModel?>> {
extends AutoDisposeFutureProvider<List<MManga?>> {
/// See also [getLatestUpdatesManga].
GetLatestUpdatesMangaProvider({
required Source source,
@ -118,7 +118,7 @@ class GetLatestUpdatesMangaProvider
@override
Override overrideWith(
FutureOr<List<MangaModel?>> Function(GetLatestUpdatesMangaRef provider)
FutureOr<List<MManga?>> Function(GetLatestUpdatesMangaRef provider)
create,
) {
return ProviderOverride(
@ -137,7 +137,7 @@ class GetLatestUpdatesMangaProvider
}
@override
AutoDisposeFutureProviderElement<List<MangaModel?>> createElement() {
AutoDisposeFutureProviderElement<List<MManga?>> createElement() {
return _GetLatestUpdatesMangaProviderElement(this);
}
@ -159,7 +159,7 @@ class GetLatestUpdatesMangaProvider
}
mixin GetLatestUpdatesMangaRef
on AutoDisposeFutureProviderRef<List<MangaModel?>> {
on AutoDisposeFutureProviderRef<List<MManga?>> {
/// The parameter `source` of this provider.
Source get source;
@ -168,7 +168,7 @@ mixin GetLatestUpdatesMangaRef
}
class _GetLatestUpdatesMangaProviderElement
extends AutoDisposeFutureProviderElement<List<MangaModel?>>
extends AutoDisposeFutureProviderElement<List<MManga?>>
with GetLatestUpdatesMangaRef {
_GetLatestUpdatesMangaProviderElement(super.provider);

View file

@ -1,34 +1,30 @@
import 'dart:async';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_manga_detail.g.dart';
@riverpod
Future<MangaModel> getMangaDetail(
Future<MManga> getMangaDetail(
GetMangaDetailRef ref, {
required MangaModel manga,
required MManga manga,
required Source source,
}) async {
MangaModel? mangadetail;
MManga? mangadetail;
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
runtime.args = [
$MangaModel.wrap(manga
..source = source.name
..lang = source.lang)
];
runtime.args = [$MManga.wrap(manga)];
var result = await runtime.executeLib('package:mangayomi/source_code.dart',
source.isManga! ? 'getMangaDetail' : 'getAnimeDetail');
try {
if (result is $MangaModel) {
if (result is $MManga) {
final value = result.$reified;
mangadetail = value;
}

View file

@ -34,13 +34,13 @@ class _SystemHash {
const getMangaDetailProvider = GetMangaDetailFamily();
/// See also [getMangaDetail].
class GetMangaDetailFamily extends Family<AsyncValue<MangaModel>> {
class GetMangaDetailFamily extends Family<AsyncValue<MManga>> {
/// See also [getMangaDetail].
const GetMangaDetailFamily();
/// See also [getMangaDetail].
GetMangaDetailProvider call({
required MangaModel manga,
required MManga manga,
required Source source,
}) {
return GetMangaDetailProvider(
@ -75,10 +75,10 @@ class GetMangaDetailFamily extends Family<AsyncValue<MangaModel>> {
}
/// See also [getMangaDetail].
class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
class GetMangaDetailProvider extends AutoDisposeFutureProvider<MManga> {
/// See also [getMangaDetail].
GetMangaDetailProvider({
required MangaModel manga,
required MManga manga,
required Source source,
}) : this._internal(
(ref) => getMangaDetail(
@ -110,12 +110,12 @@ class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
required this.source,
}) : super.internal();
final MangaModel manga;
final MManga manga;
final Source source;
@override
Override overrideWith(
FutureOr<MangaModel> Function(GetMangaDetailRef provider) create,
FutureOr<MManga> Function(GetMangaDetailRef provider) create,
) {
return ProviderOverride(
origin: this,
@ -133,7 +133,7 @@ class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
}
@override
AutoDisposeFutureProviderElement<MangaModel> createElement() {
AutoDisposeFutureProviderElement<MManga> createElement() {
return _GetMangaDetailProviderElement(this);
}
@ -154,21 +154,21 @@ class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
}
}
mixin GetMangaDetailRef on AutoDisposeFutureProviderRef<MangaModel> {
mixin GetMangaDetailRef on AutoDisposeFutureProviderRef<MManga> {
/// The parameter `manga` of this provider.
MangaModel get manga;
MManga get manga;
/// The parameter `source` of this provider.
Source get source;
}
class _GetMangaDetailProviderElement
extends AutoDisposeFutureProviderElement<MangaModel>
extends AutoDisposeFutureProviderElement<MManga>
with GetMangaDetailRef {
_GetMangaDetailProviderElement(super.provider);
@override
MangaModel get manga => (origin as GetMangaDetailProvider).manga;
MManga get manga => (origin as GetMangaDetailProvider).manga;
@override
Source get source => (origin as GetMangaDetailProvider).source;
}

View file

@ -1,45 +1,35 @@
import 'dart:async';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_popular_manga.g.dart';
@riverpod
Future<List<MangaModel?>> getPopularManga(
Future<List<MManga?>> getPopularManga(
GetPopularMangaRef ref, {
required Source source,
required int page,
}) async {
List<MangaModel> popularManga = [];
List<MManga> popularManga = [];
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
runtime.args = [
$MangaModel.wrap(MangaModel(
page: page,
lang: source.lang,
baseUrl: source.baseUrl,
apiUrl: source.apiUrl,
sourceId: source.id,
source: source.name,
dateFormat: source.dateFormat,
dateFormatLocale: source.dateFormatLocale))
];
runtime.args = [$MManga.wrap(source.toMManga(page: page))];
var res = await runtime.executeLib(
'package:mangayomi/source_code.dart',
source.isManga! ? 'getPopularManga' : 'getPopularAnime',
);
try {
if (res is $MangaModel) {
if (res is $MManga) {
final value = res.$reified;
List<MangaModel> newManga = [];
List<MManga> newManga = [];
for (var i = 0; i < value.names!.length; i++) {
MangaModel newMangaa = MangaModel(
MManga newMangaa = MManga(
name: value.names![i],
link: value.urls![i],
imageUrl: value.images!.isEmpty ? "" : value.images![i],
@ -55,7 +45,7 @@ Future<List<MangaModel?>> getPopularManga(
popularManga = newManga;
} else {
popularManga =
(res.$reified as List<dynamic>).map((e) => e as MangaModel).toList();
(res.$reified as List<dynamic>).map((e) => e as MManga).toList();
}
} catch (e) {
throw Exception(e);

View file

@ -34,7 +34,7 @@ class _SystemHash {
const getPopularMangaProvider = GetPopularMangaFamily();
/// See also [getPopularManga].
class GetPopularMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
class GetPopularMangaFamily extends Family<AsyncValue<List<MManga?>>> {
/// See also [getPopularManga].
const GetPopularMangaFamily();
@ -76,7 +76,7 @@ class GetPopularMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
/// See also [getPopularManga].
class GetPopularMangaProvider
extends AutoDisposeFutureProvider<List<MangaModel?>> {
extends AutoDisposeFutureProvider<List<MManga?>> {
/// See also [getPopularManga].
GetPopularMangaProvider({
required Source source,
@ -116,7 +116,7 @@ class GetPopularMangaProvider
@override
Override overrideWith(
FutureOr<List<MangaModel?>> Function(GetPopularMangaRef provider) create,
FutureOr<List<MManga?>> Function(GetPopularMangaRef provider) create,
) {
return ProviderOverride(
origin: this,
@ -134,7 +134,7 @@ class GetPopularMangaProvider
}
@override
AutoDisposeFutureProviderElement<List<MangaModel?>> createElement() {
AutoDisposeFutureProviderElement<List<MManga?>> createElement() {
return _GetPopularMangaProviderElement(this);
}
@ -155,7 +155,7 @@ class GetPopularMangaProvider
}
}
mixin GetPopularMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
mixin GetPopularMangaRef on AutoDisposeFutureProviderRef<List<MManga?>> {
/// The parameter `source` of this provider.
Source get source;
@ -164,7 +164,7 @@ mixin GetPopularMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
}
class _GetPopularMangaProviderElement
extends AutoDisposeFutureProviderElement<List<MangaModel?>>
extends AutoDisposeFutureProviderElement<List<MManga?>>
with GetPopularMangaRef {
_GetPopularMangaProviderElement(super.provider);

View file

@ -1,46 +1,37 @@
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
import 'package:mangayomi/eval/bridge_class/model.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'search_manga.g.dart';
@riverpod
Future<List<MangaModel?>> searchManga(
Future<List<MManga?>> searchManga(
SearchMangaRef ref, {
required Source source,
required String query,
required int page,
}) async {
List<MangaModel?>? manga = [];
List<MManga?>? manga = [];
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
runtime.args = [
$MangaModel.wrap(MangaModel(
query: query.trim(),
lang: source.lang,
page: page,
baseUrl: source.baseUrl,
apiUrl: source.apiUrl,
sourceId: source.id,
source: source.name,
dateFormat: source.dateFormat,
dateFormatLocale: source.dateFormatLocale))
$MManga.wrap(source.toMManga(query: query.trim(), page: page))
];
var res = await runtime.executeLib(
'package:mangayomi/source_code.dart',
source.isManga! ? 'searchManga' : 'searchAnime',
);
try {
if (res is $MangaModel) {
if (res is $MManga) {
final value = res.$reified;
List<MangaModel> newManga = [];
List<MManga> newManga = [];
for (var i = 0; i < value.names!.length; i++) {
MangaModel newMangaa = MangaModel(
MManga newMangaa = MManga(
name: value.names![i],
link: value.urls![i],
imageUrl: value.images!.isEmpty ? "" : value.images![i],
@ -55,8 +46,7 @@ Future<List<MangaModel?>> searchManga(
}
manga = newManga;
} else {
manga =
(res.$reified as List<dynamic>).map((e) => e as MangaModel).toList();
manga = (res.$reified as List<dynamic>).map((e) => e as MManga).toList();
}
} catch (e) {
throw Exception(e);

View file

@ -34,7 +34,7 @@ class _SystemHash {
const searchMangaProvider = SearchMangaFamily();
/// See also [searchManga].
class SearchMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
class SearchMangaFamily extends Family<AsyncValue<List<MManga?>>> {
/// See also [searchManga].
const SearchMangaFamily();
@ -78,7 +78,7 @@ class SearchMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
}
/// See also [searchManga].
class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
class SearchMangaProvider extends AutoDisposeFutureProvider<List<MManga?>> {
/// See also [searchManga].
SearchMangaProvider({
required Source source,
@ -123,7 +123,7 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
@override
Override overrideWith(
FutureOr<List<MangaModel?>> Function(SearchMangaRef provider) create,
FutureOr<List<MManga?>> Function(SearchMangaRef provider) create,
) {
return ProviderOverride(
origin: this,
@ -142,7 +142,7 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
}
@override
AutoDisposeFutureProviderElement<List<MangaModel?>> createElement() {
AutoDisposeFutureProviderElement<List<MManga?>> createElement() {
return _SearchMangaProviderElement(this);
}
@ -165,7 +165,7 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
}
}
mixin SearchMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
mixin SearchMangaRef on AutoDisposeFutureProviderRef<List<MManga?>> {
/// The parameter `source` of this provider.
Source get source;
@ -177,7 +177,7 @@ mixin SearchMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
}
class _SearchMangaProviderElement
extends AutoDisposeFutureProviderElement<List<MangaModel?>>
extends AutoDisposeFutureProviderElement<List<MManga?>>
with SearchMangaRef {
_SearchMangaProviderElement(super.provider);

View file

@ -2,7 +2,7 @@ import 'dart:developer';
import 'dart:io';
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'package:http/http.dart' as http;
import 'package:mangayomi/eval/m_bridge.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/track.dart';
import 'package:mangayomi/models/track_preference.dart';