added option to download novels
This commit is contained in:
parent
a5ff175c06
commit
5ae7a8d581
14 changed files with 161 additions and 24 deletions
|
|
@ -106,6 +106,13 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||||
BridgeParameter('url',
|
BridgeParameter('url',
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
])),
|
])),
|
||||||
|
'cleanHtmlContent': BridgeMethodDef(BridgeFunctionDef(
|
||||||
|
returns: BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.future, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
|
params: [
|
||||||
|
BridgeParameter('html',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
])),
|
||||||
'getFilterList': BridgeMethodDef(BridgeFunctionDef(
|
'getFilterList': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(
|
returns: BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
|
|
@ -1188,6 +1195,10 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||||
Future<String> getHtmlContent(String url) async =>
|
Future<String> getHtmlContent(String url) async =>
|
||||||
await $_invoke('getHtmlContent', [$String(url)]);
|
await $_invoke('getHtmlContent', [$String(url)]);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> cleanHtmlContent(String html) async =>
|
||||||
|
await $_invoke('cleanHtmlContent', [$String(html)]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, String> get headers {
|
Map<String, String> get headers {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,11 @@ class DartExtensionService implements ExtensionService {
|
||||||
return await _executeLib().getHtmlContent(url);
|
return await _executeLib().getHtmlContent(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> cleanHtmlContent(String html) async {
|
||||||
|
return await _executeLib().cleanHtmlContent(html);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FilterList getFilterList() {
|
FilterList getFilterList() {
|
||||||
List<dynamic> list;
|
List<dynamic> list;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ abstract interface class ExtensionService {
|
||||||
|
|
||||||
Future<String> getHtmlContent(String url);
|
Future<String> getHtmlContent(String url);
|
||||||
|
|
||||||
|
Future<String> cleanHtmlContent(String html);
|
||||||
|
|
||||||
FilterList getFilterList();
|
FilterList getFilterList();
|
||||||
|
|
||||||
List<SourcePreference> getSourcePreferences();
|
List<SourcePreference> getSourcePreferences();
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,9 @@ class MProvider {
|
||||||
async getHtmlContent(url) {
|
async getHtmlContent(url) {
|
||||||
throw new Error("getHtmlContent not implemented");
|
throw new Error("getHtmlContent not implemented");
|
||||||
}
|
}
|
||||||
|
async cleanHtmlContent(html) {
|
||||||
|
throw new Error("cleanHtmlContent not implemented");
|
||||||
|
}
|
||||||
getFilterList() {
|
getFilterList() {
|
||||||
throw new Error("getFilterList not implemented");
|
throw new Error("getFilterList not implemented");
|
||||||
}
|
}
|
||||||
|
|
@ -147,6 +150,15 @@ var extention = new DefaultExtension();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> cleanHtmlContent(String html) async {
|
||||||
|
_init();
|
||||||
|
final res = (await runtime.handlePromise(await runtime.evaluateAsync(
|
||||||
|
'jsonStringify(() => extention.cleanHtmlContent(`$html`))')))
|
||||||
|
.stringResult;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FilterList getFilterList() {
|
FilterList getFilterList() {
|
||||||
List<dynamic> list;
|
List<dynamic> list;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ abstract class MProvider {
|
||||||
|
|
||||||
Future<String> getHtmlContent(String url);
|
Future<String> getHtmlContent(String url);
|
||||||
|
|
||||||
|
Future<String> cleanHtmlContent(String html);
|
||||||
|
|
||||||
List<dynamic> getFilterList();
|
List<dynamic> getFilterList();
|
||||||
|
|
||||||
List<dynamic> getSourcePreferences();
|
List<dynamic> getSourcePreferences();
|
||||||
|
|
|
||||||
|
|
@ -51,13 +51,15 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
("getDetail", 3),
|
("getDetail", 3),
|
||||||
("getPageList", 4),
|
("getPageList", 4),
|
||||||
("getVideoList", 5),
|
("getVideoList", 5),
|
||||||
("getHtmlContent", 6)
|
("getHtmlContent", 6),
|
||||||
|
("cleanHtmlContent", 7)
|
||||||
];
|
];
|
||||||
|
|
||||||
int _serviceIndex = 0;
|
int _serviceIndex = 0;
|
||||||
int _page = 1;
|
int _page = 1;
|
||||||
String _query = "";
|
String _query = "";
|
||||||
String _url = "";
|
String _url = "";
|
||||||
|
String _html = "";
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
String _errorText = "";
|
String _errorText = "";
|
||||||
bool _error = false;
|
bool _error = false;
|
||||||
|
|
@ -226,6 +228,10 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
(v) {
|
(v) {
|
||||||
_url = v;
|
_url = v;
|
||||||
}),
|
}),
|
||||||
|
if (_serviceIndex == 7)
|
||||||
|
_textEditing("Html", context, "ex. <p>Text</p>", (v) {
|
||||||
|
_html = v;
|
||||||
|
}),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
|
|
@ -293,9 +299,12 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
(await service.getVideoList(_url))
|
(await service.getVideoList(_url))
|
||||||
.map((e) => e.toJson())
|
.map((e) => e.toJson())
|
||||||
.toList();
|
.toList();
|
||||||
} else {
|
} else if (_serviceIndex == 6) {
|
||||||
result = (await service
|
result = (await service
|
||||||
.getHtmlContent(_url));
|
.getHtmlContent(_url));
|
||||||
|
} else {
|
||||||
|
result = (await service
|
||||||
|
.cleanHtmlContent(_html));
|
||||||
}
|
}
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,12 @@ class TestSource extends MProvider {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean html up for reader
|
||||||
|
@override
|
||||||
|
Future<String> cleanHtmlContent(String html) async {
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
// For anime episode video list
|
// For anime episode video list
|
||||||
@override
|
@override
|
||||||
Future<List<MVideo>> getVideoList(String url) async {
|
Future<List<MVideo>> getVideoList(String url) async {
|
||||||
|
|
@ -349,6 +355,10 @@ class DefaultExtension extends MProvider {
|
||||||
async getHtmlContent(url) {
|
async getHtmlContent(url) {
|
||||||
throw new Error("getHtmlContent not implemented");
|
throw new Error("getHtmlContent not implemented");
|
||||||
}
|
}
|
||||||
|
// Clean html up for reader
|
||||||
|
async cleanHtmlContent(html) {
|
||||||
|
throw new Error("cleanHtmlContent not implemented");
|
||||||
|
}
|
||||||
// For anime episode video list
|
// For anime episode video list
|
||||||
async getVideoList(url) {
|
async getVideoList(url) {
|
||||||
throw new Error("getVideoList not implemented");
|
throw new Error("getVideoList not implemented");
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'update_manga_detail_providers.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$updateMangaDetailHash() => r'dcc5fd8f666959f62ee9ad6540eb0493ac9759f1';
|
String _$updateMangaDetailHash() => r'a86fe8fea46e411203182287c970cd80cc9a1a0c';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,13 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
final cbzFile = File(p.join(mangaDir!.path, "${widget.chapter.name}.cbz"));
|
final cbzFile = File(p.join(mangaDir!.path, "${widget.chapter.name}.cbz"));
|
||||||
final mp4File = File(p.join(mangaDir.path,
|
final mp4File = File(p.join(mangaDir.path,
|
||||||
"${widget.chapter.name!.replaceForbiddenCharacters(' ')}.mp4"));
|
"${widget.chapter.name!.replaceForbiddenCharacters(' ')}.mp4"));
|
||||||
|
final htmlFile = File(p.join(mangaDir.path, "${widget.chapter.name}.html"));
|
||||||
if (cbzFile.existsSync()) {
|
if (cbzFile.existsSync()) {
|
||||||
files = [XFile(cbzFile.path)];
|
files = [XFile(cbzFile.path)];
|
||||||
} else if (mp4File.existsSync()) {
|
} else if (mp4File.existsSync()) {
|
||||||
files = [XFile(mp4File.path)];
|
files = [XFile(mp4File.path)];
|
||||||
|
} else if (htmlFile.existsSync()) {
|
||||||
|
files = [XFile(htmlFile.path)];
|
||||||
} else {
|
} else {
|
||||||
files = path!.listSync().map((e) => XFile(e.path)).toList();
|
files = path!.listSync().map((e) => XFile(e.path)).toList();
|
||||||
}
|
}
|
||||||
|
|
@ -86,6 +89,13 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
mp4File.deleteSync();
|
mp4File.deleteSync();
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
final htmlFile =
|
||||||
|
File(p.join(mangaDir!.path, "${widget.chapter.name}.html"));
|
||||||
|
if (htmlFile.existsSync()) {
|
||||||
|
htmlFile.deleteSync();
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
path!.deleteSync(recursive: true);
|
path!.deleteSync(recursive: true);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
required Chapter chapter,
|
required Chapter chapter,
|
||||||
bool? useWifi,
|
bool? useWifi,
|
||||||
}) async {
|
}) async {
|
||||||
|
final http = MClient.init(
|
||||||
|
reqcopyWith: {'useDartHttpClient': true, 'followRedirects': false});
|
||||||
List<PageUrl> pageUrls = [];
|
List<PageUrl> pageUrls = [];
|
||||||
List<DownloadTask> tasks = [];
|
List<DownloadTask> tasks = [];
|
||||||
final StorageProvider storageProvider = StorageProvider();
|
final StorageProvider storageProvider = StorageProvider();
|
||||||
|
|
@ -48,7 +50,6 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
final chapterName = chapter.name!.replaceForbiddenCharacters(' ');
|
final chapterName = chapter.name!.replaceForbiddenCharacters(' ');
|
||||||
|
|
||||||
final itemType = chapter.manga.value!.itemType;
|
final itemType = chapter.manga.value!.itemType;
|
||||||
final isManga = itemType == ItemType.manga;
|
|
||||||
final itemTypePath = itemType == ItemType.manga
|
final itemTypePath = itemType == ItemType.manga
|
||||||
? "Manga"
|
? "Manga"
|
||||||
: itemType == ItemType.anime
|
: itemType == ItemType.anime
|
||||||
|
|
@ -60,13 +61,18 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
"${manga.source} (${manga.lang!.toUpperCase()})",
|
"${manga.source} (${manga.lang!.toUpperCase()})",
|
||||||
manga.name!.replaceForbiddenCharacters('_'),
|
manga.name!.replaceForbiddenCharacters('_'),
|
||||||
];
|
];
|
||||||
if (isManga) {
|
if (itemType == ItemType.manga) {
|
||||||
pathSegments.add(scanlator);
|
pathSegments.add(scanlator);
|
||||||
pathSegments.add(chapter.name!.replaceForbiddenCharacters('_'));
|
pathSegments.add(chapter.name!.replaceForbiddenCharacters('_'));
|
||||||
}
|
}
|
||||||
final finalPath = p.joinAll(pathSegments);
|
final finalPath = p.joinAll(pathSegments);
|
||||||
path = Directory(p.join(path1!.path, finalPath));
|
path = Directory(p.join(path1!.path, finalPath));
|
||||||
Map<String, String> videoHeader = {};
|
Map<String, String> videoHeader = {};
|
||||||
|
Map<String, String> htmlHeader = {
|
||||||
|
"Priority": "u=0, i",
|
||||||
|
"User-Agent":
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
|
||||||
|
};
|
||||||
bool hasM3U8File = false;
|
bool hasM3U8File = false;
|
||||||
bool nonM3U8File = false;
|
bool nonM3U8File = false;
|
||||||
M3u8Downloader? m3u8Downloader;
|
M3u8Downloader? m3u8Downloader;
|
||||||
|
|
@ -75,6 +81,7 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
int? m3u8MediaSequence;
|
int? m3u8MediaSequence;
|
||||||
|
|
||||||
Future<void> processConvert() async {
|
Future<void> processConvert() async {
|
||||||
|
if (itemType == ItemType.novel) return;
|
||||||
if (hasM3U8File) {
|
if (hasM3U8File) {
|
||||||
await m3u8Downloader?.mergeTsToMp4(p.join(path!.path, "$chapterName.mp4"),
|
await m3u8Downloader?.mergeTsToMp4(p.join(path!.path, "$chapterName.mp4"),
|
||||||
p.join(path.path, chapterName));
|
p.join(path.path, chapterName));
|
||||||
|
|
@ -109,7 +116,7 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
isar.settings.putSync(settings..chapterPageUrlsList = chapterPageUrls));
|
isar.settings.putSync(settings..chapterPageUrlsList = chapterPageUrls));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isManga) {
|
if (itemType == ItemType.manga) {
|
||||||
ref
|
ref
|
||||||
.read(getChapterPagesProvider(
|
.read(getChapterPagesProvider(
|
||||||
chapter: chapter,
|
chapter: chapter,
|
||||||
|
|
@ -120,7 +127,7 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
isOk = true;
|
isOk = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else if (itemType == ItemType.anime) {
|
||||||
ref.read(getVideoListProvider(episode: chapter).future).then((value) async {
|
ref.read(getVideoListProvider(episode: chapter).future).then((value) async {
|
||||||
final m3u8Urls = value.$1
|
final m3u8Urls = value.$1
|
||||||
.where((element) =>
|
.where((element) =>
|
||||||
|
|
@ -150,6 +157,25 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
isOk = true;
|
isOk = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (itemType == ItemType.novel && chapter.url != null) {
|
||||||
|
final cookie = MClient.getCookiesPref(chapter.url!);
|
||||||
|
final headers = itemType == ItemType.manga
|
||||||
|
? ref.watch(headersProvider(source: manga.source!, lang: manga.lang!))
|
||||||
|
: itemType == ItemType.anime
|
||||||
|
? videoHeader
|
||||||
|
: htmlHeader;
|
||||||
|
if (cookie.isNotEmpty) {
|
||||||
|
final userAgent = isar.settings.getSync(227)!.userAgent!;
|
||||||
|
headers.addAll(cookie);
|
||||||
|
headers[HttpHeaders.userAgentHeader] = userAgent;
|
||||||
|
}
|
||||||
|
final res = await http.get(Uri.parse(chapter.url!), headers: headers);
|
||||||
|
if (res.headers.containsKey("Location")) {
|
||||||
|
pageUrls = [PageUrl(res.headers["Location"]!)];
|
||||||
|
} else {
|
||||||
|
pageUrls = [PageUrl(chapter.url!)];
|
||||||
|
}
|
||||||
|
isOk = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Future.doWhile(() async {
|
await Future.doWhile(() async {
|
||||||
|
|
@ -166,12 +192,20 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
ref.watch(saveAsCBZArchiveStateProvider);
|
ref.watch(saveAsCBZArchiveStateProvider);
|
||||||
bool mp4FileExist =
|
bool mp4FileExist =
|
||||||
await File(p.join(mangaDir.path, "$chapterName.mp4")).exists();
|
await File(p.join(mangaDir.path, "$chapterName.mp4")).exists();
|
||||||
if (!cbzFileExist && isManga || !mp4FileExist && !isManga) {
|
bool htmlFileExist =
|
||||||
|
await File(p.join(mangaDir.path, "$chapterName.html")).exists();
|
||||||
|
if (!cbzFileExist && itemType == ItemType.manga ||
|
||||||
|
!mp4FileExist && itemType == ItemType.anime ||
|
||||||
|
!htmlFileExist && itemType == ItemType.novel) {
|
||||||
for (var index = 0; index < pageUrls.length; index++) {
|
for (var index = 0; index < pageUrls.length; index++) {
|
||||||
final path2 = Directory(p.join(
|
final path2 = Directory(p.join(
|
||||||
path1.path,
|
path1.path,
|
||||||
"downloads",
|
"downloads",
|
||||||
isManga ? "Manga" : "Anime",
|
itemType == ItemType.manga
|
||||||
|
? "Manga"
|
||||||
|
: itemType == ItemType.anime
|
||||||
|
? "Anime"
|
||||||
|
: "Novel",
|
||||||
"${manga.source} (${manga.lang!.toUpperCase()})",
|
"${manga.source} (${manga.lang!.toUpperCase()})",
|
||||||
manga.name!.replaceForbiddenCharacters('_')));
|
manga.name!.replaceForbiddenCharacters('_')));
|
||||||
if (!(await path2.exists())) {
|
if (!(await path2.exists())) {
|
||||||
|
|
@ -184,10 +218,12 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
}
|
}
|
||||||
final page = pageUrls[index];
|
final page = pageUrls[index];
|
||||||
final cookie = MClient.getCookiesPref(page.url);
|
final cookie = MClient.getCookiesPref(page.url);
|
||||||
final headers = isManga
|
final headers = itemType == ItemType.manga
|
||||||
? ref.watch(
|
? ref.watch(
|
||||||
headersProvider(source: manga.source!, lang: manga.lang!))
|
headersProvider(source: manga.source!, lang: manga.lang!))
|
||||||
: videoHeader;
|
: itemType == ItemType.anime
|
||||||
|
? videoHeader
|
||||||
|
: htmlHeader;
|
||||||
if (cookie.isNotEmpty) {
|
if (cookie.isNotEmpty) {
|
||||||
final userAgent = isar.settings.getSync(227)!.userAgent!;
|
final userAgent = isar.settings.getSync(227)!.userAgent!;
|
||||||
headers.addAll(cookie);
|
headers.addAll(cookie);
|
||||||
|
|
@ -196,7 +232,7 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
Map<String, String> pageHeaders = headers;
|
Map<String, String> pageHeaders = headers;
|
||||||
pageHeaders.addAll(page.headers ?? {});
|
pageHeaders.addAll(page.headers ?? {});
|
||||||
|
|
||||||
if (isManga) {
|
if (itemType == ItemType.manga) {
|
||||||
final file = File(p.join(tempDir.path, "Mangayomi", finalPath,
|
final file = File(p.join(tempDir.path, "Mangayomi", finalPath,
|
||||||
"${padIndex(index + 1)}.jpg"));
|
"${padIndex(index + 1)}.jpg"));
|
||||||
if (file.existsSync()) {
|
if (file.existsSync()) {
|
||||||
|
|
@ -222,7 +258,7 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
requiresWiFi: onlyOnWifi));
|
requiresWiFi: onlyOnWifi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (itemType == ItemType.anime) {
|
||||||
final file = File(
|
final file = File(
|
||||||
p.join(tempDir.path, "Mangayomi", finalPath, "$chapterName.mp4"));
|
p.join(tempDir.path, "Mangayomi", finalPath, "$chapterName.mp4"));
|
||||||
if (file.existsSync()) {
|
if (file.existsSync()) {
|
||||||
|
|
@ -270,6 +306,31 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
requiresWiFi: onlyOnWifi));
|
requiresWiFi: onlyOnWifi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
final file = File(p.join(
|
||||||
|
tempDir.path, "Mangayomi", finalPath, "$chapterName.html"));
|
||||||
|
if (file.existsSync()) {
|
||||||
|
await file.copy(p.join(path.path, "$chapterName.html"));
|
||||||
|
await file.delete();
|
||||||
|
} else {
|
||||||
|
if (!(await path.exists())) {
|
||||||
|
await path.create();
|
||||||
|
}
|
||||||
|
if (!(await File(p.join(path.path, "$chapterName.html"))
|
||||||
|
.exists())) {
|
||||||
|
tasks.add(DownloadTask(
|
||||||
|
taskId: page.url,
|
||||||
|
headers: pageHeaders,
|
||||||
|
url: page.url.trim().trimLeft().trimRight(),
|
||||||
|
filename: "$chapterName.html",
|
||||||
|
baseDirectory: BaseDirectory.temporary,
|
||||||
|
directory: p.join("Mangayomi", finalPath),
|
||||||
|
updates: Updates.statusAndProgress,
|
||||||
|
allowPause: true,
|
||||||
|
retries: 3,
|
||||||
|
requiresWiFi: onlyOnWifi));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +359,9 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
await FileDownloader().downloadBatch(
|
await FileDownloader().downloadBatch(
|
||||||
tasks,
|
tasks,
|
||||||
batchProgressCallback: (succeeded, failed) async {
|
batchProgressCallback: (succeeded, failed) async {
|
||||||
if (isManga || hasM3U8File) {
|
if (itemType == ItemType.manga ||
|
||||||
|
itemType == ItemType.novel ||
|
||||||
|
hasM3U8File) {
|
||||||
if (succeeded == tasks.length) {
|
if (succeeded == tasks.length) {
|
||||||
await processConvert();
|
await processConvert();
|
||||||
}
|
}
|
||||||
|
|
@ -335,7 +398,7 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
},
|
},
|
||||||
taskProgressCallback: (taskProgress) async {
|
taskProgressCallback: (taskProgress) async {
|
||||||
final progress = taskProgress.progress;
|
final progress = taskProgress.progress;
|
||||||
if (!isManga && !hasM3U8File) {
|
if (itemType == ItemType.anime && !hasM3U8File) {
|
||||||
bool isEmpty = isar.downloads
|
bool isEmpty = isar.downloads
|
||||||
.filter()
|
.filter()
|
||||||
.chapterIdEqualTo(chapter.id!)
|
.chapterIdEqualTo(chapter.id!)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'download_provider.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$downloadChapterHash() => r'de8e2d5b952071bc0d014fc3aa5c9b0714fbcee0';
|
String _$downloadChapterHash() => r'2873b00f9f4d0fd91bc90a28e2700a6c0d187a46';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ part of 'fetch_novel_sources.dart';
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$fetchNovelSourcesListHash() =>
|
String _$fetchNovelSourcesListHash() =>
|
||||||
r'cc4b989c0248c3b16155444c0c429d1ed0025ecb';
|
r'1444d9ca12204ccf5389efe085c8a20e3498a808';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import 'package:mangayomi/eval/dart/service.dart';
|
import 'dart:io';
|
||||||
import 'package:mangayomi/eval/javascript/service.dart';
|
|
||||||
|
import 'package:html/parser.dart';
|
||||||
|
import 'package:mangayomi/eval/lib.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/providers/storage_provider.dart';
|
||||||
import 'package:mangayomi/utils/utils.dart';
|
import 'package:mangayomi/utils/utils.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
@ -12,13 +14,24 @@ Future<String> getHtmlContent(Ref ref, {required Chapter chapter}) async {
|
||||||
if (!chapter.manga.isLoaded) {
|
if (!chapter.manga.isLoaded) {
|
||||||
chapter.manga.loadSync();
|
chapter.manga.loadSync();
|
||||||
}
|
}
|
||||||
|
final storageProvider = StorageProvider();
|
||||||
|
final mangaDirectory = await storageProvider.getMangaMainDirectory(chapter);
|
||||||
|
final htmlPath = "${mangaDirectory!.path}${chapter.name}.html";
|
||||||
|
final htmlFile = File(htmlPath);
|
||||||
|
String? htmlContent;
|
||||||
|
if (await htmlFile.exists()) {
|
||||||
|
htmlContent = await htmlFile.readAsString();
|
||||||
|
final temp = parse(htmlContent);
|
||||||
|
temp.getElementsByTagName("script").forEach((el) => el.remove());
|
||||||
|
htmlContent = temp.outerHtml;
|
||||||
|
}
|
||||||
final source =
|
final source =
|
||||||
getSource(chapter.manga.value!.lang!, chapter.manga.value!.source!);
|
getSource(chapter.manga.value!.lang!, chapter.manga.value!.source!);
|
||||||
String? html;
|
String? html;
|
||||||
if (source!.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
if (htmlContent != null) {
|
||||||
html = await DartExtensionService(source).getHtmlContent(chapter.url!);
|
html = await getExtensionService(source!).cleanHtmlContent(htmlContent);
|
||||||
} else {
|
} else {
|
||||||
html = await JsExtensionService(source).getHtmlContent(chapter.url!);
|
html = await getExtensionService(source!).getHtmlContent(chapter.url!);
|
||||||
}
|
}
|
||||||
return '''<div id="readerViewContent"><div style="padding: 2em;">${html.substring(1, html.length - 1)}</div></div>'''
|
return '''<div id="readerViewContent"><div style="padding: 2em;">${html.substring(1, html.length - 1)}</div></div>'''
|
||||||
.replaceAll("\\n", "")
|
.replaceAll("\\n", "")
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_html_content.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getHtmlContentHash() => r'0c964239912b7f93bfb4c80a47f7266ff1ae3f5e';
|
String _$getHtmlContentHash() => r'c88d61e16b50cef52da04efc5c53de7390f4910d';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue