fix get torrent video list
This commit is contained in:
parent
792f6547ef
commit
11dea6dfaf
8 changed files with 107 additions and 47 deletions
|
|
@ -1,7 +1,9 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:flutter_qjs/flutter_qjs.dart';
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:mangayomi/services/http/m_client.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class JsHttpClient {
|
||||
late JavascriptRuntime runtime;
|
||||
|
|
@ -14,33 +16,19 @@ class JsHttpClient {
|
|||
}
|
||||
|
||||
runtime.onMessage('http_get', (dynamic args) async {
|
||||
return jsonEncode((await client(args[1]).get(Uri.parse(args[2]),
|
||||
headers: (args[3] as Map?)?.toMapStringString))
|
||||
.toJson());
|
||||
return await _toHttpResponse(client(args[1]), "GET", args);
|
||||
});
|
||||
runtime.onMessage('http_post', (dynamic args) async {
|
||||
return jsonEncode((await client(args[1]).post(Uri.parse(args[2]),
|
||||
headers: (args[3] as Map?)?.toMapStringString,
|
||||
body: (args[4] as Map?)?.toMapStringString))
|
||||
.toJson());
|
||||
return await _toHttpResponse(client(args[1]), "POST", args);
|
||||
});
|
||||
runtime.onMessage('http_put', (dynamic args) async {
|
||||
return (await client(args[1]).put(Uri.parse(args[2]),
|
||||
headers: (args[3] as Map?)?.toMapStringString, body: args[4]))
|
||||
.toJson();
|
||||
return await _toHttpResponse(client(args[1]), "PUT", args);
|
||||
});
|
||||
runtime.onMessage('http_delete', (dynamic args) async {
|
||||
return jsonEncode((await client(args[1]).delete(Uri.parse(args[2]),
|
||||
headers: (args[3] as Map?)?.map(
|
||||
(key, value) => MapEntry(key.toString(), value.toString())),
|
||||
body: (args[4] as Map?)?.toMapStringString))
|
||||
.toJson());
|
||||
return await _toHttpResponse(client(args[1]), "DELETE", args);
|
||||
});
|
||||
runtime.onMessage('http_patch', (dynamic args) async {
|
||||
return jsonEncode((await client(args[1]).patch(Uri.parse(args[2]),
|
||||
headers: (args[3] as Map?)?.toMapStringString,
|
||||
body: (args[4] as Map?)?.toMapStringString))
|
||||
.toJson());
|
||||
return await _toHttpResponse(client(args[1]), "PATCH", args);
|
||||
});
|
||||
runtime.evaluate('''
|
||||
class Client {
|
||||
|
|
@ -92,6 +80,38 @@ class Client {
|
|||
}
|
||||
}
|
||||
|
||||
Future<String> _toHttpResponse(Client client, String method, List args) async {
|
||||
final url = args[2] as String;
|
||||
final headers = (args[3] as Map?)?.toMapStringString;
|
||||
final body = args.length >= 5 ? (args[4] as Map?)?.toMapStringDynamic : null;
|
||||
var request = http.Request(method, Uri.parse(url));
|
||||
request.headers.addAll(headers ?? {});
|
||||
if ((request.headers[HttpHeaders.contentTypeHeader]
|
||||
?.contains("application/json")) ??
|
||||
false) {
|
||||
request.body = json.encode(body);
|
||||
request.headers.addAll(headers ?? {});
|
||||
http.StreamedResponse response = await client.send(request);
|
||||
final res = Response("", response.statusCode,
|
||||
request: response.request,
|
||||
headers: response.headers,
|
||||
isRedirect: response.isRedirect,
|
||||
persistentConnection: response.persistentConnection,
|
||||
reasonPhrase: response.reasonPhrase);
|
||||
Map<String, dynamic> resMap = res.toJson();
|
||||
resMap["body"] = await response.stream.bytesToString();
|
||||
return jsonEncode(resMap);
|
||||
}
|
||||
final future = switch (method) {
|
||||
"GET" => client.get(Uri.parse(url), headers: headers),
|
||||
"POST" => client.post(Uri.parse(url), headers: headers, body: body),
|
||||
"PUT" => client.put(Uri.parse(url), headers: headers, body: body),
|
||||
"DELETE" => client.delete(Uri.parse(url), headers: headers, body: body),
|
||||
_ => client.patch(Uri.parse(url), headers: headers, body: body),
|
||||
};
|
||||
return jsonEncode((await future).toJson());
|
||||
}
|
||||
|
||||
extension ResponseExtexsion on Response {
|
||||
Map<String, dynamic> toJson() => {
|
||||
'body': body,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import 'package:mangayomi/modules/widgets/progress_center.dart';
|
|||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/aniskip.dart';
|
||||
import 'package:mangayomi/services/get_video_list.dart';
|
||||
import 'package:mangayomi/services/torrent_server.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
import 'package:media_kit_video/media_kit_video.dart';
|
||||
|
|
@ -38,9 +39,12 @@ class AnimePlayerView extends riv.ConsumerStatefulWidget {
|
|||
}
|
||||
|
||||
class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
||||
String? _infoHash;
|
||||
List<String> _infoHashList = [];
|
||||
@override
|
||||
void dispose() {
|
||||
for (var infoHash in _infoHashList) {
|
||||
MTorrentServer().removeTorrent(infoHash);
|
||||
}
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||
overlays: SystemUiOverlay.values);
|
||||
super.dispose();
|
||||
|
|
@ -53,8 +57,8 @@ class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
|||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||
return serversData.when(
|
||||
data: (data) {
|
||||
final (videos, isLocal, infoHash) = data;
|
||||
_infoHash = infoHash;
|
||||
final (videos, isLocal, infoHashList) = data;
|
||||
_infoHashList = infoHashList;
|
||||
if (videos.isEmpty &&
|
||||
!(widget.episode.manga.value!.isLocalArchive ?? false)) {
|
||||
return Scaffold(
|
||||
|
|
@ -77,7 +81,7 @@ class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
|||
episode: widget.episode,
|
||||
videos: videos,
|
||||
isLocal: isLocal,
|
||||
isTorrent: _infoHash != null);
|
||||
isTorrent: _infoHashList.isNotEmpty);
|
||||
},
|
||||
error: (error, stackTrace) => Scaffold(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'add_torrent.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$addTorrentFromUrlOrFromFileHash() =>
|
||||
r'8102259b30765a5c5cc57870f5c583bd5d421eee';
|
||||
r'a159635689b8f8ac22bb9faa10407f09c8008f71';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
part 'get_video_list.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<(List<Video>, bool, String?)> getVideoList(Ref ref,
|
||||
Future<(List<Video>, bool, List<String>)> getVideoList(Ref ref,
|
||||
{required Chapter episode}) async {
|
||||
final storageProvider = StorageProvider();
|
||||
final mangaDirectory = await storageProvider.getMangaMainDirectory(episode);
|
||||
|
|
@ -22,18 +22,40 @@ Future<(List<Video>, bool, String?)> getVideoList(Ref ref,
|
|||
episode.manga.value!.source != "torrent";
|
||||
final mp4animePath =
|
||||
"${mangaDirectory!.path}${episode.name!.replaceForbiddenCharacters(' ')}.mp4";
|
||||
|
||||
List<String> infoHashes = [];
|
||||
if (await File(mp4animePath).exists() || isLocalArchive) {
|
||||
final path = isLocalArchive ? episode.archivePath : mp4animePath;
|
||||
return ([Video(path!, episode.name!, path, subtitles: [])], true, null);
|
||||
return (
|
||||
[Video(path!, episode.name!, path, subtitles: [])],
|
||||
true,
|
||||
infoHashes
|
||||
);
|
||||
}
|
||||
final source =
|
||||
getSource(episode.manga.value!.lang!, episode.manga.value!.source!);
|
||||
|
||||
if (source?.isTorrent ?? false || episode.manga.value!.source == "torrent") {
|
||||
final (videos, infohash) = await MTorrentServer()
|
||||
.getTorrentPlaylist(episode.url, episode.archivePath);
|
||||
return (videos, false, infohash);
|
||||
List<Video> list = [];
|
||||
|
||||
List<Video> torrentList = [];
|
||||
|
||||
if (source?.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
list = await DartExtensionService(source).getVideoList(episode.url!);
|
||||
} else {
|
||||
list = await JsExtensionService(source).getVideoList(episode.url!);
|
||||
}
|
||||
for (var v in list) {
|
||||
final (videos, infohash) =
|
||||
await MTorrentServer().getTorrentPlaylist(v.url, episode.archivePath);
|
||||
for (var video in videos) {
|
||||
torrentList
|
||||
.add(video..quality = video.quality.substringBeforeLast("."));
|
||||
if (infohash != null) {
|
||||
infoHashes.add(infohash);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (torrentList, false, infoHashes);
|
||||
}
|
||||
|
||||
List<Video> list = [];
|
||||
|
|
@ -48,5 +70,5 @@ Future<(List<Video>, bool, String?)> getVideoList(Ref ref,
|
|||
videos.add(video);
|
||||
}
|
||||
}
|
||||
return (videos, false, null);
|
||||
return (videos, false, infoHashes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_video_list.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getVideoListHash() => r'1c62b1a5bef8b55a73ba7a436f23609ec8270436';
|
||||
String _$getVideoListHash() => r'490d0a1fc3d0367e5386104f6cdfec69bd0e079a';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -35,7 +35,7 @@ const getVideoListProvider = GetVideoListFamily();
|
|||
|
||||
/// See also [getVideoList].
|
||||
class GetVideoListFamily
|
||||
extends Family<AsyncValue<(List<Video>, bool, String?)>> {
|
||||
extends Family<AsyncValue<(List<Video>, bool, List<String>)>> {
|
||||
/// See also [getVideoList].
|
||||
const GetVideoListFamily();
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ class GetVideoListFamily
|
|||
|
||||
/// See also [getVideoList].
|
||||
class GetVideoListProvider
|
||||
extends AutoDisposeFutureProvider<(List<Video>, bool, String?)> {
|
||||
extends AutoDisposeFutureProvider<(List<Video>, bool, List<String>)> {
|
||||
/// See also [getVideoList].
|
||||
GetVideoListProvider({
|
||||
required Chapter episode,
|
||||
|
|
@ -109,7 +109,8 @@ class GetVideoListProvider
|
|||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<(List<Video>, bool, String?)> Function(GetVideoListRef provider)
|
||||
FutureOr<(List<Video>, bool, List<String>)> Function(
|
||||
GetVideoListRef provider)
|
||||
create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
|
|
@ -127,7 +128,7 @@ class GetVideoListProvider
|
|||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<(List<Video>, bool, String?)>
|
||||
AutoDisposeFutureProviderElement<(List<Video>, bool, List<String>)>
|
||||
createElement() {
|
||||
return _GetVideoListProviderElement(this);
|
||||
}
|
||||
|
|
@ -149,13 +150,13 @@ class GetVideoListProvider
|
|||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin GetVideoListRef
|
||||
on AutoDisposeFutureProviderRef<(List<Video>, bool, String?)> {
|
||||
on AutoDisposeFutureProviderRef<(List<Video>, bool, List<String>)> {
|
||||
/// The parameter `episode` of this provider.
|
||||
Chapter get episode;
|
||||
}
|
||||
|
||||
class _GetVideoListProviderElement
|
||||
extends AutoDisposeFutureProviderElement<(List<Video>, bool, String?)>
|
||||
extends AutoDisposeFutureProviderElement<(List<Video>, bool, List<String>)>
|
||||
with GetVideoListRef {
|
||||
_GetVideoListProviderElement(super.provider);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,19 @@ import 'package:mangayomi/ffi/torrent_server_ffi.dart' as libmtorrentserver_ffi;
|
|||
|
||||
class MTorrentServer {
|
||||
final http = MClient.init();
|
||||
Future<bool> removeTorrent(String? inforHash) async {
|
||||
if (inforHash == null || inforHash.isEmpty) return false;
|
||||
try {
|
||||
final res = await http
|
||||
.delete(Uri.parse("$_baseUrl/torrent/remove?infohash=$inforHash"));
|
||||
if (res.statusCode == 200) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> check() async {
|
||||
if (_baseUrl == "http://127.0.0.1:0") return false;
|
||||
|
|
|
|||
16
pubspec.lock
16
pubspec.lock
|
|
@ -355,10 +355,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: equatable
|
||||
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
||||
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "2.0.7"
|
||||
exception_templates:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -672,10 +672,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: "8ae664a70174163b9f65ea68dd8673e29db8f9095de7b5cd00e167c621f4fef5"
|
||||
sha256: "8660b74171fafae4aa8202100fa2e55349e078281dadc73a241eb8e758534d9d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.6.0"
|
||||
version: "14.6.1"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1107,10 +1107,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||
sha256: "8c4967f8b7cb46dc914e178daa29813d83ae502e0529d7b0478330616a691ef7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.12"
|
||||
version: "2.2.14"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1434,10 +1434,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ dependencies:
|
|||
url_launcher: ^6.3.0
|
||||
package_info_plus: ^8.0.0
|
||||
permission_handler: ^11.3.1
|
||||
flutter_inappwebview: ^6.2.0-beta.1
|
||||
flutter_inappwebview: ^6.2.0-beta.2
|
||||
draggable_menu: ^4.4.1
|
||||
isar: 3.1.0+1
|
||||
isar_flutter_libs: 3.1.0+1
|
||||
|
|
|
|||
Loading…
Reference in a new issue