From 6a099415db4722687632e978491cbb4728e55369 Mon Sep 17 00:00:00 2001 From: Moustapha Kodjo Amadou <107993382+kodjodevf@users.noreply.github.com> Date: Mon, 24 Nov 2025 16:59:21 +0100 Subject: [PATCH] refactor: simplify filter parsing logic & pass client cookie to mihon server --- lib/eval/mihon/service.dart | 38 +++++++ lib/services/fetch_sources_list.dart | 147 ++++++++++++++------------- 2 files changed, 114 insertions(+), 71 deletions(-) diff --git a/lib/eval/mihon/service.dart b/lib/eval/mihon/service.dart index 747b5c35..539497e0 100644 --- a/lib/eval/mihon/service.dart +++ b/lib/eval/mihon/service.dart @@ -7,7 +7,9 @@ import 'package:mangayomi/eval/model/m_chapter.dart'; import 'package:mangayomi/eval/model/m_manga.dart'; import 'package:mangayomi/eval/model/m_pages.dart'; import 'package:mangayomi/eval/model/source_preference.dart'; +import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/page.dart'; +import 'package:mangayomi/models/settings.dart'; import 'package:mangayomi/models/source.dart'; import 'package:mangayomi/models/video.dart'; import 'package:mangayomi/services/http/m_client.dart'; @@ -55,7 +57,9 @@ class MihonExtensionService implements ExtensionService { "preferences": getSourcePreferences(), "data": source.sourceCode, }), + headers: getCookie(), ); + hasError(res); final data = jsonDecode(res.body) as Map; final pages = MangaPages.fromJson(data, source.itemType); return MPages( @@ -90,7 +94,9 @@ class MihonExtensionService implements ExtensionService { "preferences": getSourcePreferences(), "data": source.sourceCode, }), + headers: getCookie(), ); + hasError(res); final data = jsonDecode(res.body) as Map; final pages = MangaPages.fromJson(data, source.itemType); return MPages( @@ -126,7 +132,9 @@ class MihonExtensionService implements ExtensionService { "preferences": getSourcePreferences(), "data": source.sourceCode, }), + headers: getCookie(), ); + hasError(res); final data = jsonDecode(res.body) as Map; final pages = MangaPages.fromJson(data, source.itemType); return MPages( @@ -161,7 +169,9 @@ class MihonExtensionService implements ExtensionService { "preferences": getSourcePreferences(), "data": source.sourceCode, }), + headers: getCookie(), ); + hasError(res); final data = jsonDecode(res.body) as Map; final chapters = await getChapterList(url); return MManga( @@ -196,7 +206,9 @@ class MihonExtensionService implements ExtensionService { "preferences": getSourcePreferences(), "data": source.sourceCode, }), + headers: getCookie(), ); + hasError(res); final data = jsonDecode(res.body) as List; return data .map( @@ -222,7 +234,9 @@ class MihonExtensionService implements ExtensionService { "preferences": getSourcePreferences(), "data": source.sourceCode, }), + headers: getCookie(), ); + hasError(res); final data = jsonDecode(res.body) as List; return data.map((e) => PageUrl(e['imageUrl'])).toList(); } @@ -237,7 +251,9 @@ class MihonExtensionService implements ExtensionService { "preferences": getSourcePreferences(), "data": source.sourceCode, }), + headers: getCookie(), ); + hasError(res); final data = jsonDecode(res.body) as List; return data.map((e) { final tempHeaders = @@ -336,4 +352,26 @@ class MihonExtensionService implements ExtensionService { } }).toList(); } + + Map getCookie() { + final userAgent = isar.settings.getSync(227)!.userAgent; + return { + ...MClient.getCookiesPref(source.baseUrl!), + if (userAgent != null) 'user-agent': userAgent, + }; + } +} + +void hasError(Response response) { + try { + final errorMessage = jsonDecode(response.body)['error']; + final code = jsonDecode(response.body)['code']; + if (errorMessage != null && code != null) { + throw "errorMessage: $errorMessage \n\n\nstatusCode: $code"; + } + } catch (e) { + if (e.toString().startsWith('errorMessage:')) { + throw e.toString().replaceFirst('errorMessage: ', ''); + } + } } diff --git a/lib/services/fetch_sources_list.dart b/lib/services/fetch_sources_list.dart index c23b0ed5..11f83339 100644 --- a/lib/services/fetch_sources_list.dart +++ b/lib/services/fetch_sources_list.dart @@ -371,82 +371,87 @@ Future fetchFilterListDalvik( body: jsonEncode({"method": "filters$name", "data": source.sourceCode}), ); final data = jsonDecode(res.body) as List; - final filters = data.expand((e) sync* { - if (e['name'] is String && - e['state'] is Map && - e['values'] is List) { - yield SortFilter( - "${e['name']}Filter", - e['name'], - SortState(e['state']['index'], e['state']['ascending'], null), - (e['values'] as List) - .map((e) => SelectFilterOption(e, e, null)) - .toList(), - null, - ); - } else if (e['name'] is String && - e['state'] is int && - (e['values'] is List || e['vals'] is List)) { - yield SelectFilter( - "${e['name']}Filter", - e['name'], - e['state'], - e['vals'] is List - ? (e['vals'] as List) - .map( - (e) => SelectFilterOption(e['first'], e['second'], null), - ) - .toList() - : e['values'] is List - ? (e['values'] as List) - .map((e) => SelectFilterOption(e, e, null)) - .toList() - : [], - "SelectFilter", - ); - } else if (e['name'] is String && e['state'] is List) { - yield GroupFilter( - "${e['name']}Filter", - e['name'], - (e['state'] as List).map((e) { - if (e['included'] is bool && - e['ignored'] is bool && - e['excluded'] is bool) { - return TriStateFilter( - null, - e['name'], - e['id'] ?? e['name'], - null, - state: e['state'], - ); - } - return CheckBoxFilter( - null, - e['name'], - e['id'] ?? e['name'], - null, - state: e['state'], - ); - }).toList(), - "GroupFilter", - ); - } else if (e['name'] is String && e['state'] is String) { - yield TextFilter( - "${e['name']}Filter", - e['name'], - null, - state: e['state'], - ); - } else if (e['name'] is String && e['state'] is int) { - yield HeaderFilter(e['name'], "${e['name']}Filter"); - } - }).toList(); - return FilterList(filters); + + return FilterList(filtersFromJson(data)); } catch (_) { return null; } } +List filtersFromJson(List json) { + return json.expand((e) sync* { + if (e['name'] is String && + e['state'] is Map && + e['values'] is List) { + yield SortFilter( + "${e['name']}Filter", + e['name'], + SortState(e['state']['index'], e['state']['ascending'], null), + (e['values'] as List) + .map((e) => SelectFilterOption(e, e, null)) + .toList(), + null, + ); + } else if (e['name'] is String && + e['state'] is int && + (e['values'] is List || e['vals'] is List)) { + yield SelectFilter( + "${e['name']}Filter", + e['name'], + e['state'], + e['vals'] is List + ? (e['vals'] as List) + .map((e) => SelectFilterOption(e['first'], e['second'], null)) + .toList() + : e['values'] is List + ? (e['values'] as List) + .map( + (e) => (e is Map) + ? SelectFilterOption(e['value'], e['value'], null) + : SelectFilterOption(e, e, null), + ) + .toList() + : [], + "SelectFilter", + ); + } else if (e['name'] is String && e['state'] is bool) { + yield CheckBoxFilter( + null, + e['name'], + e['id'] ?? e['name'], + null, + state: e['state'], + ); + } else if (e['included'] is bool && + e['ignored'] is bool && + e['excluded'] is bool) { + yield TriStateFilter( + null, + e['name'], + e['id'] ?? e['name'], + null, + state: e['state'], + ); + } else if (e['name'] is String && e['state'] is List) { + yield GroupFilter( + "${e['name']}Filter", + e['name'], + filtersFromJson((e['state'] as List)), + "GroupFilter", + ); + } else if (e['name'] is String && e['state'] is String) { + yield TextFilter( + "${e['name']}Filter", + e['name'], + null, + state: e['state'], + ); + } else if (e['name'] is String && e['state'] is int) { + yield HeaderFilter(e['name'], "${e['name']}Filter"); + } + }).toList(); +} + Future?> fetchPreferencesDalvik( InterceptedClient client, Source source,