Compare commits

...

559 commits

Author SHA1 Message Date
github-actions[bot]
dff3d68bac Update extensions 2025-02-01 07:18:05 +00:00
Moustapha Kodjo Amadou
8834f32d40
Merge pull request #157 from NBA2K1/main
#156 fix
2025-02-01 08:17:48 +01:00
NBA2K1
57ad661c74 #156 fix
concurrent requests are limited now.
2025-02-01 07:01:43 +01:00
github-actions[bot]
cc12b0a9a9 Update extensions 2025-01-30 22:20:24 +00:00
Moustapha Kodjo Amadou
f737ea3d5d
Merge pull request #155 from Swakshan/extension/weebcentral
New manga source: Weebcentral
2025-01-30 23:20:07 +01:00
github-actions[bot]
17205d5285 Update extensions 2025-01-30 22:19:53 +00:00
Moustapha Kodjo Amadou
5435f605c9
Merge pull request #154 from Swakshan/extension/aniplay
Fix Aniplay
2025-01-30 23:19:36 +01:00
Swakshan
faddc125f6 extension(weebcentral): Added search & filter 2025-01-29 23:56:20 +05:30
Swakshan
e4e490cf63 extension(weebcentral): Extract manga pages 2025-01-29 21:56:16 +05:30
Swakshan
b5807a2928 extension(weebcentral): Added details 2025-01-29 17:13:56 +05:30
Swakshan
354fd00768 extension(weebcentral): Added popular & latest 2025-01-29 11:29:18 +05:30
Swakshan
7684b0e0ba extension(aniplay): Added Pahe provider and remove Anya provider 2025-01-27 23:08:16 +05:30
Swakshan
68401c05f1 extension(aniplay): Fixed Yuki provider 2025-01-27 23:01:35 +05:30
github-actions[bot]
55542460d7 Update extensions 2025-01-25 20:23:59 +00:00
Moustapha Kodjo Amadou
602276cd35
Merge pull request #146 from Swakshan/extension/netmirror
Update: Netmirror
2025-01-25 21:23:44 +01:00
Moustapha Kodjo Amadou
a03726e0a9
Merge pull request #147 from Schnitzel5/fix/mangadex-filter
fixed global variable access
2025-01-25 21:23:28 +01:00
Schnitzel5
61b3c81373 update version 2025-01-25 21:12:52 +01:00
Schnitzel5
e4da9ad453 fixed global variable access 2025-01-25 21:11:51 +01:00
Swakshan
666e58aa4f extension(netmirror): Validate stream link 2025-01-25 12:10:52 +05:30
Swakshan
f4ab4a1354 extension(netmirror): Added stream extraction preference 2025-01-25 12:01:16 +05:30
github-actions[bot]
c21045ffed Update extensions 2025-01-24 23:47:54 +00:00
Moustapha Kodjo Amadou
34d0c6c6a4
Merge pull request #144 from kashrtx/patch-2
Update animepahe source.dart to version 0.0.5
2025-01-25 00:47:39 +01:00
Moustapha Kodjo Amadou
0d9a818e6d
Merge pull request #143 from kashrtx/patch-1
Update animepahe.dart. Add feature: Preferred audio selection (jpn/eng).
2025-01-25 00:43:31 +01:00
Kaushal Bhingaradia
e3c5fd0deb
Update animepahe source.dart to version 0.0.5
- Update animepahe version constant to 0.0.5 after implementing Preferred Audio Preference feature #143
2025-01-24 13:22:01 -05:00
Kaushal Bhingaradia
ba3170bba0
Update animepahe.dart. Add feature: Preferred audio selection for episodes (English/Japanese)
- Added a feature allowing users to set a default audio preference            (English or Japanese).
- Default is Japanese, but users can switch to English, and the preference is saved.
- Eliminates the need to manually select English dub for each new episode.
2025-01-24 12:11:45 -05:00
Moustapha Kodjo Amadou
67a32248e0 - 2025-01-23 15:19:10 +01:00
github-actions[bot]
6285f9b05a Update extensions 2025-01-23 14:15:31 +00:00
Moustapha Kodjo Amadou
7b06e8061e fix 2025-01-23 15:15:13 +01:00
github-actions[bot]
90647a7f0a Update extensions 2025-01-23 14:00:07 +00:00
Moustapha Kodjo Amadou
9f170b7a76 rewrite MangaDex source code in JS 2025-01-23 14:59:30 +01:00
github-actions[bot]
24271a087e Update extensions 2025-01-23 05:37:30 +00:00
Moustapha Kodjo Amadou
f3e845b3b7
Merge pull request #142 from hollow-frenk/main
animesaturn: fix for this:
2025-01-23 06:37:12 +01:00
Moustapha Kodjo Amadou
b7ea56d72d
Update source.dart 2025-01-23 06:36:44 +01:00
Francesco De Feo
2801a25ddf animesaturn: fix for this:
dart_eval runtime exception: Bad state: No element
List.first (dart:core-patch/growable_array.dart:344)
SIterable.SgetProperty (package:dart_eval/src/eval/shared/stdlib/core/iterable.dart:609)
SList. S getProperty (package:dart-_eval/s/eval/shared/stdib/core/list.dart:900)
at < asynchronous gap>
Shangri-La Frontier 2
RUNTIME STATE
6-=-=========
Program offset: 831
Shangri-La Frontier 2
Stack sample: [L7: Instance of "$Future<$Response>', L8: Instance of '$Response', L9: $" «html» <body» «script type="text/javascript" src="/min.js" > </script»<noscript»<h1 style="text-align:center;color:red;"› «strong»Please turn JavaScript on and reload the page.</ strong> </h1></noscripts ‹script»function toNumbers(d)(var e=;d.replace(//g,function(d)epush(parselnt(d,16));return e/function toHexfor(vard=[d=1==arguments.length&&arguments|01.constructor==Array?arguments[Ol:arguments, e=**,f=0;f<d.length;f+
+)e+=(16>dff]?")". "*)+d[f|.toString(16);return e.toLowerCase())var a=toNumbers("F4baf9d74d4cb868c5317e9802ca7c1f""),b=toNumbers("Ic2aabd2a4a9ed25aeae78669546c8f9"),c=toNumbers("2e34487f1b463e342a9ec7986e427e80");document.cookie="ASNew-
Gv="+ toHex(slowAES.decrypt(c,2,a,b))+"; path=/";location.href="http://www.animesaturn.cx/anime/Dan-Da-Dan?d=1";</script></body></html>", L10: Instance of '$MManga', L11: Function{func: Closure: (dynamic, dynamic, List<$Value?>) => $Value? from Function
'Xpath@1865285211': static.), L12: $"//div@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100 text-white"/textO", L13: D, *L14: null, L15: null, L16: null]
Args sample: 1
Call stack: [0, -1]
TRACE:
Nanatsu no Taizai: Mokushiroku no Yonkishi 2
Episodio 9
825: PushConstant (C55)
Tail: 100 Years Quest
826: BoxString (L12)
827: PushArg (L9)
Dragon Ball Daima
828: PushArg (L12)
829: InvokeDynamic (LO.C8)
on Ball Daimal
830: PushReturnValue O
831: PushObjectProperty (L13.C56) < < < EXCEPTION
832: PushReturnValue ()
833: PushObjectProperty (LO.C57)
834: PushReturnValue
2025-01-23 00:32:03 +01:00
github-actions[bot]
39dfd2b586 Update extensions 2025-01-21 08:04:47 +00:00
Moustapha Kodjo Amadou
814f585057 netflixmirror: include conditional media name display based on user preference 2025-01-21 09:04:17 +01:00
github-actions[bot]
5202a7740e Update extensions 2025-01-20 12:16:25 +00:00
Moustapha Kodjo Amadou
6375baee7a netflixmirror: enable media name by default display 2025-01-20 13:16:02 +01:00
github-actions[bot]
c8a773c9fd Update extensions 2025-01-20 11:59:36 +00:00
Moustapha Kodjo Amadou
1744099791 Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2025-01-20 12:59:13 +01:00
Moustapha Kodjo Amadou
cc90b4105b fix 2025-01-20 12:59:05 +01:00
github-actions[bot]
7495be975e Update extensions 2025-01-20 11:52:00 +00:00
Moustapha Kodjo Amadou
de9bc757c4 ZoroTheme: add 'Raw' option for type selection 2025-01-20 12:51:31 +01:00
github-actions[bot]
8265ec53e3 Update extensions 2025-01-20 11:38:31 +00:00
Moustapha Kodjo Amadou
d570df212d
Merge pull request #138 from Swakshan/extension/netmirror
Updated NetflixMirror extension
2025-01-20 12:38:14 +01:00
Swakshan
4b76a30e3f extension(NetMirror): Updated links 2025-01-19 22:23:18 +05:30
Swakshan
791826c3c9 extension(NetMirror): Added prime 2025-01-19 22:23:18 +05:30
Swakshan
dffb779403 extension(netflixMirror): updated cookie logic 2025-01-19 22:23:18 +05:30
Swakshan
499197a59d extension(netflixMirror): updated display name logic 2025-01-19 22:23:18 +05:30
Swakshan
e869c3cfee extension(netflixMirror): Added stream quality preference 2025-01-19 22:23:18 +05:30
Swakshan
cea82dd040 extension(netflixMirror): Added 1080p support 2025-01-19 22:23:18 +05:30
Swakshan
970fe5d81c extension(netflixMirror): Use TV domain for cookie 2025-01-19 22:23:18 +05:30
github-actions[bot]
3adc787cf6 Update extensions 2025-01-17 15:57:19 +00:00
Moustapha Kodjo Amadou
0b89b4a917 + 2025-01-17 16:56:58 +01:00
github-actions[bot]
37ef74bf5d Update extensions 2025-01-17 15:16:48 +00:00
Moustapha Kodjo Amadou
ce2cc568a2 fix 2025-01-17 16:16:26 +01:00
github-actions[bot]
5d54fe8b25 Update extensions 2025-01-17 10:38:38 +00:00
Moustapha Kodjo Amadou
900c891713 Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2025-01-17 11:38:11 +01:00
Moustapha Kodjo Amadou
5fe963dce4 update filma24 2025-01-17 11:38:03 +01:00
github-actions[bot]
76c1a241a0 Update extensions 2025-01-17 10:34:41 +00:00
Moustapha Kodjo Amadou
3f361d56ae update filma24 baseUrl 2025-01-17 11:34:13 +01:00
Moustapha Kodjo Amadou
ca6d0d04a1 fix Anime-Sama 2025-01-17 11:32:35 +01:00
github-actions[bot]
2cae2d260a Update extensions 2025-01-16 10:04:16 +00:00
Moustapha Kodjo Amadou
c27b6649b3 extension(aniplay): add scanlator field for filler episodes 2025-01-16 11:03:56 +01:00
github-actions[bot]
752056a02e Update extensions 2025-01-16 09:58:37 +00:00
Moustapha Kodjo Amadou
458f266f18 add 'all' to provider preference 2025-01-16 10:58:12 +01:00
github-actions[bot]
c7edf0fd01 Update extensions 2025-01-15 05:27:07 +00:00
Moustapha Kodjo Amadou
e83cec01e2
Merge pull request #136 from Swakshan/extension/aniplay
New source: Aniplay
2025-01-15 06:26:50 +01:00
Swakshan
301d94c269 extension(aniplay): misc 2025-01-14 23:18:28 +05:30
Swakshan
6ae0c65e68 extension(aniplay): misc 2025-01-14 23:16:07 +05:30
Swakshan
3f284a05fc extension(aniplay): Added preferred video resolution 2025-01-14 22:44:40 +05:30
Swakshan
3bbb1599ee extension(aniplay): Mark filler episodes 2025-01-14 12:30:19 +05:30
Swakshan
1b69828fb6 extension(aniplay): Added preferred audio type 2025-01-14 12:30:19 +05:30
Swakshan
e2e3b526c3 extension(aniplay): Added servers 2025-01-14 12:30:19 +05:30
Swakshan
7f2eca5840 extension(aniplay): Added details 2025-01-14 12:30:19 +05:30
Swakshan
c910bb9f7c extension(aniplay): Added anilist support for latest, popular, search 2025-01-14 12:30:19 +05:30
github-actions[bot]
c0f96a3e6d Update extensions 2025-01-13 16:50:48 +00:00
Moustapha Kodjo Amadou
7bd3c80c60 + 2025-01-13 17:50:16 +01:00
github-actions[bot]
463425746e Update extensions 2025-01-12 22:18:28 +00:00
Moustapha Kodjo Amadou
b85ec3aba2
Update sudatchi.js 2025-01-12 23:18:10 +01:00
Moustapha Kodjo Amadou
d5113bedc5
Update serienstream.js 2025-01-12 23:17:04 +01:00
Moustapha Kodjo Amadou
a5122ac96e
Update aniworld.js 2025-01-12 23:16:37 +01:00
Moustapha Kodjo Amadou
1b84c01390
Merge pull request #133 from NBA2K1/main
Update AniWorld & SerienStream
2025-01-12 23:15:32 +01:00
Moustapha Kodjo Amadou
01835f3958
Update sudatchi.js 2025-01-12 23:15:07 +01:00
Moustapha Kodjo Amadou
48dbe1386a
Update sudatchi.js 2025-01-12 23:13:43 +01:00
github-actions[bot]
9ac4a08379 Update extensions 2025-01-12 22:12:43 +00:00
Moustapha Kodjo Amadou
24605be091
Merge pull request #132 from Swakshan/extension/sudatchi
New source: Sudatchi
2025-01-12 23:12:26 +01:00
Enbiya Olgun
7ead8db4d8 Update AniWorld & SerienStream
Fix formatting issue in description
2025-01-12 22:45:27 +01:00
github-actions[bot]
80130a357f Update extensions 2025-01-12 12:15:18 +00:00
Moustapha Kodjo Amadou
16bb2126f1 - 2025-01-12 13:14:47 +01:00
github-actions[bot]
979e998f55 Update extensions 2025-01-12 12:07:11 +00:00
Moustapha Kodjo Amadou
92f716c547
Merge pull request #131 from Schnitzel5/feature/novel-download
adjusted novel sources
2025-01-12 13:06:54 +01:00
Swakshan
21c0e197d1 extension(sudatchi): bug fixes 2025-01-12 15:36:24 +05:30
Swakshan
c2ebf8cce6 extension(sudatchi): reverse chapters 2025-01-12 15:29:36 +05:30
Swakshan
263fc76e3e extension(sudatchi): Added streams 2025-01-12 15:24:18 +05:30
Swakshan
d2752504e5 extension(sudatchi): Added details 2025-01-12 15:24:18 +05:30
Swakshan
9ef890773e extension(sudatchi): Added search and filters 2025-01-12 15:24:18 +05:30
Swakshan
36451c230c extension(sudatchi): Added popular & latest 2025-01-12 15:24:18 +05:30
github-actions[bot]
3e3cdb94c4 Update extensions 2025-01-09 13:44:46 +00:00
kodjomoustapha
4bc64789c5 Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2025-01-09 14:44:26 +01:00
kodjomoustapha
59ce118eec fix 2025-01-09 14:44:22 +01:00
github-actions[bot]
09e79f6e59 Update extensions 2025-01-09 13:44:02 +00:00
kodjomoustapha
40e83490c7 fix 2025-01-09 14:42:49 +01:00
github-actions[bot]
4afd9461ad Update extensions 2025-01-09 13:40:44 +00:00
kodjomoustapha
3c667e59f5 fix 2025-01-09 14:40:22 +01:00
kodjomoustapha
d972abbe87 rewrite Comick source code in JS 2025-01-09 14:34:13 +01:00
Schnitzel5
eebb7d72ed adjusted novel sources 2025-01-08 13:19:23 +00:00
github-actions[bot]
2ca9be2319 Update extensions 2025-01-08 09:57:29 +00:00
kodjomoustapha
decd0b9759 Revert "Merge pull request #130 from Schnitzel5/feature/novel-download"
This reverts commit 7eedf0449c, reversing
changes made to a9a6aed1bb.
2025-01-08 10:57:07 +01:00
github-actions[bot]
c62e132126 Update extensions 2025-01-08 09:55:26 +00:00
Moustapha Kodjo Amadou
7eedf0449c
Merge pull request #130 from Schnitzel5/feature/novel-download
adjusted novel sources
2025-01-08 10:55:08 +01:00
Schnitzel5
11b9223b88 adjusted novel sources 2025-01-07 23:38:20 +01:00
Schnitzel5
fd4ffedef3 Merge branch 'main' into feature/wuxiaclick 2025-01-07 19:45:54 +01:00
Schnitzel5
9e370b16aa + 2025-01-07 15:55:02 +01:00
Schnitzel5
8bde27c857 + 2025-01-07 00:32:42 +01:00
github-actions[bot]
a9a6aed1bb Update extensions 2025-01-06 18:27:47 +00:00
Moustapha Kodjo Amadou
71c81f448a
Merge pull request #128 from Schnitzel5/feature/wordrain
added Wordrain69
2025-01-06 19:27:27 +01:00
github-actions[bot]
333d7aef69 Update extensions 2025-01-06 18:27:03 +00:00
kodjomoustapha
55d4f1745f fix 2025-01-06 19:24:31 +01:00
Schnitzel5
8671db9ef3 added Wordrain69 2025-01-06 18:30:31 +01:00
github-actions[bot]
e76efcbd7c Update extensions 2025-01-06 14:47:32 +00:00
Moustapha Kodjo Amadou
37c3b1b179
Merge pull request #121 from Schnitzel5/feature/light-novel
add novel support
2025-01-06 15:47:14 +01:00
Moustapha Kodjo Amadou
ea22b7f4cd
Merge branch 'main' into feature/light-novel 2025-01-06 15:41:28 +01:00
kodjomoustapha
34c818a2cd + 2025-01-06 15:36:05 +01:00
github-actions[bot]
e6d839506f Update extensions 2025-01-06 13:10:08 +00:00
kodjomoustapha
94f64a2e79 + 2025-01-06 14:09:38 +01:00
github-actions[bot]
ce8be66d86 Update extensions 2025-01-06 12:27:00 +00:00
kodjomoustapha
81517a2bcd fix megacloud 2025-01-06 13:26:36 +01:00
github-actions[bot]
85881230e3 Update extensions 2025-01-06 12:22:28 +00:00
Moustapha Kodjo Amadou
4cc8f54fa4
fix netflixmirror 2025-01-06 13:22:11 +01:00
github-actions[bot]
6d971cb4fb Update extensions 2025-01-05 18:20:00 +00:00
Moustapha Kodjo Amadou
9cf14d0d46
Merge pull request #125 from Swakshan/extension/autoembed
Added new stream sources for Autoembed
2025-01-05 19:19:41 +01:00
Swakshan
f54f71d3ff extension(autembed): Added vidapi server 2025-01-03 18:30:48 +05:30
Swakshan
e59d703484 extension(autembed): Added flicky server 2025-01-03 15:24:12 +05:30
Swakshan
d8f5cb3975 extension(autoembed): Added autoembed - Indian languages server 2025-01-03 13:12:47 +05:30
Swakshan
86d4b73257 extension(autoembed): Misc 2025-01-03 13:10:02 +05:30
Schnitzel5
8046a81d16 added another domain 2025-01-02 22:13:40 +01:00
Swakshan
64635de462 extension(autoembed): Added mulitple stream source 2025-01-03 00:23:51 +05:30
github-actions[bot]
73c6509c4e Update extensions 2024-12-27 08:42:11 +00:00
kodjomoustapha
e936b60623 fix 2024-12-27 09:41:48 +01:00
github-actions[bot]
ff2a7fa557 Update extensions 2024-12-27 08:29:55 +00:00
kodjomoustapha
8eb3ccb793 fix 2024-12-27 09:29:33 +01:00
github-actions[bot]
3906233019 Update extensions 2024-12-27 08:10:44 +00:00
Moustapha Kodjo Amadou
96f40a2e9c
Merge pull request #124 from Swakshan/main
New Source: Mangapill
2024-12-27 09:10:28 +01:00
Swakshan
6bba7e0d4b extension(mangapill): release 2024-12-25 16:13:00 +05:30
Swakshan
1664c238ff extension(mangapill): Added get pages 2024-12-25 16:11:47 +05:30
Swakshan
aa0a0563d6 extension(mangapill): Added search filters 2024-12-25 15:50:26 +05:30
Swakshan
76e17aed9d extension(mangapill): Added manga title pref 2024-12-24 19:53:57 +05:30
Swakshan
e18af3aa79 extension(mangapill): Added manga details 2024-12-24 19:29:18 +05:30
Swakshan
26bb82df8a extension(mangapill): Added search 2024-12-24 13:35:13 +05:30
Swakshan
c970fb211e extension(mangapill): Added popular and latest section 2024-12-24 13:18:02 +05:30
github-actions[bot]
fb5640ec3b Update extensions 2024-12-23 05:22:56 +00:00
Moustapha Kodjo Amadou
bfdebcfa5e
Merge pull request #123 from Swakshan/extension/autoembed
extension(Autoembed): Updates
2024-12-23 06:22:38 +01:00
Swakshan
d731680b1d extension(Autoembed): optimisation 2024-12-22 21:14:05 +05:30
Swakshan
e523e14ca3 extension(Autoembed): Modified content link 2024-12-22 20:27:04 +05:30
Swakshan
8084885244 extension(Autoembed): Added list priority 2024-12-22 20:01:53 +05:30
Schnitzel5
7695344aee updated workflow 2024-12-21 21:20:10 +01:00
Schnitzel5
b69c5dfa5f fix 2024-12-21 21:16:05 +01:00
Schnitzel5
cbdb59f795 removed temp redirect 2024-12-21 20:19:08 +01:00
Schnitzel5
2b764e40ef Merge branch 'feature/novel' into feature/light-novel 2024-12-21 20:16:42 +01:00
Schnitzel5
8b68030674 added filters 2024-12-21 20:11:21 +01:00
github-actions[bot]
2d6b41c90e Update extensions 2024-12-21 15:41:29 +00:00
Moustapha Kodjo Amadou
f44ce1b6f9
reverse episodes 2024-12-21 16:41:11 +01:00
github-actions[bot]
9a626c5d9f Update extensions 2024-12-21 15:05:47 +00:00
Moustapha Kodjo Amadou
d7bce6a7fc
Merge pull request #120 from Swakshan/main
New Source: Autoembed (All)
2024-12-21 16:05:30 +01:00
Moustapha Kodjo Amadou
2403ce71c2
Update autoembed.js 2024-12-21 16:03:26 +01:00
Swakshan
68e5849bc9 Merge branch 'extension/autoembed' 2024-12-20 23:48:12 +05:30
Swakshan
3e6b0a4f16 extension(Autoembed): misc 2024-12-20 23:42:26 +05:30
Swakshan
7dd7b2e8ab extension(Autoembed): Added search 2024-12-20 23:07:54 +05:30
Swakshan
8395d2df9e extension(Autoembed): Added stream resolution preference 2024-12-20 22:59:49 +05:30
Swakshan
7584c28bb5 extension(Autoembed): Added latest page 2024-12-20 22:16:17 +05:30
Swakshan
0ff2f005be extension(Autoembed): Updated logic 2024-12-20 21:56:08 +05:30
github-actions[bot]
ebba6a94a5 Update extensions 2024-12-20 14:17:19 +00:00
kodjomoustapha
fb18ee975f fix Asura Scans 2024-12-20 15:16:49 +01:00
Swakshan
10c9d4b15e extension(Autoembed): Added series support 2024-12-20 17:22:18 +05:30
kodjomoustapha
7bf707d8bc fix iconUrl 2024-12-20 11:17:25 +01:00
Swakshan
2a829ea3fd extension(Autoembed): Added movies support 2024-12-20 13:10:29 +05:30
Schnitzel5
5bd1347feb added extension function 2024-12-20 00:23:42 +01:00
github-actions[bot]
3df56430c1 Update extensions 2024-12-19 11:13:35 +00:00
Moustapha Kodjo Amadou
dee597d41d
Update webtoons.js 2024-12-19 12:13:15 +01:00
github-actions[bot]
c74156e01a Update extensions 2024-12-19 11:13:01 +00:00
Moustapha Kodjo Amadou
6232ed7aed
Update webtoons.js 2024-12-19 12:12:44 +01:00
github-actions[bot]
b021c84478 Update extensions 2024-12-19 11:02:34 +00:00
Moustapha Kodjo Amadou
9f1f00dd18
fix 2024-12-19 12:02:15 +01:00
github-actions[bot]
567b59f67c Update extensions 2024-12-19 10:46:22 +00:00
Moustapha Kodjo Amadou
b05a2bfb4e
Update webtoons.js 2024-12-19 11:46:07 +01:00
Moustapha Kodjo Amadou
85a3996ff6
fix 2024-12-19 11:45:53 +01:00
github-actions[bot]
a37074b6dd Update extensions 2024-12-19 10:35:53 +00:00
Moustapha Kodjo Amadou
e3812c168f
Merge pull request #118 from uwu-wuw/main
Create webtoons.js
2024-12-19 11:35:31 +01:00
Moustapha Kodjo Amadou
21dba5bf72
add more langs 2024-12-19 11:34:31 +01:00
uwu-wuw
20d6ba6c19
Create webtoons.js 2024-12-18 00:19:46 +06:00
github-actions[bot]
e159fe9b16 Update extensions 2024-12-15 18:09:54 +00:00
Moustapha Kodjo Amadou
65a07d6796
Merge pull request #116 from NBA2K1/main
dateUpload for AniWorld & SerienStream
2024-12-15 19:09:37 +01:00
NBA2K1
bab407b3e3 Version++ 2024-12-15 19:07:54 +01:00
NBA2K1
423e1da501 Corrected dateupload. 2024-12-15 18:51:08 +01:00
NBA2K1
44c8514b4e Revert "AnimeToast partial rewrite in js"
This reverts commit abd7e06eea.
2024-12-13 03:01:41 +01:00
NBA2K1
37e3b206a1 dateUpload for AniWorld & SerienStream
- dateUpload
- + improved performance using Promise.all instead of sequentially with the for loops.
2024-12-13 02:57:21 +01:00
NBA2K1
a5a48a8760
Merge branch 'kodjodevf:main' into main 2024-12-13 00:51:25 +01:00
Schnitzel5
36c1fbbe94 fix NovelUpdates 2024-12-09 23:39:43 +01:00
github-actions[bot]
5c85c33dae Update extensions 2024-12-09 13:06:57 +00:00
kodjomoustapha
bf58a599ec Torrentio: do not show upcoming episodes 2024-12-09 14:06:39 +01:00
github-actions[bot]
54bfec70e1 Update extensions 2024-12-09 11:21:40 +00:00
kodjomoustapha
2392a10c5f AnimePahe: add cookie to headers 2024-12-09 12:21:14 +01:00
Schnitzel5
62741a79f2 fix NovelUpdates 2024-12-08 22:53:12 +01:00
NBA2K1
abd7e06eea AnimeToast partial rewrite in js 2024-12-08 18:47:42 +01:00
github-actions[bot]
c8d5613288 Update extensions 2024-12-07 15:59:27 +00:00
kodjomoustapha
8f121c136e Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-12-07 16:59:02 +01:00
kodjomoustapha
95945137da Torrentio: use all providers by default 2024-12-07 16:58:57 +01:00
github-actions[bot]
0a81a9ab82 Update extensions 2024-12-06 11:11:32 +00:00
kodjomoustapha
e89de932e3 fix Torrentio 2024-12-06 12:11:08 +01:00
github-actions[bot]
915d339351 Update extensions 2024-12-03 11:15:45 +00:00
kodjomoustapha
8b70217248 fix 2024-12-03 12:15:15 +01:00
github-actions[bot]
36d6304837 Update extensions 2024-12-03 10:52:27 +00:00
kodjomoustapha
2e14f3ad8e fix NetflixMirror getCookie 2024-12-03 11:51:50 +01:00
github-actions[bot]
966cea943b Update extensions 2024-12-03 08:05:22 +00:00
Moustapha Kodjo Amadou
468c9757e4
Merge pull request #113 from NBA2K1/main
Update serienstream.js
2024-12-03 09:05:04 +01:00
NBA2K1
ca0cd15152 Revert "Show actual anime covers"
This reverts commit 3d4284baad.
2024-12-02 22:50:58 +01:00
NBA2K1
e6d1dbe356 Update serienstream.js
copied changes from aniworld extension.
2024-12-02 22:47:23 +01:00
NBA2K1
3d4284baad Show actual anime covers
Not ready. Very slow.
2024-12-02 22:26:43 +01:00
github-actions[bot]
a3a4479922 Update extensions 2024-12-02 17:02:33 +00:00
kodjomoustapha
6514cdd36e Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-12-02 18:02:10 +01:00
kodjomoustapha
67c14d0f95 + 2024-12-02 18:02:07 +01:00
github-actions[bot]
ebcd1065b2 Update extensions 2024-12-02 17:01:49 +00:00
kodjomoustapha
f3f8aef7d0 Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-12-02 18:01:29 +01:00
kodjomoustapha
66969de042 + 2024-12-02 18:01:26 +01:00
github-actions[bot]
683effe550 Update extensions 2024-12-02 17:00:04 +00:00
kodjomoustapha
e5cfb41c40 + 2024-12-02 17:59:38 +01:00
kodjomoustapha
a7faa05038 New sources : Torrentio (Torrent) and Torrentio Anime (Torrent) 2024-12-02 17:59:22 +01:00
Schnitzel5
076005c715 temp redirect 2024-12-01 19:33:47 +01:00
Schnitzel5
90c8ce01cb testing novel source 2024-12-01 19:11:59 +01:00
github-actions[bot]
f6386c5da8 Update extensions 2024-12-01 12:44:00 +00:00
Moustapha Kodjo Amadou
49363694a4
Merge pull request #111 from Ftbom/main
remove invalid chinese sources and fix some broken ones
2024-12-01 13:43:42 +01:00
github-actions[bot]
8a5ecf0a85 Update extensions 2024-12-01 12:42:40 +00:00
Moustapha Kodjo Amadou
9c5127f54e
Merge pull request #110 from RndDev123/manga-extensions
Mangalib: Fix lang
2024-12-01 13:42:23 +01:00
ftbom
fd97370fcc remove invalid sources and fix some broken ones 2024-12-01 20:19:34 +08:00
RndDev123
37222cbb84 Mangalib: Fix lang 2024-12-01 05:17:01 +01:00
Schnitzel5
07545f8843 fix 2024-12-01 00:52:42 +01:00
Moustapha Kodjo Amadou
9c4260cef2
Merge pull request #109 from RndDev123/manga-extensions
New Source: Mangalib (RU)
2024-11-30 20:50:49 +01:00
RndDev123
5e6f35dd22 Mangalib: Change default image server 2024-11-30 15:34:06 +01:00
RndDev123
9942e332a7 Mangalib: Fix status 2024-11-30 15:25:56 +01:00
github-actions[bot]
2c2c04a897 Update extensions 2024-11-30 14:20:57 +00:00
Moustapha Kodjo Amadou
c1d2b9f38c
Merge pull request #107 from RndDev123/main
Aniworld: New Host & Language preference filters + lib update
2024-11-30 15:20:40 +01:00
RndDev123
a51943bac4 New Source: Mangalib (RU) 2024-11-30 15:16:06 +01:00
RndDev123
1b496ac313 Another Filemoon fix 2024-11-30 05:53:01 +01:00
RndDev123
e0901a7154 Update aniworld.js 2024-11-29 09:58:02 +01:00
RndDev123
3c5696e6a5 Filemoon init headers 2024-11-29 09:14:12 +01:00
RndDev123
6bf8fa6018 + 2024-11-29 08:59:30 +01:00
RndDev123
86922fff77 Fix Filemoon extractor on Android 2024-11-29 08:54:17 +01:00
RndDev123
8784a20560 Merge remote-tracking branch 'upstream/main' 2024-11-29 04:10:11 +01:00
RndDev123
9b9150366f Aniworld: New Host & Language preference filters + lib update
Aniworld:
- New Host: Luluvdo
- Language preference filters

Lib:
- New Host: Luluvdo
2024-11-29 04:09:52 +01:00
Schnitzel5
9f614fe664 added novel template 2024-11-28 15:47:22 +01:00
github-actions[bot]
2428842da3 Update extensions 2024-11-28 10:54:23 +00:00
Moustapha Kodjo Amadou
6f9727883f
Merge pull request #106 from RndDev123/main
New Source: MangaWorld (IT) + Fixes
2024-11-28 11:39:42 +01:00
RndDev123
2940e029cd New Source: MangaWorld (IT) + Fixes
New Source:
- Manga World

JKAnime, TioAnime, ,AnimeFenix and AnimeWorld:
- Add await before this.parseAnimeList for readability
2024-11-28 07:04:26 +01:00
github-actions[bot]
6161949090 Update extensions 2024-11-27 14:42:18 +00:00
Moustapha Kodjo Amadou
d5e911ad26
Merge pull request #105 from RndDev123/main
New Source: AnimeWorld & Shortened filter code
2024-11-27 15:42:00 +01:00
Schnitzel5
ac1a8f19cc Merge branch 'migrate/light-novel' 2024-11-27 15:16:28 +01:00
Schnitzel5
1e01f73fb4 fixed error 2024-11-27 15:11:25 +01:00
RndDev123
2c97ce81cb + 2024-11-27 13:49:54 +01:00
RndDev123
c0edb5c0c5 New Source: AnimeWorld & Updates: Shortened filter code
New Source:
- Anime World

AnimeFenix, JKAnime and Mangafire:
- Shortened filter code
2024-11-27 13:26:11 +01:00
github-actions[bot]
b9224f725a Update extensions 2024-11-26 17:07:56 +00:00
kodjomoustapha
baa8ddd6a5 fix 2024-11-26 18:07:12 +01:00
github-actions[bot]
c83d3a7472 Update extensions 2024-11-26 16:09:43 +00:00
kodjomoustapha
8da19368c7 fix 2024-11-26 17:09:20 +01:00
github-actions[bot]
f423f60380 Update extensions 2024-11-26 16:06:25 +00:00
kodjomoustapha
6f47acd819 fix datalifeengine 2024-11-26 17:05:30 +01:00
github-actions[bot]
8149b4c0b1 Update extensions 2024-11-26 13:12:02 +00:00
Moustapha Kodjo Amadou
2d1def7ac9
Merge pull request #104 from RndDev123/main
AniWorld, AnimeFenix, JKAnime and TioAnime: New host, fixes and helper lib update
2024-11-26 14:11:43 +01:00
RndDev123
1141e53c0b JKAnime: Change Logo 2024-11-26 10:32:43 +01:00
RndDev123
fd074790e8 AniWorld, AnimeFenix, JKAnime and TioAnime: New host, fixes and helper lib update
AniWorld
- New Host: Speedfiles
- New Host: Filemoon
- Better Sorting for preferences

AnimeFenix:
- Added possible status string

JKAnime
- Get Studios

TioAnime
- Fix hasNextPage

Helper library
- Add new host: Speedfiles
- Add new String function: reverse, swapcase
2024-11-26 08:05:50 +01:00
Schnitzel5
c19638eb6d fix 2024-11-25 23:06:37 +01:00
Schnitzel5
433ab9ceea fix 2024-11-25 23:03:39 +01:00
Schnitzel5
a6eaf30579 add novel support 2024-11-25 23:00:07 +01:00
Schnitzel5
0c7eccf180 Merge branch 'main' of github.com:Schnitzel5/mangayomi-extensions 2024-11-25 22:57:08 +01:00
Schnitzel5
c635cffdf2 add novel support 2024-11-25 22:55:23 +01:00
Schnitzel5
7414887be2 add novel support 2024-11-25 22:51:11 +01:00
github-actions[bot]
749861af61 Update extensions 2024-11-23 17:49:43 +00:00
Moustapha Kodjo Amadou
8c6cd36d9c
Merge pull request #101 from NBA2K1/main
Update serienstream.js
2024-11-23 18:49:22 +01:00
NBA2K1
20668f2829 Update serienstream.js
Serienstream:
- copied the changes from Aniworld

Aniworld:
- shortened getSourcePreferences() and made it more readable/maintainable
- used array in getRandomString() for better readability
2024-11-23 18:26:07 +01:00
github-actions[bot]
c7d2cae26b Update extensions 2024-11-23 14:56:03 +00:00
Moustapha Kodjo Amadou
9f97699b53
Merge pull request #99 from NBA2K1/main
New Source (SerienStream), Aniworld apostrophe rendering fix and improve performance
2024-11-23 15:54:49 +01:00
Moustapha Kodjo Amadou
7778873a09
Update aniworld.js 2024-11-23 15:54:27 +01:00
Moustapha Kodjo Amadou
92529e06a9
Update serienstream.js 2024-11-23 15:54:04 +01:00
Moustapha Kodjo Amadou
e2d52be133
Merge branch 'main' into main 2024-11-23 15:52:22 +01:00
github-actions[bot]
4e6ac0bdb4 Update extensions 2024-11-23 14:35:05 +00:00
Moustapha Kodjo Amadou
ed39ba33f7
Merge pull request #100 from RndDev123/main
Add TioAnime, AnimeFenix and JKAnime + Updates to Mangafire and Aniworld
2024-11-23 15:34:48 +01:00
RndDev123
52c55a8d85 Add TioAnime, AnimeFenix and JKAnime + Updates to Mangafire and Aniworld
- New Source: TioAnime source (es)
- New Source: AnimeFenix source (es)
- New Source: JKAnime source (es)
- Aniworld: Async loading for getVideoList and getDetail.
- Aniworld: Changed headers in getVideoList which helps load times.
- Mangafire: changed a query name
- Mangafire: search sometimes failed because filters were empty. I got this on android. And some other user also stated having problems with search.
- Implemented new videoExtractors and helper functions in a "library", used in all three new extensions
2024-11-23 09:47:54 +01:00
NBA2K1
8522088783
filename in lowercase now 2024-11-22 16:42:50 +01:00
NBA2K1
8541a92f83 New Anime Source
This is practically the same as aniworld, but also includes other shows, not just Anime.
2024-11-22 16:39:33 +01:00
NBA2K1
c163b9fed4 Fix apostrophe rendering and improve performance
Fixed apostrophe rendering in episode names (e.g., for "DAN DA DAN")
by replacing HTML character references (&#039;) with actual apostrophes.

Optimized performance by reusing a single Client instance, passing it to
parseEpisodesFromSeries() instead of creating a new instance in each loop.

Parallelized episode fetching in getDetail() using Promise.all to
improve request efficiency, replacing the sequential loop.
2024-11-22 16:20:07 +01:00
github-actions[bot]
afd8d6ba31 Update extensions 2024-11-21 09:35:19 +00:00
kodjomoustapha
cf661ba909 fix 2024-11-21 10:34:55 +01:00
github-actions[bot]
7d1fd73dc4 Update extensions 2024-11-21 09:23:05 +00:00
kodjomoustapha
f4bf7c24b0 fix 2024-11-21 09:57:57 +01:00
github-actions[bot]
caf6f36eef Update extensions 2024-11-19 17:27:58 +00:00
kodjomoustapha
5075d6b75a + 2024-11-19 18:27:35 +01:00
github-actions[bot]
c5e181a82b Update extensions 2024-11-19 17:22:42 +00:00
kodjomoustapha
5eb0fbd513 add override Base Url preference 2024-11-19 18:22:22 +01:00
github-actions[bot]
16122da36d Update extensions 2024-11-19 17:12:32 +00:00
kodjomoustapha
5ee227b6de fix Asura Scans 2024-11-19 18:11:27 +01:00
github-actions[bot]
dc979b30d9 Update extensions 2024-11-15 13:41:01 +00:00
kodjomoustapha
d173331829 fix NetflixMirror 2024-11-15 14:40:41 +01:00
github-actions[bot]
53bf4ac3b3 Update extensions 2024-11-14 14:50:21 +00:00
kodjomoustapha
a4d2b620a3 - 2024-11-14 15:49:59 +01:00
github-actions[bot]
a5a85aee35 Update extensions 2024-11-06 15:10:01 +00:00
kodjomoustapha
828b9b89b0 fix NetflixMirror 2024-11-06 16:09:35 +01:00
github-actions[bot]
12287770b0 Update extensions 2024-11-06 05:15:08 +00:00
Moustapha Kodjo Amadou
88dc90f2d7
Merge pull request #97 from RndDev123/main
AniWorld - Doodstream & Vidoza Fix
2024-11-06 06:14:50 +01:00
RndDev123
5a539c5d0b Increment AniWorld Version 2024-11-06 01:36:45 +01:00
RndDev123
cfd05732c6 AniWorld - Doodstream & Vidoza Fix
- Implemented a vidoza extractor
- Implemented a temporary doodstream extractor until the one in the application is fixed.
- Changed quality from `${hoster} ${language}` to `${language} - ${hoster}` for better sorting and readability
2024-11-06 01:17:44 +01:00
github-actions[bot]
e9865029b4 Update extensions 2024-11-05 16:32:20 +00:00
kodjomoustapha
a97e16a072 + 2024-11-05 17:31:52 +01:00
kodjomoustapha
f5eb6611dc fix chapter date 2024-11-05 17:27:09 +01:00
github-actions[bot]
a82dcee6b2 Update extensions 2024-11-05 10:17:40 +00:00
kodjomoustapha
e6f460d86d fix 2024-11-05 11:16:35 +01:00
github-actions[bot]
ae46720fbf Update extensions 2024-11-05 10:09:55 +00:00
kodjomoustapha
7d18d6c1eb fix AniWorld video extractors 2024-11-05 11:09:20 +01:00
github-actions[bot]
81031978a0 Update extensions 2024-11-05 09:10:17 +00:00
kodjomoustapha
4388fb03ff fix 2024-11-05 10:09:52 +01:00
kodjomoustapha
1b61f97fae - 2024-11-05 10:04:55 +01:00
github-actions[bot]
c1e1da1bf8 Update extensions 2024-11-05 09:00:54 +00:00
kodjomoustapha
c88780ccfb fix langs 2024-11-05 10:00:32 +01:00
kodjomoustapha
eb9bb3b8f2 fix generate multiple langage for JS source 2024-11-05 10:00:02 +01:00
Moustapha Kodjo Amadou
d54e6a5794
Merge pull request #96 from RndDev123/main
Add MangaFire with Filters
2024-11-05 09:16:10 +01:00
RndDev123
099e52f5b2 Add MangaFire 2024-11-05 02:12:42 +01:00
github-actions[bot]
d7e8142433 Update extensions 2024-10-25 20:03:24 +00:00
Moustapha Kodjo Amadou
1e935c6082
Merge pull request #93 from hollow-frenk/main
Update source.dart
2024-10-25 21:03:06 +01:00
Moustapha Kodjo Amadou
f862f29c26
Update source.dart 2024-10-25 21:02:05 +01:00
Francesco De Feo
f775ee2118
Update source.dart 2024-10-25 20:53:06 +02:00
github-actions[bot]
806b1fed32 Update extensions 2024-10-24 08:29:28 +00:00
kodjomoustapha
e80a70f2b0 fix 2024-10-24 09:29:07 +01:00
github-actions[bot]
63797dcfcd Update extensions 2024-10-15 08:14:13 +00:00
Moustapha Kodjo Amadou
62913d55f1
Merge pull request #92 from yxxyun/dev
update UC tip
2024-10-15 09:13:56 +01:00
github-actions[bot]
0c6dc2b586 Update extensions 2024-10-15 08:12:01 +00:00
kodjomoustapha
528ba54c6f fix 2024-10-15 09:11:39 +01:00
yxxyun
c8ca805ecb
Update yydsys.js 2024-10-14 21:46:39 +08:00
yxxyun
d2ecb573b7
Update wogg.js 2024-10-14 21:45:38 +08:00
github-actions[bot]
d914a25cce Update extensions 2024-10-13 17:46:19 +00:00
kodjomoustapha
576a2e5b1e fix 2024-10-13 18:45:56 +01:00
github-actions[bot]
8b7039b5e3 Update extensions 2024-10-13 17:40:47 +00:00
kodjomoustapha
60f1e30475 Update netflixmirror.js 2024-10-13 18:40:12 +01:00
kodjomoustapha
c877345aac Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-10-13 18:36:06 +01:00
kodjomoustapha
86919cdff2 fix 2024-10-13 18:36:03 +01:00
github-actions[bot]
9eea568829 Update extensions 2024-10-13 17:33:21 +00:00
kodjomoustapha
c03aa7986e New source: NetflixMirror (ALL) 2024-10-13 18:32:23 +01:00
github-actions[bot]
2e830863ff Update extensions 2024-10-10 11:27:59 +00:00
kodjomoustapha
9957b9b213 fix & add new extractors 2024-10-10 12:26:58 +01:00
github-actions[bot]
eb222dedb8 Update extensions 2024-10-09 08:52:59 +00:00
kodjomoustapha
d551f71bf9 add extractor prefix name 2024-10-09 09:52:39 +01:00
github-actions[bot]
7c345c3279 Update extensions 2024-10-09 08:35:15 +00:00
kodjomoustapha
1dc88b7d7a fix AllAnime 2024-10-09 09:34:24 +01:00
github-actions[bot]
cfc7da44dd Update extensions 2024-10-07 16:07:57 +00:00
Moustapha Kodjo Amadou
ab6b766459
Merge pull request #89 from yxxyun/dev
add 多多影音
2024-10-07 17:07:39 +01:00
Moustapha Kodjo Amadou
8ea195e5f1
Merge pull request #88 from yxxyun/quark
add wogg, support play video from quark and uc clouddrive.
2024-10-07 17:07:25 +01:00
yxxyun
b1f2dc23aa add tip for user to fill in the cookie 2024-10-06 21:13:26 +08:00
yxxyun
d7d9c859cf add tip for user to fill in the cookie 2024-10-06 21:09:38 +08:00
yxxyun
9b8ba7b7f1 add 多多影音 2024-10-05 23:47:06 +08:00
yxxyun
1302f70b66 add UC support 2024-10-05 21:14:53 +08:00
yxxyun
96203e8a93 fix 2024-10-02 21:00:58 +08:00
yxxyun
924976161c add wogg, only support quark now. 2024-10-02 16:25:36 +08:00
github-actions[bot]
d87042a0a0 Update extensions 2024-09-30 16:42:43 +00:00
kodjomoustapha
820e089c59 fix AnZone episodes list 2024-09-30 17:42:07 +01:00
github-actions[bot]
4ec2bdbb50 Update extensions 2024-09-30 15:46:17 +00:00
kodjomoustapha
806482c5a3 fix 2024-09-30 16:45:42 +01:00
github-actions[bot]
906ad5f57e Update extensions 2024-09-30 15:33:35 +00:00
kodjomoustapha
43fcb00405 New source: AnimeOnlineNinja (es) 2024-09-30 16:33:13 +01:00
github-actions[bot]
4f009be6a4 Update extensions 2024-09-26 08:29:40 +00:00
kodjomoustapha
b2ee317592 + 2024-09-26 09:29:10 +01:00
github-actions[bot]
af4b241523 Update extensions 2024-09-26 08:26:30 +00:00
kodjomoustapha
db029c0806 + 2024-09-26 09:26:08 +01:00
kodjomoustapha
6e08887d1f - 2024-09-26 09:25:52 +01:00
kodjomoustapha
17bd4a761a - 2024-09-26 09:25:17 +01:00
Moustapha Kodjo Amadou
258eed505b
Merge pull request #86 from Needey/main
Add AniZone Source (Anisama)
2024-09-26 09:20:40 +01:00
kodjomoustapha
722dcdea3d fix 2024-09-26 09:18:49 +01:00
Moustapha Kodjo Amadou
36c270edd8
Merge pull request #85 from Schnitzel5/fix/mangadex
Fix/mangadex
2024-09-26 09:10:11 +01:00
Needye
057cf25dd8 Add AniZone Source 2024-09-26 01:37:05 +02:00
Schnitzel5
b361b887c2 covers 2024-09-25 18:16:40 +02:00
Schnitzel5
a59b478d2d add imageUrl for getDetail 2024-09-25 17:03:29 +02:00
github-actions[bot]
46a8ba3266 Update extensions 2024-09-21 23:58:48 +00:00
kodjomoustapha
c7c2863f9e + 2024-09-22 00:51:13 +01:00
kodjomoustapha
b2d331834a - 2024-09-22 00:45:32 +01:00
github-actions[bot]
e5802aaac3 Update extensions 2024-09-21 23:21:25 +00:00
kodjomoustapha
bc95f1b8fd - 2024-09-22 00:21:04 +01:00
github-actions[bot]
13c5b002d0 Update extensions 2024-09-21 22:00:28 +00:00
kodjomoustapha
24825d0d9c remove some NSFW sources 2024-09-21 23:00:04 +01:00
github-actions[bot]
235dc9ca6f Update extensions 2024-09-19 21:59:46 +00:00
Moustapha Kodjo Amadou
6a3d306911
Merge pull request #84 from yxxyun/yxxyun-vod
add some vod collection site
2024-09-19 22:59:27 +01:00
yxxyun
5a921411e7
add some vod collection site 2024-09-19 20:46:18 +08:00
github-actions[bot]
c37049b75c Update extensions 2024-09-18 13:28:14 +00:00
Moustapha Kodjo Amadou
810d083cc0
Merge pull request #83 from yxxyun/360zy
add 360资源站
2024-09-18 14:27:54 +01:00
Moustapha Kodjo Amadou
f55b797ff5
Add pkgPath 2024-09-18 14:25:39 +01:00
yxxyun
19b9a298bc
add 360资源站 2024-09-18 21:01:17 +08:00
github-actions[bot]
97bcc51d92 Update extensions 2024-09-18 12:12:36 +00:00
kodjomoustapha
8b1504296b fix 2024-09-18 13:11:16 +01:00
github-actions[bot]
d0a4a40da9 Update extensions 2024-09-11 16:40:15 +00:00
kodjomoustapha
e452ef9fa1 fix 2024-09-11 17:37:57 +01:00
github-actions[bot]
d5713877d1 Update extensions 2024-09-04 12:15:08 +00:00
kodjomoustapha
9d9ce1c6a4 remove Aniwave 2024-09-04 13:14:25 +01:00
github-actions[bot]
3f779fb496 Update extensions 2024-08-30 11:47:57 +00:00
kodjomoustapha
efa6ebf066 Update 2024-08-30 12:47:23 +01:00
github-actions[bot]
99c896ce8a Update extensions 2024-08-22 17:53:11 +00:00
kodjomoustapha
9616e0a5b0 Aniwave: fix encryption 2024-08-22 18:52:43 +01:00
github-actions[bot]
619c8694a4 Update extensions 2024-08-22 14:52:31 +00:00
kodjomoustapha
ec0ea73cb2 Update 2024-08-22 15:52:04 +01:00
Moustapha Kodjo Amadou
b23811eb60
Update vivamaxph 2024-08-22 15:49:15 +01:00
Moustapha Kodjo Amadou
c635ead19a
Merge pull request #80 from Non9X/patch-1
Create vivamaxph
2024-08-22 15:46:37 +01:00
github-actions[bot]
5bded6dd5f Update extensions 2024-08-21 17:16:57 +00:00
kodjomoustapha
dc5dbe8941 Update AnimePahe 2024-08-21 18:16:00 +01:00
github-actions[bot]
70673d5fb6 Update extensions 2024-08-20 17:11:29 +00:00
kodjomoustapha
10b68b370e Mangadex: Add use custom user agent 2024-08-20 18:10:54 +01:00
⟁:non.
4b1ebb62b4
Create vivamaxph 2024-08-18 12:32:07 +03:00
github-actions[bot]
90bc78d887 Update extensions 2024-08-18 05:31:57 +00:00
Moustapha Kodjo Amadou
268eae032d
Update sources.dart 2024-08-18 06:31:37 +01:00
Moustapha Kodjo Amadou
cec0889b51
Update madara.dart 2024-08-18 06:30:59 +01:00
github-actions[bot]
7f30b24cce Update extensions 2024-08-13 09:12:43 +00:00
kodjomoustapha
96d33aa3bf fix #77 2024-08-13 10:12:07 +01:00
kodjomoustapha
719614cf3a rm 2024-08-08 11:56:57 +01:00
github-actions[bot]
070b1fed65 Update extensions 2024-08-08 10:55:03 +00:00
kodjomoustapha
cdf4ab6f45 Update Aniwave keys & fix vidsrcExtractor 2024-08-08 11:54:08 +01:00
kodjomoustapha
cc7cac1aa5 Update CONTRIBUTING 2024-08-03 07:48:08 +01:00
github-actions[bot]
8d40365b16 Update extensions 2024-08-02 19:24:32 +00:00
Moustapha Kodjo Amadou
b1590c5cfd
Merge pull request #75 from gr8vewalker/main
Add diziWatch site
2024-08-02 20:24:13 +01:00
Moustapha Kodjo Amadou
781448d7e0
reverse episode list 2024-08-02 20:21:16 +01:00
gr8vewalker
9255328005 feat(anime) tr/diziWatch extension 2024-08-02 21:51:13 +03:00
kodjomoustapha
0bd8dc206e Update CONTRIBUTING 2024-08-02 17:48:27 +01:00
github-actions[bot]
a5c8639dbf Update extensions 2024-08-02 15:48:04 +00:00
kodjomoustapha
2d01092aa5 fix: Madara getPageList 2024-08-02 16:47:39 +01:00
github-actions[bot]
d89329155d Update extensions 2024-07-23 12:54:17 +00:00
kodjomoustapha
4c816b4d2f fix 2024-07-23 13:53:35 +01:00
github-actions[bot]
4f5c43d259 Update extensions 2024-07-23 12:33:47 +00:00
kodjomoustapha
a14cdc1b42 fix 2024-07-23 13:33:21 +01:00
github-actions[bot]
a02a184321 Update extensions 2024-07-23 11:28:15 +00:00
kodjomoustapha
2171bf0f4c Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-07-23 12:27:54 +01:00
kodjomoustapha
7be0b71393 new source AnimeFLV (ES) 2024-07-23 12:27:48 +01:00
github-actions[bot]
6d8706e0f0 Update extensions 2024-07-17 16:58:23 +00:00
kodjomoustapha
90e2605a78 fix 2024-07-17 17:57:57 +01:00
kodjomoustapha
7972cf8660 fixes 2024-07-17 17:56:08 +01:00
github-actions[bot]
d9d720cc91 Update extensions 2024-07-07 09:07:36 +00:00
kodjomoustapha
4040390767 v0.1.45 2024-07-07 10:06:54 +01:00
github-actions[bot]
21af7707e3 Update extensions 2024-07-05 10:52:26 +00:00
kodjomoustapha
5103964110 Update 2024-07-05 11:52:03 +01:00
github-actions[bot]
5ceb56b097 Update extensions 2024-06-24 16:39:49 +00:00
kodjomoustapha
0454a95617 fixes by @yutthaphon
- Remove duplicate description detection.
- Remove unused code.
- FIxed genres detection.
- Add FunToons to sources.dart
2024-06-24 17:39:23 +01:00
github-actions[bot]
42dcef9e3b Update extensions 2024-06-24 16:25:40 +00:00
kodjomoustapha
b4355830e6 fix 2024-06-24 17:25:17 +01:00
github-actions[bot]
d661cd7d51 Update extensions 2024-06-24 16:01:44 +00:00
kodjomoustapha
50bd8c65fd fix Mangabox date 2024-06-24 17:00:35 +01:00
github-actions[bot]
4720c5bfea Update extensions 2024-06-21 17:15:12 +00:00
kodjomoustapha
66970d2ccb updates 2024-06-21 18:13:20 +01:00
github-actions[bot]
6cf198e4ce Update extensions 2024-06-19 10:56:40 +00:00
kodjomoustapha
c7c002df47 v0.1.25 2024-06-19 11:56:09 +01:00
github-actions[bot]
912d7d18a5 Update extensions 2024-06-18 19:17:29 +00:00
kodjomoustapha
e501914fb6 Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-06-18 20:17:03 +01:00
kodjomoustapha
e36f6955ca + 2024-06-18 20:16:57 +01:00
github-actions[bot]
749164ceb6 Update extensions 2024-06-18 19:12:57 +00:00
kodjomoustapha
afb2db57ec Refactor mangareader 2024-06-18 20:12:05 +01:00
Moustapha Kodjo Amadou
b454d7c644
Merge pull request #72 from yutthaphon/main
Add FunToons site
2024-06-18 19:56:48 +01:00
github-actions[bot]
3be880e7bf Update extensions 2024-06-18 14:18:54 +00:00
kodjomoustapha
f8cf21d64a Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-06-18 15:18:33 +01:00
kodjomoustapha
245338a2ff fix #67 2024-06-18 15:18:26 +01:00
github-actions[bot]
0529d1cdb9 Update extensions 2024-06-18 14:03:48 +00:00
kodjomoustapha
c567a70c6b fix rapidCloudExtractor 2024-06-18 15:03:27 +01:00
Yutthaphon Inchaiya
85fb4df439 Add FunToons site
Add support for custom mangareader template
2024-06-18 12:46:43 +07:00
github-actions[bot]
0255a20e09 Update extensions 2024-05-31 16:14:23 +00:00
kodjomoustapha
4a9900237d fix: Wiflix episode name & update baseUrl 2024-05-31 17:13:11 +01:00
kodjomoustapha
c871514bde fix 2024-05-27 12:12:36 +01:00
github-actions[bot]
2df62af242 Update extensions 2024-05-27 11:05:55 +00:00
kodjomoustapha
42a9353d68 fix Mangareader 2024-05-27 12:04:57 +01:00
kodjomoustapha
c8bc5bd3ff Update CONTRIBUTING-DART 2024-05-25 19:13:17 +01:00
kodjomoustapha
2ca6b5ef2c Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-05-25 19:12:00 +01:00
kodjomoustapha
eaa434f025 Update README 2024-05-25 19:11:58 +01:00
kodjomoustapha
8a5a74725d Update CONTRIBUTING-DART 2024-05-25 19:11:23 +01:00
github-actions[bot]
daad7fcaa2 Update extensions 2024-05-25 18:10:24 +00:00
kodjomoustapha
6027e0d548 Update CONTRIBUTING-DART 2024-05-25 19:09:59 +01:00
kodjomoustapha
670f00cc86 Update CONTRIBUTING-JS 2024-05-25 18:47:24 +01:00
kodjomoustapha
82952b0e7e Update CONTRIBUTING-DART 2024-05-25 18:46:55 +01:00
kodjomoustapha
c9223b7461 Add Override BaseUrl for Mangareader 2024-05-25 18:20:31 +01:00
github-actions[bot]
b89ae8402a Update extensions 2024-05-18 16:28:14 +00:00
kodjomoustapha
6aa707c109 Update UHD Movies baseUrl 2024-05-18 17:27:47 +01:00
github-actions[bot]
9fb95e820a Update extensions 2024-05-17 21:16:19 +00:00
kodjomoustapha
c620cb095a Merge branch 'main' of https://github.com/kodjodevf/mangayomi-extensions 2024-05-17 22:04:49 +01:00
kodjomoustapha
b76835a0a7 Fix some MangaReader sources flag 2024-05-17 20:40:26 +01:00
kodjomoustapha
73bc8ce75c Add New Madara sources 2024-05-17 20:33:34 +01:00
github-actions[bot]
b4542881ab Update extensions 2024-05-17 16:28:19 +00:00
kodjomoustapha
1661ef9149 New MangaReader sources 2024-05-17 17:26:08 +01:00
github-actions[bot]
9341b1d0a3 Update extensions 2024-05-17 10:07:37 +00:00
kodjomoustapha
e420a10df9 fix AnimeWorld India(ALL) 2024-05-17 11:06:32 +01:00
github-actions[bot]
d4dd99a3cd Update extensions 2024-05-14 12:51:02 +00:00
Moustapha Kodjo Amadou
b28c106d87
Merge pull request #63 from Ftbom/main
some fixes
2024-05-14 13:49:51 +01:00
ftbom
bc03517eff some fixes 2024-05-14 18:47:29 +08:00
github-actions[bot]
de8e3cd7ae Update extensions 2024-05-13 09:51:55 +00:00
kodjomoustapha
45113c5cec Add 2024 2024-05-13 10:46:49 +01:00
github-actions[bot]
419426b804 Update extensions 2024-05-13 09:07:50 +00:00
Moustapha Kodjo Amadou
21daead997
Merge pull request #62 from Ftbom/main
add mikan and yhdm
2024-05-13 10:07:33 +01:00
ftbom
8f01b54e0c add mikan and yhdm 2024-05-13 07:46:42 +08:00
kodjomoustapha
cba8e6d226 fix 2024-05-09 17:48:53 +01:00
github-actions[bot]
ce00c7c6e4 Update extensions 2024-05-09 15:55:20 +00:00
kodjomoustapha
074fd3a682 Copymanga: fix getgetDetail url 2024-05-09 16:54:35 +01:00
github-actions[bot]
15ed18b6e1 Update extensions 2024-05-09 14:55:16 +00:00
kodjomoustapha
9ca3f7111f KissKh: add decrypt subtitle 2024-05-09 15:54:12 +01:00
github-actions[bot]
a482eaffff Update extensions 2024-05-09 13:59:15 +00:00
kodjomoustapha
97b15a98da feat(manga/zh): reverse chapters list 2024-05-09 14:58:32 +01:00
github-actions[bot]
f090e07c87 Update extensions 2024-05-09 13:44:59 +00:00
Moustapha Kodjo Amadou
0151b18632
Merge pull request #61 from Ftbom/main
dmzj.js fix wrong pkgPath
2024-05-09 14:44:41 +01:00
Ftbom
7fc352dccd
dmzj.js fix wrong pkgPath 2024-05-09 21:40:48 +08:00
github-actions[bot]
b07a153189 Update extensions 2024-05-09 13:32:06 +00:00
kodjomoustapha
e30014431f fix #55 2024-05-09 14:31:43 +01:00
github-actions[bot]
3fb11d396d Update extensions 2024-05-09 13:28:05 +00:00
Moustapha Kodjo Amadou
3768fc19b5
Merge pull request #53 from Ftbom/main
add dmzj,copymanga,jmcomic
2024-05-09 14:27:48 +01:00
Ftbom
0ba0d5044e
add dmzj,copymanga,jmccomic 2024-05-09 07:55:36 +08:00
github-actions[bot]
c8f78a4b58 Update extensions 2024-05-07 08:14:47 +00:00
Moustapha Kodjo Amadou
f0731f18d2
Merge pull request #51 from Yursd/main
add njav(anime/all)
2024-05-07 09:13:45 +01:00
Yursd
cf02442fde
Update njav.js 2024-05-07 14:31:19 +08:00
Yursd
adab4b4528
add njav 2024-05-07 14:27:22 +08:00
github-actions[bot]
a7aab58977 Update extensions 2024-05-06 10:11:51 +00:00
kodjomoustapha
2101a7da10 Fix DataLifeEngine video extractor 2024-05-06 11:07:01 +01:00
github-actions[bot]
2555a554c0 Update extensions 2024-05-04 18:59:05 +00:00
kodjomoustapha
fe9ade5589 feat(manga/zh): reverse chapters list 2024-05-04 19:53:05 +01:00
github-actions[bot]
a0b22d1587 Update extensions 2024-05-04 16:18:16 +00:00
Moustapha Kodjo Amadou
daa8d05e76
Merge pull request #49 from Ftbom/main
fix bugs
2024-05-04 17:17:59 +01:00
Moustapha Kodjo Amadou
81d87815a6
Update 77mh version 2024-05-04 17:16:20 +01:00
Moustapha Kodjo Amadou
f461f09f7e
Update manhuagui version 2024-05-04 17:15:37 +01:00
Moustapha Kodjo Amadou
e652e827e2
Update manhuadb version 2024-05-04 17:15:05 +01:00
Ftbom
cb9ab18d97 update iconUrl of manhuadb 2024-05-04 14:16:03 +00:00
Ftbom
7aa39bcbc6 fix bugs 2024-05-04 14:11:32 +00:00
github-actions[bot]
ad3f44c7bb Update extensions 2024-05-04 11:12:56 +00:00
Moustapha Kodjo Amadou
cf0e35367a
Merge pull request #48 from Ftbom/main
add some manga extensions
2024-05-04 12:12:38 +01:00
Ftbom
02f666db10
add some manga extensions 2024-05-04 17:59:54 +08:00
github-actions[bot]
a88ab18abd Update extensions 2024-05-03 14:34:32 +00:00
kodjomoustapha
a0df41e8b8 AnimesUltra: fix search 2024-05-03 15:33:06 +01:00
github-actions[bot]
cbf5bffde4 Update extensions 2024-05-03 14:13:38 +00:00
kodjomoustapha
e9863dc307 AnimesUltra: change baseUrl & fix server 2024-05-03 15:12:21 +01:00
kodjomoustapha
a5f7eb27f6 FrAnime: fix player 2024-05-03 11:50:22 +01:00
kodjomoustapha
67bb9c88ed OtakuFr fix player 2024-05-03 11:44:11 +01:00
kodjomoustapha
dd876615f5 Anime-Sama fix player 2024-05-03 11:18:09 +01:00
github-actions[bot]
a5d04c67c9 Update extensions 2024-04-30 16:28:06 +00:00
kodjomoustapha
f5f98fe65c Remove vidbmExtractor 2024-04-30 17:26:56 +01:00
github-actions[bot]
c99e481807 Update extensions 2024-04-29 12:31:17 +00:00
kodjomoustapha
f4b0f893ae Fix Aniwave use serverName instead url 2024-04-29 13:30:52 +01:00
github-actions[bot]
0f47a8ce8f Update extensions 2024-04-22 18:12:52 +00:00
Moustapha Kodjo Amadou
870140dae4
Merge pull request #47 from abdelaziz-mahdy/patch-1
Update gogoanime.dart
2024-04-22 19:12:33 +01:00
Moustapha Kodjo Amadou
c65f1d8813
Update source.dart 2024-04-22 19:09:10 +01:00
Abdelaziz Mahdy
9affe93790
Update gogoanime.dart 2024-04-22 18:07:11 +02:00
github-actions[bot]
6ddbbc80ae Update extensions 2024-04-17 09:37:15 +00:00
kodjomoustapha
09977b86be Aniwave: fix encryption 2024-04-17 10:35:18 +01:00
github-actions[bot]
975178da9b Update extensions 2024-04-13 05:45:30 +00:00
Moustapha Kodjo Amadou
d90d33b6b1
Update wnacg.js 2024-04-13 06:45:15 +01:00
github-actions[bot]
1dd038bdd2 Update extensions 2024-04-13 05:45:04 +00:00
Moustapha Kodjo Amadou
83762012fb
Update jable.js 2024-04-13 06:44:41 +01:00
github-actions[bot]
ea0a6fb38c Update extensions 2024-04-13 05:42:39 +00:00
Moustapha Kodjo Amadou
5f93542bcd
Merge pull request #43 from Yursd/main
fix wnacg and update jable
2024-04-13 06:41:34 +01:00
Yursd
bd5adfdccc
Update jable.js 2024-04-13 12:34:45 +08:00
Yursd
0ca21162b3
fix wnacg.js filter 2024-04-13 12:31:34 +08:00
Moustapha Kodjo Amadou
84fbd77bad
Merge pull request #42 from Yursd/main
Add some Chinese extensions
2024-04-11 06:33:53 +01:00
Yursd
52461baf30 Add some Chinese extensions 2024-04-11 11:03:17 +08:00
github-actions[bot]
d4e777483c Update extensions 2024-04-10 12:38:27 +00:00
kodjomoustapha
3662f5028a Fix Gogoanime getLatestUpdates & detail description 2024-04-10 13:36:24 +01:00
Moustapha Kodjo Amadou
7db7e20916
Update CONTRIBUTING-JS.md 2024-03-28 16:43:04 +01:00
Moustapha Kodjo Amadou
538d82f926
Update CONTRIBUTING-JS.md 2024-03-28 16:40:31 +01:00
597 changed files with 21677 additions and 6928 deletions

View file

@ -36,7 +36,6 @@ body:
label: Other details
placeholder: |
Additional details and attachments.
Example: "+18/NSFW = yes"
- type: checkboxes
id: acknowledgements

View file

@ -27,5 +27,6 @@ jobs:
git checkout main
git add index.json
git add anime_index.json
git add novel_index.json
git commit -m "Update extensions"
git push origin main --force

View file

@ -1,120 +1,38 @@
# Contributing
This guide have some instructions and tips on how to create a new Mangayomi extension.
This guide have some instructions and tips on how to create a new Mangayomi extension on Dart extension.
## Prerequisites
Before you start, please note that the ability to use following technologies is **required**.
Before starting please have installed the recent desktop version of the mangayomi application preferably or if you want with a tablet too.
- [Flutter development](https://flutter.dev/)
- [Dart](https://dart.dev/)
- Web scraping
- [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML)
- [CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors)
This project uses the capabilities of the [dart_eval](https://pub.dev/packages/dart_eval) package
### Tools
- [Android Studio](https://developer.android.com/studio)
- [VS Code](https://code.visualstudio.com/)
- Any platform emulator
### Writing your extension
1. Clone [Mangayomi](https://github.com/kodjodevf/mangayomi) next, read the README file to learn how to run the project.
2. Open the project then go to :
```console
lib
└── sources
└── source_test.dart
```
and you will see this :
1. Open the app.
2. Go to extension tab :
![1](https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/screenshots/1.png)
3. then click `+` and you will see :
![2](https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/screenshots/2.png)
4. Fill in the fields with your new source that you would like to create,
![3](https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/screenshots/dart-3.png)
NB: only the `ApiUrl` field is optional
then click on save
5. you will see your new source in the extension list
![4](https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/screenshots/dart-4.png)
click to open settings
6. After click on edit code
![5](https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/screenshots/dart-5.png)
7. Finally you can now write the extension
![6](https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/screenshots/dart-6.png)
- This page contains three parts:
- Code editor: where you will write your code
- Fecth result: where you will test the different implemented methods by having a result in the expected format
- Console: which will show you the logs
```bash
import 'package:mangayomi/models/source.dart';
//For testing purposes, set to true
const useTestSourceCode = true;
final testSourceModelList = [
Source(
id: "Test Source".hashCode,
name: "Test Source",
// Example: https://gogoanime3.net
baseUrl: "",
// source code
sourceCode: testSourceCode,
// Example: en
lang: "",
// Example: false for anime true for manga
isManga: false)
];
const testSourceCode = r'''
import 'package:mangayomi/bridge_lib.dart';
class TestSource extends MProvider {
TestSource({required this.source});
MSource source;
final Client client = Client(source);
@override
bool get supportsLatest => true;
@override
Future<MPages> getPopular(int page) async {
// TODO: implement
}
@override
Future<MPages> getLatestUpdates(int page) async {
// TODO: implement
}
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
// TODO: implement
}
@override
Future<MManga> getDetail(String url) async {
// TODO: implement
}
// For anime episode video list
@override
Future<List<MVideo>> getVideoList(String url) async {
// TODO: implement
}
// For manga chapter pages
@override
Future<List<String>> getPageList(String url) {
// TODO: implement
}
@override
List<dynamic> getFilterList() {
// TODO: implement
}
@override
List<dynamic> getSourcePreferences() {
// TODO: implement
}
}
TestSource main(MSource source) {
return TestSource(source:source);
}
''';
```
For testing your source set `useTestSourceCode` to true.
During the development it is recommended (but not necessary) to write it directly mangayomi application project.
Once extension is ready you can relocate your code into `mangayomi-extension` project in a `src` or `multisrc` package and create a Pull Request.
Once extension is ready you can relocate your code into `mangayomi-extension` project in a `src` or `multisrc` package
Create the folder with the name of the source such as [this example](https://github.com/kodjodevf/mangayomi-extensions/blob/main/dart/anime/src/en/kisskh)
after go either to the anime_source_list.dart file for anime or manga_source_list.dart for the manga and import the extension then
create a Pull Request.
### Source
@ -215,7 +133,7 @@ All control filters can have a default state set. It's usually recommended if th
#### Chapter pages
- When user opens an chapter, `getPageList` will be called and it will return a `List<String>` that are used by the reader.
- When user opens an chapter, `getPageList` will be called and it will return a `List<String>` or `List<Map<String,dynamic>>` with a list of `{"url":string,"headers":Map<String,String>}` that are used by the reader.
#### Episode Videos
@ -223,11 +141,11 @@ All control filters can have a default state set. It's usually recommended if th
## Example sources that can help you understand how to create your source
- [Example](https://github.com/kodjodevf/mangayomi-extensions/blob/main/anime/src/en/kisskh/kisskh.dart)
- [Example](https://github.com/kodjodevf/mangayomi-extensions/blob/main/dart/anime/src/en/kisskh/kisskh.dart)
of Json API usage.
- [Example](https://github.com/kodjodevf/mangayomi-extensions/blob/main/manga/src/en/mangahere/mangahere.dart)
- [Example](https://github.com/kodjodevf/mangayomi-extensions/blob/main/dart/manga/src/en/mangahere/mangahere.dart)
of HTML parsing using xpath selector.
- [Example](https://github.com/kodjodevf/mangayomi-extensions/blob/main/manga/multisrc/madara/madara.dart)
- [Example](https://github.com/kodjodevf/mangayomi-extensions/blob/main/dart/manga/multisrc/madara/madara.dart)
of HTML parsing using HTML DOM selector.

View file

@ -1,6 +1,6 @@
# Contributing
This guide have some instructions and tips on how to create a new Mangayomi extension on js extension.
This guide have some instructions and tips on how to create a new Mangayomi extension on JavaScript extension.
## Prerequisites
@ -97,7 +97,7 @@ a.k.a. the Latest source entry point in the app (invoked by tapping on the "Late
#### Chapter pages
- When user opens an chapter, `getPageList` will be called and it will return an array of string that are used by the reader.
- When user opens an chapter, `getPageList` will be called and it will return an array of string or an array of map like `{ url:string,headers:map }` that are used by the reader.
#### Episode Videos
@ -143,7 +143,7 @@ console.log(res.body);
const client = new Client();
final res = await client.post("http://example.com",{"Referer": "http://example.com"},{'name':'test'});
const res = await client.post("http://example.com",{"Referer": "http://example.com"},{'name':'test'});
console.log(res.body);
@ -183,7 +183,7 @@ console.log(document.selectFirst("a").attr("href")); // https://github.com/kodjo
console.log(document.selectFirst("td").text); // 1
```
See [`dom_selector`](https://github.com/kodjodevf/mangayomi/blob/lib/eval/javascript/dom_selector.dart) to see available methods.
See [`dom_selector`](https://github.com/kodjodevf/mangayomi/blob/main/lib/eval/javascript/dom_selector.dart) to see available methods.
### String utils

View file

@ -7,7 +7,7 @@ This repository contains the available extension catalogues for the [Mangayomi](
Contributions are welcome!
To get started with development, see [CONTRIBUTING.md](./CONTRIBUTING.md) for create sources in Dart or [CONTRIBUTING-JS.md](./CONTRIBUTING-JS.md) for create sources in JavaScript.
To get started with development, see [CONTRIBUTING-DART.md](./CONTRIBUTING-DART.md) for create sources in Dart or [CONTRIBUTING-JS.md](./CONTRIBUTING-JS.md) for create sources in JavaScript.
## License

File diff suppressed because one or more lines are too long

View file

@ -5,14 +5,14 @@ import 'multisrc/zorotheme/sources.dart';
import 'src/all/animeworldindia/sources.dart';
import 'src/all/nyaa/source.dart';
import 'src/ar/okanime/source.dart';
import 'src/de/aniflix/source.dart';
import 'src/de/animetoast/source.dart';
import 'src/en/animepahe/source.dart';
import 'src/en/aniwave/source.dart';
import 'src/en/dramacool/source.dart';
import 'src/en/gogoanime/source.dart';
import 'src/en/nineanimetv/source.dart';
import 'src/es/animeonlineninja/source.dart';
import 'src/fr/animesama/source.dart';
import 'src/fr/anizone/source.dart';
import 'src/hi/yomovies/source.dart';
import 'src/en/kisskh/source.dart';
import 'src/en/uhdmovies/source.dart';
@ -25,6 +25,7 @@ import 'src/id/otakudesu/source.dart';
import 'src/it/animesaturn/source.dart';
import 'src/pt/animesvision/source.dart';
import 'src/sq/filma24/source.dart';
import 'src/tr/diziwatch/source.dart';
List<Source> dartAnimesourceList = [
gogoanimeSource,
@ -37,7 +38,6 @@ List<Source> dartAnimesourceList = [
otakudesu,
nimegami,
oploverz,
aniwave,
...dopeflixSourcesList,
animesaturn,
uhdmoviesSource,
@ -47,10 +47,12 @@ List<Source> dartAnimesourceList = [
yomoviesSource,
animesamaSource,
nineanimetv,
aniflix,
...animeworldindiaSourcesList,
nyaaSource,
animepaheSource,
animetoast,
animesvision
animesvision,
diziwatchSource,
aniZoneSource,
animeonlineninjaSource
];

View file

@ -1,21 +1,25 @@
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';
import 'package:mangayomi/bridge_lib.dart';
class DataLifeEngine extends MProvider {
DataLifeEngine({required this.source});
MSource source;
final Client client = Client(source);
final Client client =
Client(source, json.encode({"useDartHttpClient": true}));
@override
bool get supportsLatest => false;
@override
String get baseUrl => getPreferenceValue(source.id, "overrideBaseUrl");
@override
Future<MPages> getPopular(int page) async {
final res = (await client
.get(Uri.parse("${source.baseUrl}${getPath(source)}page/$page")))
.body;
final res =
(await client.get(Uri.parse("$baseUrl${getPath(source)}page/$page")))
.body;
return animeFromElement(res);
}
@ -27,10 +31,10 @@ class DataLifeEngine extends MProvider {
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final filters = filterList.filters;
final baseUrl = source.baseUrl;
String res = "";
if (query.isNotEmpty) {
if (query.length < 4) return MPages([], false);
if (query.length < 4)
throw "La recherche est suspendue! La chaîne de recherche est vide ou contient moins de 4 caractères.";
final headers = {
"Host": Uri.parse(baseUrl).host,
"Origin": baseUrl,
@ -71,7 +75,9 @@ class DataLifeEngine extends MProvider {
@override
Future<MManga> getDetail(String url) async {
String res = (await client.get(Uri.parse(url))).body;
String res =
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
.body;
MManga anime = MManga();
final description = xpath(res, '//span[@itemprop="description"]/text()');
anime.description = description.isNotEmpty ? description.first : "";
@ -89,25 +95,40 @@ class DataLifeEngine extends MProvider {
episodesList.add(ep);
}
} else {
final eps = xpath(res,
'//*[@class="hostsblock"]/div/a[contains(@href,"https")]/parent::div/@class');
if (eps.isNotEmpty) {
for (var i = 0; i < eps.length; i++) {
final epUrls = xpath(res,
'//*[@class="hostsblock"]/div[@class="${eps[i]}"]/a[contains(@href,"https")]/@href');
final doc = parseHtml(res);
final elements = doc
.select(".hostsblock div:has(a)")
.where((MElement e) => e.outerHtml.contains("loadVideo('https://"))
.toList();
if (elements.isNotEmpty) {
for (var element in elements) {
element = element as MElement;
MChapter ep = MChapter();
ep.name = "Episode ${i + 1}";
ep.url = epUrls.join(",").replaceAll("/vd.php?u=", "");
ep.scanlator = eps[i].contains('vf') ? 'VF' : 'VOSTFR';
ep.name = element.className
.replaceAll("ep", "Episode ")
.replaceAll("vs", " VOSTFR")
.replaceAll("vf", " VF");
ep.url = element
.select("a")
.map((MElement e) => substringBefore(
substringAfter(e.attr('onclick'), "loadVideo('"), "')"))
.toList()
.join(",")
.replaceAll("/vd.php?u=", "");
ep.scanlator = element.className.contains('vf') ? 'VF' : 'VOSTFR';
episodesList.add(ep);
}
} else {
anime.status = MStatus.completed;
final epUrls = xpath(res,
'//*[contains(@class,"filmlinks")]/div/a[contains(@href,"https")]/@href');
MChapter ep = MChapter();
ep.name = "Film";
ep.url = epUrls.join(",").replaceAll("/vd.php?u=", "");
ep.url = doc
.select("a")
.where((MElement e) => e.outerHtml.contains("loadVideo('https://"))
.map((MElement e) => substringBefore(
substringAfter(e.attr('onclick'), "loadVideo('"), "')"))
.toList()
.join(",")
.replaceAll("/vd.php?u=", "");
episodesList.add(ep);
}
}
@ -122,13 +143,10 @@ class DataLifeEngine extends MProvider {
final sUrls = url.split(',');
for (var sUrl in sUrls) {
List<MVideo> a = [];
if (sUrl.contains("dood")) {
if (sUrl.contains("dood") || sUrl.contains("d000")) {
a = await doodExtractor(sUrl, "DoodStream");
} else if (sUrl.contains("voe.sx")) {
a = await voeExtractor(sUrl, "Voe");
} else if (sUrl.contains("streamvid") ||
sUrl.contains("guccihide") ||
sUrl.contains("streamhide")) {
} else if (["streamhide", "guccihide", "streamvid", "dhtpre"]
.any((a) => sUrl.contains(a))) {
a = await streamHideExtractor(sUrl);
} else if (sUrl.contains("uqload")) {
a = await uqloadExtractor(sUrl);
@ -138,6 +156,12 @@ class DataLifeEngine extends MProvider {
a = await sibnetExtractor(sUrl);
} else if (sUrl.contains("ok.ru")) {
a = await okruExtractor(sUrl);
} else if (sUrl.contains("vidmoly")) {
a = await vidmolyExtractor(sUrl);
} else if (sUrl.contains("streamtape")) {
a = await streamTapeExtractor(sUrl, "");
} else if (sUrl.contains("voe.sx")) {
a = await voeExtractor(sUrl, "");
}
videos.addAll(a);
}
@ -156,7 +180,7 @@ class DataLifeEngine extends MProvider {
MManga anime = MManga();
anime.name =
"$name ${season.isNotEmpty ? season.first.replaceAll("\n", " ") : ""}";
anime.imageUrl = "${source.baseUrl}$image";
anime.imageUrl = "$baseUrl$image";
anime.link = url;
animeList.add(anime);
}
@ -246,11 +270,70 @@ class DataLifeEngine extends MProvider {
return [video];
}
Future<List<MVideo>> vidmolyExtractor(String url) async {
final headers = {
'Referer': 'https://vidmoly.to',
};
List<MVideo> videos = [];
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
final playlistUrl =
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
"";
if (playlistUrl.isEmpty) return [];
final masterPlaylistRes =
await client.get(Uri.parse(playlistUrl), headers: headers);
if (masterPlaylistRes.statusCode == 200) {
for (var it
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "Vidmoly $quality"
..headers = headers;
videos.add(video);
}
}
return videos;
}
String getPath() {
if (source.name == "French Anime") return "/animes-vostfr/";
return "/serie-en-streaming/";
}
@override
List<dynamic> getSourcePreferences() {
return [
if (source.name == "Wiflix")
EditTextPreference(
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://wiflix-hd.vip",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://wiflix-hd.vip"),
if (source.name == "French Anime")
EditTextPreference(
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://french-anime.com",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://french-anime.com"),
];
}
@override
List<dynamic> getFilterList() {
return [

View file

@ -2,7 +2,7 @@ import '../../../../model/source.dart';
import 'src/frenchanime/frenchanime.dart';
import 'src/wiflix/wiflix.dart';
const _datalifeengineVersion = "0.0.35";
const _datalifeengineVersion = "0.0.6";
const _datalifeengineSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/datalifeengine/datalifeengine.dart";

View file

@ -7,7 +7,7 @@ Source _frenchanimeSource = Source(
baseUrl: "https://french-anime.com",
lang: "fr",
typeSource: "datalifeengine",
isManga: false,
itemType: ItemType.anime,
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/datalifeengine/src/frenchanime/icon.png",
);

View file

@ -4,10 +4,10 @@ Source get wiflixSource => _wiflixSource;
Source _wiflixSource = Source(
name: "Wiflix",
baseUrl: "https://wiflix.voto",
baseUrl: "https://wiflix-hd.vip",
lang: "fr",
typeSource: "datalifeengine",
isManga: false,
itemType: ItemType.anime,
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/datalifeengine/src/wiflix/icon.png",
);

View file

@ -336,6 +336,7 @@ class DopeFlix extends MProvider {
]),
SelectFilter("ReleaseYearFilter", "Released at", 0, [
SelectFilterOption("All", "all"),
SelectFilterOption("2024", "2024"),
SelectFilterOption("2023", "2023"),
SelectFilterOption("2022", "2022"),
SelectFilterOption("2021", "2021"),

View file

@ -2,7 +2,7 @@ import '../../../../model/source.dart';
import 'src/dopebox/dopebox.dart';
import 'src/sflix/sflix.dart';
const _dopeflixVersion = "0.0.5";
const _dopeflixVersion = "0.0.55";
const _dopeflixSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/dopeflix/dopeflix.dart";

View file

@ -7,7 +7,7 @@ Source _dopeboxSource = Source(
baseUrl: "https://dopebox.to",
lang: "en",
typeSource: "dopeflix",
isManga: false,
itemType: ItemType.anime,
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/dopeflix/src/dopebox/icon.png",
);

View file

@ -7,7 +7,7 @@ Source _sflixSource = Source(
baseUrl: "https://sflix.to",
lang: "en",
typeSource: "dopeflix",
isManga: false,
itemType: ItemType.anime,
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/dopeflix/src/sflix/icon.png",
);

View file

@ -2,7 +2,7 @@ import '../../../../model/source.dart';
import 'src/hianime/hianime.dart';
import 'src/kaido/kaido.dart';
const _zorothemeVersion = "0.0.9";
const _zorothemeVersion = "0.1.2";
const _zorothemeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/zorotheme/zorotheme.dart";
@ -15,5 +15,6 @@ List<Source> _zorothemeSourcesList = [
]
.map((e) => e
..sourceCodeUrl = _zorothemeSourceCodeUrl
..appMinVerReq = "0.4.0"
..version = _zorothemeVersion)
.toList();

View file

@ -6,7 +6,7 @@ Source _aniwatchSource = Source(
id: 814067600,
name: "HiAnime",
baseUrl: "https://hianime.to",
isManga: false,
itemType: ItemType.anime,
lang: "en",
typeSource: "zorotheme",
iconUrl:

View file

@ -6,7 +6,7 @@ Source _kaidoSource = Source(
name: "Kaido.to",
baseUrl: "https://kaido.to",
lang: "en",
isManga: false,
itemType: ItemType.anime,
typeSource: "zorotheme",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/zorotheme/src/kaido/icon.png",

File diff suppressed because one or more lines are too long

View file

@ -52,7 +52,8 @@ class AnimeWorldIndia extends MProvider {
url += "${ll(url)}s_genre=";
if (genre.isNotEmpty) {
for (var st in genre) {
url += "${st.value}".toLowerCase().replaceAll(" ", "-");
String value = st.value;
url += value.toLowerCase().replaceAll(" ", "-");
if (genre.length > 1) {
url += "%2C";
}

View file

@ -1,6 +1,6 @@
import '../../../../../model/source.dart';
const _animeworldindiaVersion = "0.0.25";
const _animeworldindiaVersion = "0.0.3";
const _animeworldindiaSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/all/animeworldindia/animeworldindia.dart";
@ -28,6 +28,6 @@ List<Source> _animeworldindiaSourcesList = _languages
typeSource: "multiple",
iconUrl: _iconUrl,
version: _animeworldindiaVersion,
isManga: false,
itemType: ItemType.anime,
sourceCodeUrl: _animeworldindiaSourceCodeUrl))
.toList();

View file

@ -59,6 +59,16 @@ class Nyaa extends MProvider {
return anime;
}
@override
Future<List<MVideo>> getVideoList(String url) async {
var video = MVideo();
video
..url = url
..originalUrl = url
..quality = "";
return [video];
}
@override
List<dynamic> getFilterList() {
return [

View file

@ -1,6 +1,6 @@
import '../../../../../model/source.dart';
const _nyaaVersion = "0.0.2";
const _nyaaVersion = "0.0.25";
const _nyaaSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/all/nyaa/nyaa.dart";
@ -15,5 +15,5 @@ Source _nyaaSource = Source(
typeSource: "torrent",
iconUrl: _iconUrl,
version: _nyaaVersion,
isManga: false,
itemType: ItemType.anime,
sourceCodeUrl: _nyaaSourceCodeUrl);

View file

@ -13,4 +13,4 @@ Source _okanimeSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/ar/okanime/icon.png",
sourceCodeUrl: _okanimeSourceCodeUrl,
version: _okanimeVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -1,240 +0,0 @@
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';
class AniFlix extends MProvider {
AniFlix({required this.source});
MSource source;
final Client client = Client(source);
@override
Future<MPages> getPopular(int page) async {
final headers = getHeader(source.baseUrl);
final res = (await client.get(
Uri.parse("${source.baseUrl}/api/show/new/${page - 1}"),
headers: headers))
.body;
return parseAnimeList(res, true);
}
@override
Future<MPages> getLatestUpdates(int page) async {
final headers = getHeader(source.baseUrl);
final res = (await client.get(
Uri.parse("${source.baseUrl}/api/show/airing/${page - 1}"),
headers: headers))
.body;
final datas = json.decode(res);
List<MManga> animeList = [];
List<String> ids = [];
for (var data in datas) {
final anim = data["season"]["show"];
if (!ids.contains(anim["id"])) {
ids.add(anim["id"]);
MManga anime = MManga();
anime.name = anim["name"];
anime.imageUrl =
"${source.baseUrl}/storage/" + (anim["cover_portrait"] ?? "");
anime.link =
getUrlWithoutDomain("${source.baseUrl}/api/show/${anim['url']}");
anime.description = anim["description"];
if (anim["airing"] == 0) {
anime.status = MStatus.completed;
} else if (anim["airing"] == 1) {
anime.status = MStatus.ongoing;
}
animeList.add(anime);
}
}
return MPages(animeList, true);
}
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final res = await client.post(
Uri.parse("${source.baseUrl}/api/show/search"),
headers: {'Referer': source.baseUrl},
body: {"search": query});
return parseAnimeList(res.body, false);
}
@override
Future<MManga> getDetail(String url) async {
final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body;
MManga anime = MManga();
final jsonRes = json.decode(res);
anime.name = jsonRes["name"];
if (jsonRes["cover_portrait"] != null) {
anime.imageUrl = "${source.baseUrl}/storage/" + jsonRes["cover_portrait"];
}
anime.description = jsonRes["description"];
anime.genre = (jsonRes["genres"] as List<Map<String, dynamic>>)
.map((e) => e["name"])
.toList();
var seasons = jsonRes["seasons"];
final animeUrl = jsonRes["url"];
List<MChapter>? episodesList = [];
for (var season in seasons) {
List<Map<String, dynamic>> episodes = season["episodes"];
int page = 1;
final res = (await client.get(Uri.parse(
"${source.baseUrl}/api/show/$animeUrl/${season["id"]}/$page")))
.body;
bool hasMoreResult =
(json.decode(res)["episodes"] as List<Map<String, dynamic>>)
.isNotEmpty;
while (hasMoreResult) {
final res = (await client.get(Uri.parse(
"${source.baseUrl}/api/show/$animeUrl/${season["id"]}/$page")))
.body;
final epList =
json.decode(res)["episodes"] as List<Map<String, dynamic>>;
page++;
episodes.addAll(epList);
hasMoreResult = epList.isNotEmpty;
}
for (var episode in episodes) {
String name = episode["name"] ?? "";
if (name.toLowerCase().contains("folge") ||
name.toLowerCase().contains("episode")) {
name = "";
} else {
name = ": $name";
}
MChapter ep = MChapter();
ep.name = "Staffel ${season["number"]} Folge ${episode["number"]}$name";
ep.url =
"/api/episode/show/$animeUrl/season/${season["number"]}/episode/${episode["number"]}";
episodesList.add(ep);
}
}
anime.chapters = episodesList.reversed.toList();
return anime;
}
@override
Future<List<MVideo>> getVideoList(String url) async {
final res = (await client.get(Uri.parse("${source.baseUrl}$url"),
headers: getHeader(source.baseUrl)))
.body;
final jsonRes = json.decode(res)["streams"];
List<MVideo> videos = [];
final hosterSelection = preferenceHosterSelection(source.id);
for (var stream in jsonRes) {
List<MVideo> a = [];
String quality = '${stream["hoster"]["name"]} - ${stream["lang"]}';
String link = stream["link"];
if ((link.contains("https://dood") || link.contains("https://d0")) &&
hosterSelection.contains("doodstream")) {
a = await doodExtractor(link, quality);
} else if (link.contains("https://streamtape") &&
hosterSelection.contains("streamtape")) {
a = await streamTapeExtractor(link, quality);
} else if (link.contains("https://voe.sx") &&
hosterSelection.contains("voe")) {
a = await voeExtractor(link, quality);
} else if (link.contains("https://streamlare") &&
hosterSelection.contains("streamlare")) {
a = await streamlareExtractor(link, quality, '', '');
}
videos.addAll(a);
}
return sortVideos(videos, source.id);
}
MPages parseAnimeList(String res, bool hasNextPage) {
final datas = json.decode(res);
List<MManga> animeList = [];
for (var data in datas) {
MManga anime = MManga();
anime.name = data["name"];
anime.imageUrl =
"${source.baseUrl}/storage/" + (data["cover_portrait"] ?? "");
anime.link =
getUrlWithoutDomain("${source.baseUrl}/api/show/${data['url']}");
anime.description = data["description"];
if (data["airing"] == 0) {
anime.status = MStatus.completed;
} else if (data["airing"] == 1) {
anime.status = MStatus.ongoing;
}
animeList.add(anime);
}
return MPages(animeList, hasNextPage);
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String hoster = getPreferenceValue(sourceId, "preferred_hoster");
String sub = getPreferenceValue(sourceId, "preferred_sub");
videos.sort((MVideo a, MVideo b) {
int hosterMatchA = 0;
if (a.url.toLowerCase().contains(hoster.toLowerCase()) &&
a.quality.toLowerCase().contains(sub.toLowerCase())) {
hosterMatchA = 1;
}
int hosterMatchB = 0;
if (b.url.toLowerCase().contains(hoster.toLowerCase()) &&
b.quality.toLowerCase().contains(sub.toLowerCase())) {
hosterMatchB = 1;
}
return hosterMatchB - hosterMatchA;
});
return videos;
}
List<String> preferenceHosterSelection(int sourceId) {
return getPreferenceValue(sourceId, "hoster_selectionn");
}
@override
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_hoster",
title: "Standard-Hoster",
summary: "",
valueIndex: 0,
entries: [
"Streamtape",
"Doodstream",
"Voe",
"Streamlare"
],
entryValues: [
"https://streamtape.com",
"https://dood",
"https://voe.sx",
"https://streamlare.com"
]),
ListPreference(
key: "preferred_sub",
title: "Standardmäßig Sub oder Dub?",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["Sub", "Dub"]),
MultiSelectListPreference(
key: "hoster_selectionn",
title: "Hoster auswählen",
summary: "",
entries: ["Streamtape", "Doodstream", "Voe", "Streamlare"],
entryValues: ["streamtape", "doodstream", "voe", "streamlare"],
values: ["streamtape", "doodstream", "voe", "streamlare"]),
];
}
}
Map<String, String> getHeader(String url) {
return {'Referer': url};
}
AniFlix main(MSource source) {
return AniFlix(source: source);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -1,16 +0,0 @@
import '../../../../../model/source.dart';
Source get aniflix => _aniflix;
const _aniflixVersion = "0.0.3";
const _aniflixCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/aniflix/aniflix.dart";
Source _aniflix = Source(
name: "Aniflix",
baseUrl: "https://aniflix.cc",
lang: "de",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/aniflix/icon.png",
sourceCodeUrl: _aniflixCodeUrl,
version: _aniflixVersion,
isManga: false);

View file

@ -76,8 +76,9 @@ class AnimeToast extends MProvider {
} else {
elements = document.select("#multi_link_tab1");
}
for (var element in elements) {
final episodeElement = element.selectFirst("div.tab-pane a");
final episodeElement = element.selectFirst("a");
final epT = episodeElement.text;
if (epT.contains(":") || epT.contains("-")) {
final url = episodeElement.attr("href");
@ -92,7 +93,7 @@ class AnimeToast extends MProvider {
episodesList.add(ep);
}
} else {
final episodeElements = element.select("div.tab-pane a");
final episodeElements = element.select("a");
for (var epElement in episodeElements) {
MChapter ep = MChapter();
ep.name = epElement.text;

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get animetoast => _animetoast;
const _animetoastVersion = "0.0.15";
const _animetoastVersion = "0.0.2";
const _animetoastCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/animetoast/animetoast.dart";
Source _animetoast = Source(
@ -13,4 +13,4 @@ Source _animetoast = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/animetoast/icon.png",
sourceCodeUrl: _animetoastCodeUrl,
version: _animetoastVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -12,6 +12,9 @@ class AnimePahe extends MProvider {
@override
String get baseUrl => getPreferenceValue(source.id, "preferred_domain");
@override
Map<String, String> get headers => {'cookie': '__ddg1_=;__ddg2_=;'};
@override
Future<MPages> getPopular(int page) async {
return await getLatestUpdates(page);
@ -19,8 +22,9 @@ class AnimePahe extends MProvider {
@override
Future<MPages> getLatestUpdates(int page) async {
final res =
(await client.get(Uri.parse("$baseUrl/api?m=airing&page=$page"))).body;
final res = (await client.get(Uri.parse("$baseUrl/api?m=airing&page=$page"),
headers: headers))
.body;
final jsonResult = json.decode(res);
final hasNextPage = jsonResult["current_page"] < jsonResult["last_page"];
List<MManga> animeList = [];
@ -37,9 +41,10 @@ class AnimePahe extends MProvider {
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final res =
(await client.get(Uri.parse("$baseUrl/api?m=search&l=8&q=$query")))
.body;
final res = (await client.get(
Uri.parse("$baseUrl/api?m=search&l=8&q=$query"),
headers: headers))
.body;
final jsonResult = json.decode(res);
List<MManga> animeList = [];
for (var item in jsonResult["data"]) {
@ -61,9 +66,10 @@ class AnimePahe extends MProvider {
final id = substringBefore(substringAfterLast(url, "?anime_id="), "&name=");
final name = substringAfterLast(url, "&name=");
final session = await getSession(name, id);
final res =
(await client.get(Uri.parse("$baseUrl/anime/$session?anime_id=$id")))
.body;
final res = (await client.get(
Uri.parse("$baseUrl/anime/$session?anime_id=$id"),
headers: headers))
.body;
final document = parseHtml(res);
final status =
(document.xpathFirst('//div/p[contains(text(),"Status:")]/text()') ??
@ -91,7 +97,7 @@ class AnimePahe extends MProvider {
anime.description += "\n\n$synonyms";
}
final epUrl = "$baseUrl/api?m=release&id=$session&sort=episode_desc&page=1";
final resEp = (await client.get(Uri.parse(epUrl))).body;
final resEp = (await client.get(Uri.parse(epUrl), headers: headers)).body;
final episodes = await recursivePages(epUrl, resEp, session);
anime.chapters = episodes;
@ -114,15 +120,17 @@ class AnimePahe extends MProvider {
}
if (hasNextPage) {
final newUrl = "${substringBeforeLast(url, "&page=")}&page=${page + 1}";
final newRes = (await client.get(Uri.parse(newUrl))).body;
final newRes =
(await client.get(Uri.parse(newUrl), headers: headers)).body;
animeList.addAll(await recursivePages(newUrl, newRes, session));
}
return animeList;
}
Future<String> getSession(String title, String animeId) async {
final res =
(await client.get(Uri.parse("$baseUrl/api?m=search&q=$title"))).body;
final res = (await client.get(Uri.parse("$baseUrl/api?m=search&q=$title"),
headers: headers))
.body;
return substringBefore(
substringAfter(
substringAfter(res, "\"id\":$animeId"), "\"session\":\""),
@ -131,19 +139,25 @@ class AnimePahe extends MProvider {
@override
Future<List<MVideo>> getVideoList(String url) async {
final res = (await client.get(Uri.parse("$baseUrl$url")));
//by default we use rhttp package but it does not support `followRedirects`
//so setting `useDartHttpClient` to true allows us to use a Dart http package that supports `followRedirects`
final client = Client(source, json.encode({"useDartHttpClient": true}));
final res = (await client.get(Uri.parse("$baseUrl$url"), headers: headers));
final document = parseHtml(res.body);
final downloadLinks = document.select("div#pickDownload > a");
final buttons = document.select("div#resolutionMenu > button");
List<MVideo> videos = [];
for (var i = 0; i < buttons.length; i++) {
final btn = buttons[i];
final audio = btn.attr("data-audio"); // Get audio type (jpn/eng). Japanese or Dubbed.
final kwikLink = btn.attr("data-src");
final quality = btn.text;
final paheWinLink = downloadLinks[i].attr("href");
if (getPreferenceValue(source.id, "preffered_link_type")) {
final noRedirectClient =
Client(source, json.encode({"followRedirects": false}));
final noRedirectClient = Client(source,
json.encode({"followRedirects": false, "useDartHttpClient": true}));
final kwikHeaders =
(await noRedirectClient.get(Uri.parse("${paheWinLink}/i"))).headers;
final kwikUrl =
@ -165,9 +179,11 @@ class AnimePahe extends MProvider {
getMapValue(json.encode(res.request.headers), "cookie");
cookie +=
"; ${getMapValue(json.encode(reskwik.headers), "set-cookie").replaceAll("path=/;", "")}";
final resNo =
await Client(source, json.encode({"followRedirects": false}))
.post(Uri.parse(url), headers: {
final resNo = await Client(
source,
json.encode(
{"followRedirects": false, "useDartHttpClient": true}))
.post(Uri.parse(url), headers: {
"referer": reskwik.request.url.toString(),
"cookie": cookie,
"user-agent":
@ -253,8 +269,20 @@ class AnimePahe extends MProvider {
List<MVideo> sortVideos(List<MVideo> videos) {
String quality = getPreferenceValue(source.id, "preferred_quality");
String preferredAudio = getPreferenceValue(source.id, "preferred_audio"); // get user's audio preference
videos.sort((MVideo a, MVideo b) {
// Prioritize audio first.
// Preferred Audio: Videos with matching preferred audio are ranked highest.
int audioMatchA = a.quality.contains(preferredAudio) ? 1 : 0;
int audioMatchB = b.quality.contains(preferredAudio) ? 1 : 0;
if (audioMatchA != audioMatchB) {
return audioMatchB - audioMatchA;
}
// quality prioritized next
// Preferred Video Quality: If audio matches, videos with preferred video quality are ranked higher.
int qualityMatchA = 0;
if (a.quality.contains(quality)) {
qualityMatchA = 1;
@ -308,6 +336,14 @@ class AnimePahe extends MProvider {
valueIndex: 0,
entries: ["1080p", "720p", "360p"],
entryValues: ["1080", "720", "360"]),
ListPreference(
key: "preferred_audio", // Add new preference for audio
title: "Preferred Audio",
summary: "Select your preferred audio language (Japanese or English).",
valueIndex: 0, // Default to Japanese (or whichever you prefer)
entries: ["Japanese", "English"],
entryValues: ["jpn", "eng"]),
];
}
}

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get animepaheSource => _animepaheSource;
const _animepaheVersion = "0.0.35";
const _animepaheVersion = "0.0.5";
const _animepaheSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/animepahe/animepahe.dart";
Source _animepaheSource = Source(
@ -13,4 +13,4 @@ Source _animepaheSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/animepahe/icon.png",
sourceCodeUrl: _animepaheSourceCodeUrl,
version: _animepaheVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -1,688 +0,0 @@
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';
class Aniwave extends MProvider {
Aniwave({required this.source});
MSource source;
final Client client = Client(source);
@override
String get baseUrl => getPreferenceValue(source.id, "preferred_domain1");
@override
Future<MPages> getPopular(int page) async {
final res = (await client
.get(Uri.parse("$baseUrl/filter?sort=trending&page=$page")))
.body;
return parseAnimeList(res);
}
@override
Future<MPages> getLatestUpdates(int page) async {
final res = (await client
.get(Uri.parse("$baseUrl/filter?sort=recently_updated&page=$page")))
.body;
return parseAnimeList(res);
}
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final filters = filterList.filters;
String url = "$baseUrl/filter?keyword=$query";
for (var filter in filters) {
if (filter.type == "OrderFilter") {
final order = filter.values[filter.state].value;
url += "${ll(url)}sort=$order";
} else if (filter.type == "GenreFilter") {
final genre = (filter.state as List).where((e) => e.state).toList();
if (genre.isNotEmpty) {
for (var st in genre) {
url += "${ll(url)}genre[]=${st.value}";
}
}
} else if (filter.type == "CountryFilter") {
final country = (filter.state as List).where((e) => e.state).toList();
if (country.isNotEmpty) {
for (var st in country) {
url += "${ll(url)}country[]=${st.value}";
}
}
} else if (filter.type == "SeasonFilter") {
final season = (filter.state as List).where((e) => e.state).toList();
if (season.isNotEmpty) {
for (var st in season) {
url += "${ll(url)}season[]=${st.value}";
}
}
} else if (filter.type == "YearFilter") {
final year = (filter.state as List).where((e) => e.state).toList();
if (year.isNotEmpty) {
for (var st in year) {
url += "${ll(url)}year[]=${st.value}";
}
}
} else if (filter.type == "TypeFilter") {
final type = (filter.state as List).where((e) => e.state).toList();
if (type.isNotEmpty) {
for (var st in type) {
url += "${ll(url)}type[]=${st.value}";
}
}
} else if (filter.type == "StatusFilter") {
final status = (filter.state as List).where((e) => e.state).toList();
if (status.isNotEmpty) {
for (var st in status) {
url += "${ll(url)}status[]=${st.value}";
}
}
} else if (filter.type == "LanguageFilter") {
final language = (filter.state as List).where((e) => e.state).toList();
if (language.isNotEmpty) {
for (var st in language) {
url += "${ll(url)}language[]=${st.value}";
}
}
} else if (filter.type == "RatingFilter") {
final rating = (filter.state as List).where((e) => e.state).toList();
if (rating.isNotEmpty) {
for (var st in rating) {
url += "${ll(url)}rating[]=${st.value}";
}
}
}
}
final res = (await client.get(Uri.parse("$url&page=$page"))).body;
return parseAnimeList(res);
}
@override
Future<MManga> getDetail(String url) async {
final statusList = [
{"Releasing": 0, "Completed": 1}
];
final res = (await client.get(Uri.parse("$baseUrl$url"))).body;
MManga anime = MManga();
final status = xpath(res, '//div[contains(text(),"Status")]/span/text()');
if (status.isNotEmpty) {
anime.status = parseStatus(status.first, statusList);
}
final description = xpath(res,
'//*[contains(@class,"synopsis")]/div[@class="shorting"]/div[@class="content"]/text()');
if (description.isNotEmpty) {
anime.description = description.first;
}
final author = xpath(res, '//div[contains(text(),"Studio")]/span/text()');
if (author.isNotEmpty) {
anime.author = author.first;
}
anime.genre = xpath(res, '//div[contains(text(),"Genre")]/span/a/text()');
final id = parseHtml(res).selectFirst("div[data-id]").attr("data-id");
final encrypt = vrfEncrypt(id);
final vrf = "vrf=${Uri.encodeComponent(encrypt)}";
final resEp =
(await client.get(Uri.parse("$baseUrl/ajax/episode/list/$id?$vrf")))
.body;
final html = json.decode(resEp)["result"];
List<MChapter>? episodesList = [];
final epsHtmls = parseHtml(html).select("div.episodes ul > li");
for (var epH in epsHtmls) {
final epHtml = epH.outerHtml;
final title = xpath(epHtml, '//li/@title').isNotEmpty
? xpath(epHtml, '//li/@title').first
: "";
final ids = xpath(epHtml, '//a/@data-ids').first;
final sub = xpath(epHtml, '//a/@data-sub').first;
final dub = xpath(epHtml, '//a/@data-dub').first;
final softsub = title.toLowerCase().contains("softsub") ? "1" : "";
final fillerEp = title.toLowerCase().contains("filler") ? "1" : "";
final epNum = xpath(epHtml, '//a/@data-num').first;
String scanlator = "";
if (sub == "1") {
scanlator += "Sub";
}
if (softsub == "1") {
scanlator += ", Softsub";
}
if (dub == "1") {
scanlator += ", Dub";
}
if (fillerEp == "1") {
scanlator += ", • Filler Episode";
}
MChapter episode = MChapter();
episode.name = "Episode $epNum";
episode.scanlator = scanlator;
episode.url = "$ids&epurl=$url/ep-$epNum";
episodesList.add(episode);
}
anime.chapters = episodesList.reversed.toList();
return anime;
}
@override
Future<List<MVideo>> getVideoList(String url) async {
final ids = substringBefore(url, "&");
final encrypt = vrfEncrypt(ids);
final vrf = "vrf=${Uri.encodeComponent(encrypt)}";
final res =
(await client.get(Uri.parse("$baseUrl/ajax/server/list/$ids?$vrf")))
.body;
final html = json.decode(res)["result"];
final vidsHtmls = parseHtml(html).select("div.servers > div");
List<MVideo> videos = [];
for (var vidH in vidsHtmls) {
final vidHtml = vidH.outerHtml;
final type = xpath(vidHtml, '//div/@data-type').first;
final serversIds = xpath(vidHtml, '//li/@data-link-id');
for (int i = 0; i < serversIds.length; i++) {
final serverId = serversIds[i];
final encrypt = vrfEncrypt(serverId);
final vrf = "vrf=${Uri.encodeComponent(encrypt)}";
final res =
(await client.get(Uri.parse("$baseUrl/ajax/server/$serverId?$vrf")))
.body;
final status = json.decode(res)["status"];
if (status == 200) {
List<MVideo> a = [];
final url = vrfDecrypt(json.decode(res)["result"]["url"]);
final hosterSelection = preferenceHosterSelection(source.id);
final typeSelection = preferenceTypeSelection(source.id);
if (typeSelection.contains(type.toLowerCase())) {
if (url.contains("vidplay") || url.contains("mcloud")) {
final hosterName =
url.contains("vidplay") ? "VidPlay" : "MyCloud";
if (hosterSelection.contains(hosterName.toLowerCase())) {
a = await vidsrcExtractor(url, hosterName, type);
}
} else if (url.contains("mp4upload") &&
hosterSelection.contains("mp4upload")) {
a = await mp4UploadExtractor(url, null, "", type);
} else if (url.contains("streamtape") &&
hosterSelection.contains("streamtape")) {
a = await streamTapeExtractor(url, "StreamTape - $type");
} else if (url.contains("filemoon") &&
hosterSelection.contains("filemoon")) {
a = await filemoonExtractor(url, "", type);
}
videos.addAll(a);
}
}
}
}
return sortVideos(videos, source.id);
}
MPages parseAnimeList(String res) {
List<MManga> animeList = [];
final urls = xpath(res, '//div[@class="item "]/div/div/div/a/@href');
final names = xpath(res, '//div[@class="item "]/div/div/div/a/text()');
final images = xpath(res, '//div[@class="item "]/div/div/a/img/@src');
for (var i = 0; i < names.length; i++) {
MManga anime = MManga();
anime.name = names[i];
anime.imageUrl = images[i];
anime.link = urls[i];
animeList.add(anime);
}
return MPages(animeList, true);
}
List<int> rc4Encrypt(String key, List<int> message) {
List<int> _key = utf8.encode(key);
int _i = 0, _j = 0;
List<int> _box = List.generate(256, (i) => i);
int x = 0;
for (int i = 0; i < 256; i++) {
x = (x + _box[i] + _key[i % _key.length]) % 256;
var tmp = _box[i];
_box[i] = _box[x];
_box[x] = tmp;
}
List<int> out = [];
for (var char in message) {
_i = (_i + 1) % 256;
_j = (_j + _box[_i]) % 256;
var tmp = _box[_i];
_box[_i] = _box[_j];
_box[_j] = tmp;
final c = char ^ (_box[(_box[_i] + _box[_j]) % 256]);
out.add(c);
}
return out;
}
String vrfEncrypt(String input) {
final rc4 = rc4Encrypt("ysJhV6U27FVIjjuk", input.codeUnits);
final vrf = base64Url.encode(rc4);
final vrf1 = base64.encode(vrf.codeUnits);
List<int> vrf2 = vrfShift(vrf1.codeUnits);
final vrf3 = base64.encode(vrf2);
return utf8.decode(rot13(vrf3.codeUnits));
}
String vrfDecrypt(String input) {
final decode = base64Url.decode(input);
final rc4 = rc4Encrypt("hlPeNwkncH0fq9so", decode);
return Uri.decodeComponent(utf8.decode(rc4));
}
List<int> vrfShift(List<int> vrf) {
var shifts = [-3, 3, -4, 2, -2, 5, 4, 5];
for (var i = 0; i < vrf.length; i++) {
var shift = shifts[i % 8];
vrf[i] = (vrf[i] + shift) & 0xFF;
}
return vrf;
}
List<int> rot13(List<int> vrf) {
for (var i = 0; i < vrf.length; i++) {
var byte = vrf[i];
if (byte >= 'A'.codeUnitAt(0) && byte <= 'Z'.codeUnitAt(0)) {
vrf[i] = (byte - 'A'.codeUnitAt(0) + 13) % 26 + 'A'.codeUnitAt(0);
} else if (byte >= 'a'.codeUnitAt(0) && byte <= 'z'.codeUnitAt(0)) {
vrf[i] = (byte - 'a'.codeUnitAt(0) + 13) % 26 + 'a'.codeUnitAt(0);
}
}
return vrf;
}
Future<List<MVideo>> vidsrcExtractor(
String url, String name, String type) async {
List<String> keys = json.decode((await client.get(Uri.parse(
"https://raw.githubusercontent.com/KillerDogeEmpire/vidplay-keys/keys/keys.json")))
.body);
List<MVideo> videoList = [];
final host = Uri.parse(url).host;
final apiUrl = await getApiUrl(url, keys);
final res = await client.get(Uri.parse(apiUrl), headers: {
"Host": host,
"Referer": Uri.decodeComponent(url),
"X-Requested-With": "XMLHttpRequest"
});
final result = json.decode(res.body)['result'];
if (result != 404) {
String masterUrl =
((result['sources'] as List<Map<String, dynamic>>).first)['file'];
final tracks = (result['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
List<MTrack> subtitles = [];
for (var sub in tracks) {
try {
MTrack subtitle = MTrack();
subtitle
..label = sub["label"]
..file = sub["file"];
subtitles.add(subtitle);
} catch (_) {}
}
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "$name - $type - $quality"
..headers = {"Referer": "https://$host/"}
..subtitles = subtitles;
videoList.add(video);
}
}
return videoList;
}
Future<String> getApiUrl(String url, List<String> keyList) async {
final host = Uri.parse(url).host;
final paramsToString = Uri.parse(url)
.queryParameters
.entries
.map((e) => "${e.key}=${e.value}")
.join("&");
var vidId = substringBefore(substringAfterLast(url, "/"), "?");
var encodedID = encodeID(vidId, keyList);
final apiSlug = await callFromFuToken(host, encodedID);
String apiUrlString = "";
apiUrlString += "https://$host/$apiSlug";
if (paramsToString.isNotEmpty) {
apiUrlString += "?$paramsToString";
}
return apiUrlString;
}
String encodeID(String vidId, List<String> keyList) {
var rc4Key1 = keyList[0];
var rc4Key2 = keyList[1];
final rc4 = rc4Encrypt(rc4Key1, vidId.codeUnits);
final rc41 = rc4Encrypt(rc4Key2, rc4);
return base64.encode(rc41).replaceAll("/", "_").trim();
}
Future<String> callFromFuToken(String host, String data) async {
final fuTokenScript =
(await client.get(Uri.parse("https://$host/futoken"))).body;
String js = "";
js += "(function";
js += substringBefore(
substringAfter(substringAfter(fuTokenScript, "window"), "function")
.replaceAll("jQuery.ajax(", ""),
"+location.search");
js += "}(\"$data\"))";
final jsRes = await evalJs(js);
if (jsRes == "error") return "";
return jsRes;
}
@override
List<dynamic> getFilterList() {
return [
SelectFilter("OrderFilter", "Sort order", 0, [
SelectFilterOption("Most relevance", "most_relevance"),
SelectFilterOption("Recently updated", "recently_updated"),
SelectFilterOption("Recently added", "recently_added"),
SelectFilterOption("Release date", "release_date"),
SelectFilterOption("Trending", "trending"),
SelectFilterOption("Name A-Z", "title_az"),
SelectFilterOption("Scores", "scores"),
SelectFilterOption("MAL scores", "mal_scores"),
SelectFilterOption("Most watched", "most_watched"),
SelectFilterOption("Most favourited", "most_favourited"),
SelectFilterOption("Number of episodes", "number_of_episodes"),
]),
SeparatorFilter(),
GroupFilter("GenreFilter", "Genre", [
CheckBoxFilter("Action", "1"),
CheckBoxFilter("Adventure", "2"),
CheckBoxFilter("Avant Garde", "2262888"),
CheckBoxFilter("Boys Love", "2262603"),
CheckBoxFilter("Comedy", "4"),
CheckBoxFilter("Demons", "4424081"),
CheckBoxFilter("Drama", "7"),
CheckBoxFilter("Ecchi", "8"),
CheckBoxFilter("Fantasy", "9"),
CheckBoxFilter("Girls Love", "2263743"),
CheckBoxFilter("Gourmet", "2263289"),
CheckBoxFilter("Harem", "11"),
CheckBoxFilter("Horror", "14"),
CheckBoxFilter("Isekai", "3457284"),
CheckBoxFilter("Iyashikei", "4398552"),
CheckBoxFilter("Josei", "15"),
CheckBoxFilter("Kids", "16"),
CheckBoxFilter("Magic", "4424082"),
CheckBoxFilter("Mahou Shoujo", "3457321"),
CheckBoxFilter("Martial Arts", "18"),
CheckBoxFilter("Mecha", "19"),
CheckBoxFilter("Military", "20"),
CheckBoxFilter("Music", "21"),
CheckBoxFilter("Mystery", "22"),
CheckBoxFilter("Parody", "23"),
CheckBoxFilter("Psychological", "25"),
CheckBoxFilter("Reverse Harem", "4398403"),
CheckBoxFilter("Romance", "26"),
CheckBoxFilter("School", "28"),
CheckBoxFilter("Sci-Fi", "29"),
CheckBoxFilter("Seinen", "30"),
CheckBoxFilter("Shoujo", "31"),
CheckBoxFilter("Shounen", "33"),
CheckBoxFilter("Slice of Life", "35"),
CheckBoxFilter("Space", "36"),
CheckBoxFilter("Sports", "37"),
CheckBoxFilter("Super Power", "38"),
CheckBoxFilter("Supernatural", "39"),
CheckBoxFilter("Suspense", "2262590"),
CheckBoxFilter("Thriller", "40"),
CheckBoxFilter("Vampire", "41")
]),
GroupFilter("CountryFilter", "Country", [
CheckBoxFilter("China", "120823"),
CheckBoxFilter("Japan", "120822")
]),
GroupFilter("SeasonFilter", "Season", [
CheckBoxFilter("Fall", "fall"),
CheckBoxFilter("Summer", "summer"),
CheckBoxFilter("Spring", "spring"),
CheckBoxFilter("Winter", "winter"),
CheckBoxFilter("Unknown", "unknown")
]),
GroupFilter("YearFilter", "Year", [
CheckBoxFilter("2023", "2023"),
CheckBoxFilter("2022", "2022"),
CheckBoxFilter("2021", "2021"),
CheckBoxFilter("2020", "2020"),
CheckBoxFilter("2019", "2019"),
CheckBoxFilter("2018", "2018"),
CheckBoxFilter("2017", "2017"),
CheckBoxFilter("2016", "2016"),
CheckBoxFilter("2015", "2015"),
CheckBoxFilter("2014", "2014"),
CheckBoxFilter("2013", "2013"),
CheckBoxFilter("2012", "2012"),
CheckBoxFilter("2011", "2011"),
CheckBoxFilter("2010", "2010"),
CheckBoxFilter("2009", "2009"),
CheckBoxFilter("2008", "2008"),
CheckBoxFilter("2007", "2007"),
CheckBoxFilter("2006", "2006"),
CheckBoxFilter("2005", "2005"),
CheckBoxFilter("2004", "2004"),
CheckBoxFilter("2003", "2003"),
CheckBoxFilter("2000s", "2000s"),
CheckBoxFilter("1990s", "1990s"),
CheckBoxFilter("1980s", "1980s"),
CheckBoxFilter("1970s", "1970s"),
CheckBoxFilter("1960s", "1960s"),
CheckBoxFilter("1950s", "1950s"),
CheckBoxFilter("1940s", "1940s"),
CheckBoxFilter("1930s", "1930s"),
CheckBoxFilter("1920s", "1920s"),
CheckBoxFilter("1910s", "1910s")
]),
GroupFilter("TypeFilter", "Type", [
CheckBoxFilter("Movie", "movie"),
CheckBoxFilter("TV", "tv"),
CheckBoxFilter("OVA", "ova"),
CheckBoxFilter("ONA", "ona"),
CheckBoxFilter("Special", "special"),
CheckBoxFilter("Music", "music")
]),
GroupFilter("StatusFilter", "Status", [
CheckBoxFilter("Not Yet Aired", "info"),
CheckBoxFilter("Releasing", "releasing"),
CheckBoxFilter("Completed", "completed")
]),
GroupFilter("LanguageFilter", "Language", [
CheckBoxFilter("Sub and Dub", "subdub"),
CheckBoxFilter("Sub", "sub"),
CheckBoxFilter("Dub", "dub")
]),
GroupFilter("RatingFilter", "Rating", [
CheckBoxFilter("G - All Ages", "g"),
CheckBoxFilter("PG - Children", "pg"),
CheckBoxFilter("PG 13 - Teens 13 and Older", "pg_13"),
CheckBoxFilter("R - 17+, Violence & Profanity", "r"),
CheckBoxFilter("R+ - Profanity & Mild Nudity", "r+"),
CheckBoxFilter("Rx - Hentai", "rx")
]),
];
}
@override
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_domain1",
title: "Preferred domain",
summary: "",
valueIndex: 0,
entries: [
"aniwave.to",
"aniwave.ws",
"aniwave.li",
"aniwave.vc"
],
entryValues: [
"https://aniwave.to",
"https://aniwave.ws",
"https://aniwave.li",
"https://aniwave.vc"
]),
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
ListPreference(
key: "preferred_language",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Softsub", "Dub"],
entryValues: ["Sub", "Softsub", "Dub"]),
ListPreference(
key: "preferred_server",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: [
"VidPlay",
"MyCloud",
"Filemoon",
"StreamTape",
"Mp4Upload"
],
entryValues: [
"vidplay",
"mycloud",
"filemoon",
"streamtape",
"mp4upload"
]),
MultiSelectListPreference(
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: [
"VidPlay",
"MyCloud",
"Filemoon",
"StreamTape",
"Mp4Upload"
],
entryValues: [
"vidplay",
"mycloud",
"filemoon",
"streamtape",
"mp4upload"
],
values: [
"vidplay",
"mycloud",
"filemoon",
"streamtape",
"mp4upload"
]),
MultiSelectListPreference(
key: "type_selection",
title: "Enable/Disable Type",
summary: "",
entries: ["Sub", "Softsub", "Dub"],
entryValues: ["sub", "softsub", "dub"],
values: ["sub", "softsub", "dub"]),
];
}
List<String> preferenceHosterSelection(int sourceId) {
return getPreferenceValue(sourceId, "hoster_selection");
}
List<String> preferenceTypeSelection(int sourceId) {
return getPreferenceValue(sourceId, "type_selection");
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String quality = getPreferenceValue(sourceId, "preferred_quality");
String server = getPreferenceValue(sourceId, "preferred_server");
String lang = getPreferenceValue(sourceId, "preferred_language");
videos.sort((MVideo a, MVideo b) {
int qualityMatchA = 0;
if (a.quality.contains(quality) &&
a.quality.toLowerCase().contains(lang.toLowerCase()) &&
a.quality.toLowerCase().contains(server.toLowerCase())) {
qualityMatchA = 1;
}
int qualityMatchB = 0;
if (b.quality.contains(quality) &&
b.quality.toLowerCase().contains(lang.toLowerCase()) &&
b.quality.toLowerCase().contains(server.toLowerCase())) {
qualityMatchB = 1;
}
if (qualityMatchA != qualityMatchB) {
return qualityMatchB - qualityMatchA;
}
final regex = RegExp(r'(\d+)p');
final matchA = regex.firstMatch(a.quality);
final matchB = regex.firstMatch(b.quality);
final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0;
final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0;
return qualityNumB - qualityNumA;
});
return videos;
}
String ll(String url) {
if (url.contains("?")) {
return "&";
}
return "?";
}
}
Aniwave main(MSource source) {
return Aniwave(source: source);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -1,16 +0,0 @@
import '../../../../../model/source.dart';
Source get aniwave => _aniwave;
const _aniwaveVersion = "0.0.65";
const _aniwaveCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/aniwave/aniwave.dart";
Source _aniwave = Source(
name: "Aniwave",
baseUrl: "https://aniwave.to",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/aniwave/icon.png",
sourceCodeUrl: _aniwaveCodeUrl,
version: _aniwaveVersion,
isManga: false);

View file

@ -13,4 +13,4 @@ Source _dramacoolSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/dramacool/icon.png",
sourceCodeUrl: _dramacoolSourceCodeUrl,
version: _dramacoolVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -35,27 +35,23 @@ class GogoAnime extends MProvider {
@override
Future<MPages> getLatestUpdates(int page) async {
final res = (await client.get(Uri.parse(
"https://ajax.gogo-load.com/ajax/page-recent-release-ongoing.html?page=$page&type=1")))
.body;
List<MManga> animeList = [];
final urls =
xpath(res, '//*[@class="added_series_body popular"]/ul/li/a[1]/@href');
final names = xpath(
res, '//*[//*[@class="added_series_body popular"]/ul/li/a[1]/@title');
List<String> images = [];
List<String> imagess = xpath(res,
'//*[//*[@class="added_series_body popular"]/ul/li/a/div[@class="thumbnail-popular"]/@style');
for (var url in imagess) {
images.add(url.replaceAll("background: url('", "").replaceAll("');", ""));
String url = baseUrl;
if (baseUrl.toLowerCase().contains("gogo")) {
url = url + "/?page=$page";
} else {
url = url + "/home.html?page=$page";
}
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final elements = document.select("div.img a");
List<MManga> animeList = [];
for (var i = 0; i < names.length; i++) {
MManga anime = MManga();
anime.name = names[i];
anime.imageUrl = images[i];
anime.link = urls[i];
for (var element in elements) {
var anime = MManga();
anime.name = element.attr("title");
anime.imageUrl = element.selectFirst("img")?.attr("src") ?? "";
final slug = substringBefore(element.attr("href"), "-episode-");
anime.link = "/category/$slug";
animeList.add(anime);
}
@ -175,10 +171,10 @@ class GogoAnime extends MProvider {
res, '//*[@class="anime_info_body_bg"]/p[@class="type"][5]/text()')
.first
.replaceAll("Status: ", "");
anime.description = xpath(
res, '//*[@class="anime_info_body_bg"]/p[@class="type"][2]/text()')
.first
.replaceAll("Plot Summary: ", "");
anime.description = parseHtml(res)
.selectFirst("div.anime_info_body_bg > div.description")
?.text ??
"";
anime.status = parseStatus(status, statusList);
anime.genre = xpath(
res, '//*[@class="anime_info_body_bg"]/p[@class="type"][3]/text()')
@ -589,6 +585,7 @@ class GogoAnime extends MProvider {
CheckBoxFilter("Winter", "winter"),
]),
GroupFilter("YearFilter", "Year", [
CheckBoxFilter("2024", "2024"),
CheckBoxFilter("2023", "2023"),
CheckBoxFilter("2022", "2022"),
CheckBoxFilter("2021", "2021"),
@ -985,6 +982,9 @@ class GogoAnime extends MProvider {
SelectFilter("SeasonIFilter", "Season", 0, [
SelectFilterOption("", ""),
SelectFilterOption("Latest season", "new-season.html"),
SelectFilterOption("Summer 2024", "sub-category/summer-2024-anime"),
SelectFilterOption("Spring 2024", "sub-category/spring-2024-anime"),
SelectFilterOption("Winter 2024", "sub-category/winter-2024-anime"),
SelectFilterOption("Summer 2023", "sub-category/summer-2023-anime"),
SelectFilterOption("Spring 2023", "sub-category/spring-2023-anime"),
SelectFilterOption("Winter 2023", "sub-category/winter-2023-anime"),

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get gogoanimeSource => _gogoanimeSource;
const _gogoanimeVersion = "0.0.9";
const _gogoanimeVersion = "0.1.15";
const _gogoanimeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/gogoanime/gogoanime.dart";
Source _gogoanimeSource = Source(
@ -13,4 +13,4 @@ Source _gogoanimeSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/gogoanime/icon.png",
sourceCodeUrl: _gogoanimeSourceCodeUrl,
version: _gogoanimeVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -18,7 +18,7 @@ class KissKh extends MProvider {
List<MManga> animeList = [];
for (var data in datas) {
MManga anime = MManga();
var anime = MManga();
anime.name = data["title"];
anime.imageUrl = data["thumbnail"] ?? "";
anime.link =
@ -42,7 +42,7 @@ class KissKh extends MProvider {
List<MManga> animeList = [];
for (var data in datas) {
MManga anime = MManga();
var anime = MManga();
anime.name = data["title"];
anime.imageUrl = data["thumbnail"] ?? "";
anime.link =
@ -63,7 +63,7 @@ class KissKh extends MProvider {
final jsonRes = json.decode(res);
List<MManga> animeList = [];
for (var data in jsonRes) {
MManga anime = MManga();
var anime = MManga();
anime.name = data["title"];
anime.imageUrl = data["thumbnail"] ?? "";
anime.link =
@ -79,7 +79,7 @@ class KissKh extends MProvider {
{"Ongoing": 0, "Completed": 1}
];
final res = (await client.get(Uri.parse(url))).body;
MManga anime = MManga();
var anime = MManga();
final jsonRes = json.decode(res);
final status = jsonRes["status"] ?? "";
anime.description = jsonRes["description"];
@ -123,22 +123,24 @@ class KissKh extends MProvider {
final subRes =
(await client.get(Uri.parse("${source.baseUrl}/api/Sub/$id"))).body;
var jsonSubRes = json.decode(subRes);
List<MTrack> subtitles = [];
for (var sub in jsonSubRes) {
try {
final subUrl = sub["src"];
final label = sub["label"];
MTrack subtitle = MTrack();
final subUrl = sub["src"] as String;
final label = sub["label"];
if (subUrl.endsWith("txt")) {
var subtitle = await getSubtitle(subUrl, label);
subtitles.add(subtitle);
} else {
var subtitle = MTrack();
subtitle
..label = label
..file = subUrl;
subtitles.add(subtitle);
} catch (_) {}
}
}
final videoUrl = jsonRes["Video"];
MVideo video = MVideo();
var video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
@ -150,6 +152,31 @@ class KissKh extends MProvider {
};
return [video];
}
Future<MTrack> getSubtitle(String subUrl, String subLang) async {
final response = await client.get(Uri.parse(subUrl), headers: {
"referer": "https://kisskh.me/",
"origin": "https://kisskh.me"
});
final subtitleData = response.body;
String decrypted = "\n";
for (String line in subtitleData.split('\n')) {
decrypted += "${decrypt(line.trim())}\n";
}
var subtitle = MTrack();
subtitle
..label = subLang
..file = decrypted;
return subtitle;
}
String decrypt(String data) {
final key = utf8.decode(
[56, 48, 53, 54, 52, 56, 51, 54, 52, 54, 51, 50, 56, 55, 54, 51]);
final iv = utf8.decode(
[54, 56, 53, 50, 54, 49, 50, 51, 55, 48, 49, 56, 53, 50, 55, 51]);
return cryptoHandler(data, iv, key, false);
}
}
KissKh main(MSource source) {

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get kisskhSource => _kisskhSource;
const _kisskhVersion = "0.0.55";
const _kisskhVersion = "0.0.6";
const _kisskhSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/kisskh/kisskh.dart";
Source _kisskhSource = Source(
@ -13,4 +13,4 @@ Source _kisskhSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/kisskh/icon.png",
sourceCodeUrl: _kisskhSourceCodeUrl,
version: _kisskhVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -244,7 +244,8 @@ class NineAnimeTv extends MProvider {
}
videoResJson = decryptAESCryptoJS(ciphertext, password);
} else {
videoResJson = resServer;
videoResJson = json.encode(
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>));
}
String masterUrl =
@ -399,6 +400,7 @@ class NineAnimeTv extends MProvider {
CheckBoxFilter("Winter", "4")
]),
GroupFilter("YearFilter", "Year", [
CheckBoxFilter("2024", "2024"),
CheckBoxFilter("2023", "2023"),
CheckBoxFilter("2022", "2022"),
CheckBoxFilter("2021", "2021"),

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get nineanimetv => _nineanimetv;
const _nineanimetvVersion = "0.0.3";
const _nineanimetvVersion = "0.0.4";
const _nineanimetvCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/nineanimetv/nineanimetv.dart";
Source _nineanimetv = Source(
@ -13,4 +13,4 @@ Source _nineanimetv = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/nineanimetv/icon.png",
sourceCodeUrl: _nineanimetvCodeUrl,
version: _nineanimetvVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -1,16 +1,16 @@
import '../../../../../model/source.dart';
Source get uhdmoviesSource => _uhdmoviesSource;
const _uhdmoviesVersion = "0.0.35";
const _uhdmoviesVersion = "0.0.45";
const _uhdmoviesSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/uhdmovies/uhdmovies.dart";
Source _uhdmoviesSource = Source(
name: "UHD Movies",
baseUrl: "https://uhdmovies.zip",
baseUrl: "https://uhdmovies.fans",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/uhdmovies/icon.png",
sourceCodeUrl: _uhdmoviesSourceCodeUrl,
version: _uhdmoviesVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -12,7 +12,7 @@ class UHDMovies extends MProvider {
bool get supportsLatest => false;
@override
String get baseUrl => getPreferenceValue(source.id, "pref_domain");
String get baseUrl => getPreferenceValue(source.id, "pref_domain_new");
@override
Future<MPages> getPopular(int page) async {
@ -126,13 +126,13 @@ class UHDMovies extends MProvider {
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "pref_domain",
key: "pref_domain_new",
title: "Currently used domain",
summary: "",
value: "https://uhdmovies.zip",
value: "https://uhdmovies.fans",
dialogTitle: "Currently used domain",
dialogMessage: "",
text: "https://uhdmovies.zip"),
text: "https://uhdmovies.fans"),
];
}

View file

@ -0,0 +1,311 @@
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';
class AnimeOnlineNinja extends MProvider {
AnimeOnlineNinja({required this.source});
MSource source;
final Client client = Client(source);
@override
bool get supportsLatest => false;
@override
Future<MPages> getPopular(int page) async {
final res =
(await client.get(Uri.parse("${source.baseUrl}/tendencias"))).body;
return parseAnimeList(res);
}
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
String pageStr = page == 1 ? "" : "page/$page/";
final res = (await client.get(Uri.parse(
"${source.baseUrl}/$pageStr?s=${query.replaceAll(" ", "+")}")))
.body;
return parseAnimeList(res,
selector: "div.result-item div.image a",
hasNextPage: parseHtml(res)
.selectFirst(
"div.pagination > *:last-child:not(span):not(.current)")
?.text !=
null);
}
@override
Future<MManga> getDetail(String url) async {
final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body;
MManga anime = MManga();
final document = parseHtml(res);
anime.description = document.selectFirst("div#info").text;
anime.genre = document
.selectFirst("div.sheader")
.select("div.data > div.sgeneros > a")
.map((e) => e.text)
.toList();
List<MChapter>? episodesList = [];
final seasonElements = document.select("div#seasons > div");
if (seasonElements.isEmpty) {
MChapter episode = MChapter();
episode.name = "Película";
episode.url = getUrlWithoutDomain(url);
episodesList.add(episode);
} else {
for (var seasonElement in seasonElements) {
final seasonName = seasonElement.selectFirst("span.se-t").text;
for (var epElement in seasonElement.select("ul.episodios > li")) {
final href = epElement.selectFirst("a[href]");
final epNum = epElement.selectFirst('div.numerando')?.text ?? "0 - 0";
MChapter episode = MChapter();
episode.name =
"Season $seasonName x ${substringAfter(epNum, '- ')} ${href.text}";
episode.url = getUrlWithoutDomain(href!.getHref);
episodesList.add(episode);
}
}
}
anime.chapters = episodesList.reversed.toList();
return anime;
}
@override
Future<List<MVideo>> getVideoList(String url) async {
final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body;
final document = parseHtml(res);
final players = document.select("ul#playeroptionsul li");
List<MVideo> videos = [];
for (var player in players) {
final name = player.selectFirst("span.title").text;
final type = player.attr("data-type");
final id = player.attr("data-post");
final num = player.attr("data-nume");
final resUrl = (await client.get(Uri.parse(
"${source.baseUrl}/wp-json/dooplayer/v1/post/$id?type=$type&source=$num")))
.body;
final url =
substringBefore(substringAfter(resUrl, "\"embed_url\":\""), "\",")
.replaceAll("\\", "");
videos.addAll(await extractVideos(url, name));
}
return sortVideos(videos, source.id);
}
Future<List<MVideo>> extractVideos(String url, String lang) async {
List<MVideo> videos = [];
List<MVideo> a = [];
if (url.contains("saidochesto.top") || lang == "MULTISERVER") {
return await extractFromMulti(url);
} else if (["filemoon", "moon", "filemooon"].any((a) => url.contains(a))) {
a = await filemoonExtractor(url, "$lang Filemoon - ", "");
} else if (["https://dood", "https://ds2play", "https://d0"]
.any((a) => url.contains(a))) {
a = await doodExtractor(url, "$lang DoodStream");
} else if (["streamtape", "stp", "stape"].any((a) => url.contains(a))) {
a = await streamTapeExtractor(url, "$lang StreamTape");
} else if (url.contains("uqload")) {
a = await uqloadExtractor(url, lang);
} else if (url.contains("wolfstream")) {
final resUrl = (await client.get(Uri.parse(url))).body;
final jsData =
parseHtml(resUrl).selectFirst("script:contains(sources)").text;
final videoUrl =
substringBefore(substringAfter(jsData, "{file:\""), "\"");
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "$lang WolfStream";
a = [video];
} else if (["wishembed", "streamwish", "strwish", "wish"]
.any((a) => url.contains(a))) {
a = await streamWishExtractor(url, "$lang StreamWish");
} else if (url.contains("mp4upload")) {
a = await mp4UploadExtractor(url, null, "$lang", "");
} else if (["vidhide", "filelions.top", "vid."]
.any((a) => url.contains(a))) {
a = await streamHideExtractor(url, lang);
}
videos.addAll(a);
return videos;
}
Future<List<MVideo>> streamHideExtractor(String url, String prefix) async {
final res = (await client.get(Uri.parse(url))).body;
final masterUrl = substringBefore(
substringAfter(
substringAfter(
substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\""),
'"');
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
List<MVideo> videos = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "$prefix StreamHideVid - $quality";
videos.add(video);
}
return videos;
}
Future<List<MVideo>> uqloadExtractor(String url, String lang) async {
final Client client =
Client(source, json.encode({"useDartHttpClient": true}));
final res = (await client.get(Uri.parse(url))).body;
final js = xpath(res, '//script[contains(text(), "sources:")]/text()');
if (js.isEmpty) {
return [];
}
final videoUrl =
substringBefore(substringAfter(js.first, "sources: [\""), '"');
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "$lang Uqload"
..headers = {"Referer": "${Uri.parse(url).origin}/"};
return [video];
}
Future<List<MVideo>> extractFromMulti(String url) async {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final prefLang = getPreferenceValue(source.id, "preferred_lang");
String langSelector = "";
if (prefLang.isEmpty) {
langSelector = "div";
} else {
langSelector = "div.OD_$prefLang";
}
List<MVideo> videos = [];
for (var element in document.select("div.ODDIV $langSelector > li")) {
final hosterUrl =
substringBefore(substringAfter(element.attr("onclick"), "('"), "')");
String lang = "";
if (langSelector == "div") {
lang = substringBefore(
substringAfter(element.parent?.attr("class"), "OD_", ""), " ");
} else {
lang = prefLang;
}
videos.addAll(await extractVideos(hosterUrl, lang));
}
return videos;
}
MPages parseAnimeList(String res,
{String selector = "article.w_item_a > a", bool hasNextPage = false}) {
final elements = parseHtml(res).select(selector);
List<MManga> animeList = [];
for (var element in elements) {
final url = getUrlWithoutDomain(element.getHref);
if (!url.startsWith("/episodio/")) {
MManga anime = MManga();
final img = element.selectFirst("img");
anime.name = img.attr("alt");
anime.imageUrl = img?.attr("data-src") ??
img?.attr("data-lazy-src") ??
img?.attr("srcset") ??
img?.getSrc;
anime.link = url;
animeList.add(anime);
}
}
return MPages(animeList, hasNextPage);
}
@override
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_lang",
title: "Preferred language",
summary: "",
valueIndex: 0,
entries: ["SUB", "All", "ES", "LAT"],
entryValues: ["SUB", "", "ES", "LAT"]),
ListPreference(
key: "preferred_server1",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: [
"Filemoon",
"DoodStream",
"StreamTape",
"Uqload",
"WolfStream",
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload"
],
entryValues: [
"Filemoon",
"DoodStream",
"StreamTape",
"Uqload",
"WolfStream",
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload"
]),
];
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String prefLang = getPreferenceValue(source.id, "preferred_lang");
String server = getPreferenceValue(sourceId, "preferred_server1");
videos.sort((MVideo a, MVideo b) {
int qualityMatchA = 0;
if (a.quality.toLowerCase().contains(prefLang.toLowerCase()) &&
a.quality.toLowerCase().contains(server.toLowerCase())) {
qualityMatchA = 1;
}
int qualityMatchB = 0;
if (b.quality.toLowerCase().contains(prefLang.toLowerCase()) &&
b.quality.toLowerCase().contains(server.toLowerCase())) {
qualityMatchB = 1;
}
if (qualityMatchA != qualityMatchB) {
return qualityMatchB - qualityMatchA;
}
final regex = RegExp(r'(\d+)p');
final matchA = regex.firstMatch(a.quality);
final matchB = regex.firstMatch(b.quality);
final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0;
final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0;
return qualityNumB - qualityNumA;
});
return videos;
}
}
AnimeOnlineNinja main(MSource source) {
return AnimeOnlineNinja(source: source);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1,16 @@
import '../../../../../model/source.dart';
Source get animeonlineninjaSource => _animeonlineninjaSource;
const _animeonlineninjaVersion = "0.0.3";
const _animeonlineninjaSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/es/animeonlineninja/animeonlineninja.dart";
Source _animeonlineninjaSource = Source(
name: "AnimeOnline.Ninja",
baseUrl: "https://ww3.animeonline.ninja",
lang: "es",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/es/animeonlineninja/icon.png",
sourceCodeUrl: _animeonlineninjaSourceCodeUrl,
version: _animeonlineninjaVersion,
itemType: ItemType.anime);

View file

@ -32,10 +32,10 @@ class AnimeSama extends MProvider {
final latest = document
.select("h2")
.where((MElement e) =>
e.outerHtml.toLowerCase().contains("derniers ajouts"))
e.outerHtml.toLowerCase().contains("derniers épisodes ajoutés"))
.toList();
final seasonElements = (latest.first.nextElementSibling as MElement)
.select(".scrollBarStyled > div")
final seasonElements = (latest.first.parent.nextElementSibling as MElement)
.select("div")
.toList();
List<MManga> seasons = [];
for (var seasonElement in seasonElements) {
@ -128,13 +128,22 @@ class AnimeSama extends MProvider {
List<MChapter>? episodesList = [];
for (var episodeNumber = 0; episodeNumber < maxLength; episodeNumber++) {
List<String> langs = [];
bool isVf = false;
int iVostfr = 0;
int iVf = 0;
List<Map<String, dynamic>> players = [];
for (var playerListt in playersList) {
for (var player in playerListt["players"]) {
for (var playerList in playersList) {
for (var player in playerList["players"]) {
if (player.length > episodeNumber) {
langs.add(playerListt["lang"]);
players.add(
{"lang": playerListt["lang"], "player": player[episodeNumber]});
isVf = playerList["lang"] == "vf";
if ((isVf && iVf < 2) || (!isVf && iVostfr < 2)) {
var lang = playerList["lang"];
if (!langs.contains(lang)) {
langs.add(lang);
}
players.add({"lang": lang, "player": player[episodeNumber]});
isVf ? iVf++ : iVostfr++;
}
}
}
}
@ -161,16 +170,9 @@ class AnimeSama extends MProvider {
String playerUrl = player["player"];
List<MVideo> a = [];
if (playerUrl.contains("sendvid")) {
a = await sendVidExtractor(playerUrl, null, lang);
} else if (playerUrl.contains("anime-sama.fr")) {
MVideo video = MVideo();
video
..url = playerUrl
..originalUrl = playerUrl
..quality = "${lang} - AS Player";
a = [video];
} else if (playerUrl.contains("sibnet.ru")) {
a = await sibnetExtractor(playerUrl, lang);
a = await sendVidExtractorr(playerUrl, "$lang ");
} else if (playerUrl.contains("vidmoly")) {
a = await vidmolyExtractor(playerUrl, lang);
}
videos.addAll(a);
}
@ -178,6 +180,94 @@ class AnimeSama extends MProvider {
return sortVideos(videos, source.id);
}
Future<List<MVideo>> vidmolyExtractor(String url, String lang) async {
final headers = {
'Referer': 'https://vidmoly.to',
};
List<MVideo> videos = [];
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
final playlistUrl =
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
"";
if (playlistUrl.isEmpty) return [];
final masterPlaylistRes =
await client.get(Uri.parse(playlistUrl), headers: headers);
if (masterPlaylistRes.statusCode == 200) {
for (var it
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "$lang Vidmoly $quality"
..headers = headers;
videos.add(video);
}
}
return videos;
}
Future<List<MVideo>> sendVidExtractorr(String url, String prefix) async {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final masterUrl = document.selectFirst("source#video_source")?.attr("src");
if (masterUrl == null) return [];
final masterHeaders = {
"Accept": "*/*",
"Host": Uri.parse(masterUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
List<MVideo> videos = [];
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
final videoHeaders = {
"Accept": "*/*",
"Host": Uri.parse(videoUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
var video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = prefix + "Sendvid:$quality"
..headers = videoHeaders;
videos.add(video);
}
} else {
var video = MVideo();
video
..url = masterUrl
..originalUrl = masterUrl
..quality = prefix + "Sendvid:default"
..headers = masterHeaders;
videos.add(video);
}
return videos;
}
@override
List<dynamic> getFilterList() {
return [
@ -240,74 +330,73 @@ class AnimeSama extends MProvider {
Future<List<MManga>> fetchAnimeSeasons(String url) async {
final res = (await client.get(Uri.parse(url))).body;
var document = parseHtml(res);
String animeName = document.getElementById("titreOeuvre")?.text ?? "";
var seasonRegex =
RegExp("^\\s*panneauAnime\\(\"(.*)\", \"(.*)\"\\)", multiLine: true);
var seasonRegex = RegExp(r'panneauAnime\("(.*?)",\s*"(.*?)"\);');
var scripts = document
.select("h2 + p + div > script, h2 + div > script")
.map((MElement element) => element.text)
.toList()
.join("");
List<MManga> animeList = [];
List<RegExpMatch> seasonRegexReg = seasonRegex.allMatches(scripts).toList();
for (var animeIndex = 0; animeIndex < seasonRegexReg.length; animeIndex++) {
final seasonName = seasonRegexReg[animeIndex].group(1);
final seasonStem = seasonRegexReg[animeIndex].group(2);
if (seasonStem.toLowerCase().contains("film")) {
var moviesUrl = "$url/$seasonStem";
var movies = await fetchPlayers(moviesUrl);
if (movies.isNotEmpty) {
var movieNameRegex =
RegExp("^\\s*newSPF\\(\"(.*)\"\\);", multiLine: true);
var moviesDoc = (await client.get(Uri.parse(moviesUrl))).body;
List<RegExpMatch> matches =
movieNameRegex.allMatches(moviesDoc).toList();
if (seasonName != "nom" && seasonStem != "url") {
if (seasonStem.toLowerCase().contains("film")) {
var moviesUrl = "$url/$seasonStem";
var movies = await fetchPlayers(moviesUrl);
if (movies.isNotEmpty) {
var movieNameRegex =
RegExp("^\\s*newSPF\\(\"(.*)\"\\);", multiLine: true);
var moviesDoc = (await client.get(Uri.parse(moviesUrl))).body;
List<RegExpMatch> matches =
movieNameRegex.allMatches(moviesDoc).toList();
for (var i = 0; i < movies.length; i++) {
var title = "";
if (animeIndex == 0 && movies.length == 1) {
title = animeName;
} else if (matches.length > i) {
title = "$animeName ${(matches[i]).group(1)}";
} else if (movies.length == 1) {
title = "$animeName Film";
} else {
title = "$animeName Film ${i + 1}";
for (var i = 0; i < movies.length; i++) {
var title = "";
if (animeIndex == 0 && movies.length == 1) {
title = animeName;
} else if (matches.length > i) {
title = "$animeName ${(matches[i]).group(1)}";
} else if (movies.length == 1) {
title = "$animeName Film";
} else {
title = "$animeName Film ${i + 1}";
}
MManga anime = MManga();
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
anime.genre = (document.xpathFirst(
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
"")
.split(",");
anime.description = document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
"";
anime.name = title;
anime.link = "$moviesUrl#$i";
anime.status = MStatus.completed;
animeList.add(anime);
}
MManga anime = MManga();
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
anime.genre = (document.xpathFirst(
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
"")
.split(",");
anime.description = document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
"";
anime.name = title;
anime.link = "$moviesUrl#$i";
anime.status = MStatus.completed;
animeList.add(anime);
}
} else {
MManga anime = MManga();
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
anime.genre = (document.xpathFirst(
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
"")
.split(",");
anime.description = document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
"";
anime.name =
'$animeName ${substringBefore(seasonName, ',').replaceAll('"', "")}';
anime.link = "$url/$seasonStem";
animeList.add(anime);
}
} else {
MManga anime = MManga();
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
anime.genre = (document.xpathFirst(
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
"")
.split(",");
anime.description = document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
"";
anime.name =
'$animeName ${substringBefore(seasonName, ',').replaceAll('"', "")}';
anime.link = "$url/$seasonStem";
animeList.add(anime);
}
}
return animeList;

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get animesamaSource => _animesama;
const animesamaVersion = "0.0.25";
const animesamaVersion = "0.0.4";
const animesamaCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesama/animesama.dart";
Source _animesama = Source(
@ -13,4 +13,4 @@ Source _animesama = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesama/icon.png",
sourceCodeUrl: animesamaCodeUrl,
version: animesamaVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -8,9 +8,12 @@ class AnimesUltra extends MProvider {
final Client client = Client(source);
@override
String get baseUrl => source.baseUrl;
@override
Future<MPages> getPopular(int page) async {
final res = (await client.get(Uri.parse(source.baseUrl))).body;
final res = (await client.get(Uri.parse(baseUrl))).body;
List<MManga> animeList = [];
final urls = xpath(res,
@ -33,7 +36,7 @@ class AnimesUltra extends MProvider {
@override
Future<MPages> getLatestUpdates(int page) async {
final res = (await client.get(Uri.parse(source.baseUrl))).body;
final res = (await client.get(Uri.parse(baseUrl))).body;
List<MManga> animeList = [];
final urls = xpath(res,
@ -56,7 +59,10 @@ class AnimesUltra extends MProvider {
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final res = (await client.get(Uri.parse(source.baseUrl))).body;
query = query.trim().replaceAll(" ", "+");
final res = (await client.get(Uri.parse(
"$baseUrl/index.php?do=search&subaction=search&story=$query")))
.body;
List<MManga> animeList = [];
final urls = xpath(res, '//*[@class="film-poster"]/a/@href');
@ -71,7 +77,7 @@ class AnimesUltra extends MProvider {
animeList.add(anime);
}
return MPages(animeList, false);
return MPages(animeList.reversed.toList(), false);
}
@override
@ -81,7 +87,8 @@ class AnimesUltra extends MProvider {
];
final res = (await client.get(Uri.parse(url))).body;
MManga anime = MManga();
var anime = MManga();
final doc = parseHtml(res);
anime.description =
xpath(res, '//*[@class="film-description m-hide"]/text()').first;
@ -91,66 +98,115 @@ class AnimesUltra extends MProvider {
anime.status = parseStatus(status, statusList);
anime.genre = xpath(res,
'//*[@class="item item-list" and contains(text(),"Genres:")]/a/text()');
anime.author = xpath(res,
'//*[@class="item item-title" and contains(text(),"Studio:")]/span[2]/text()')
.first;
final urlEp = url.replaceAll('.html', '/episode-1.html');
final resEpWebview =
await getHtmlViaWebview(urlEp, '//*[@class="ss-list"]/a/@href');
final epUrls =
xpath(resEpWebview, '//*[@class="ss-list"]/a/@href').reversed.toList();
final names = xpath(resEpWebview,
'//*[@class="ss-list"]/a/div[@class="ssli-detail"]/div/text()')
.reversed
.toList();
anime.author = doc.xpathFirst(
'//*[@class="item item-title" and contains(text(),"Studio:")]/span[2]/text()');
final episodesLength = int.parse(substringBefore(
doc.xpathFirst('//*[@class="film-stats"]/span[7]/text()'), "/")
.replaceAll("Ep", ""));
List<MChapter>? episodesList = [];
for (var i = 0; i < names.length; i++) {
MChapter episode = MChapter();
episode.name = names[i];
episode.url = epUrls[i];
for (var i = 0; i < episodesLength; i++) {
var episode = MChapter();
episode.name = "Episode ${i + 1}";
episode.url = url.replaceAll('.html', '/episode-${i + 1}.html');
episodesList.add(episode);
}
anime.chapters = episodesList;
anime.chapters = episodesList.reversed.toList();
return anime;
}
@override
Future<List<MVideo>> getVideoList(String url) async {
final resWebview = await getHtmlViaWebview(
url, '//*[@class="ps__-list"]/div/@data-server-id');
final resHtml = (await client.get(Uri.parse(url))).body;
final id = url.split('/')[4].split('-')[0];
final resServer = (await client
.get(Uri.parse("$baseUrl/engine/ajax/full-story.php?newsId=$id")))
.body;
final serverIds =
xpath(resWebview, '//*[@class="ps__-list"]/div/@data-server-id');
final serverNames =
xpath(resWebview, '//*[@class="ps__-list"]/div/a/text()');
xpath(resHtml, '//*[@class="ps__-list"]/div/@data-server-id');
final serverNames = xpath(resHtml, '//*[@class="ps__-list"]/div/a/text()');
List<String> serverUrls = [];
for (var id in serverIds) {
final serversUrls =
xpath(resWebview, '//*[@id="content_player_${id}"]/text()').first;
final serversUrls = xpath(jsonDecode(resServer)["html"],
'//*[@id="content_player_${id}"]/text()')
.first;
serverUrls.add(serversUrls);
}
List<MVideo> videos = [];
for (var i = 0; i < serverNames.length; i++) {
final name = serverNames[i];
final url = serverUrls[i];
List<MVideo> a = [];
if (name.contains("Sendvid")) {
a = await sendVidExtractor(url.replaceAll("https:////", "https://"),
json.encode({"Referer": "${source.baseUrl}/"}), "");
a = await sendVidExtractorr(
url.replaceAll("https:////", "https://"), "");
} else if (name.contains("Sibnet")) {
a = await sibnetExtractor(
"https://video.sibnet.ru/shell.php?videoid=$url");
} else if (name.contains("Mytv")) {
a = await myTvExtractor("https://www.myvi.tv/embed/$url");
} else if (name.contains("Fmoon")) {
a = await filemoonExtractor(url, "", "");
}
videos.addAll(a);
}
return videos;
}
Future<List<MVideo>> sendVidExtractorr(String url, String prefix) async {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final masterUrl = document.selectFirst("source#video_source")?.attr("src");
if (masterUrl == null) return [];
final masterHeaders = {
"Accept": "*/*",
"Host": Uri.parse(masterUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
List<MVideo> videos = [];
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
final videoHeaders = {
"Accept": "*/*",
"Host": Uri.parse(videoUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
var video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = prefix + "Sendvid:$quality"
..headers = videoHeaders;
videos.add(video);
}
} else {
var video = MVideo();
video
..url = masterUrl
..originalUrl = masterUrl
..quality = prefix + "Sendvid:default"
..headers = masterHeaders;
videos.add(video);
}
return videos;
}
}
AnimesUltra main(MSource source) {

View file

@ -1,17 +1,17 @@
import '../../../../../model/source.dart';
Source get animesultraSource => _animesultraSource;
const _animesultraVersion = "0.0.65";
const _animesultraVersion = "0.0.75";
const _animesultraSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesultra/animesultra.dart";
Source _animesultraSource = Source(
name: "AnimesUltra",
baseUrl: "https://ww.animesultra.net",
baseUrl: "https://w2.animesultra.net",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesultra/icon.png",
sourceCodeUrl: _animesultraSourceCodeUrl,
version: _animesultraVersion,
isManga: false,
itemType: ItemType.anime,
isFullData: false);

View file

@ -0,0 +1,490 @@
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';
class AniZone extends MProvider {
AniZone({required this.source});
final MSource source;
final Client client = Client(source);
// Constants for the xpath
static const String urlXpath =
'//*[contains(@class,"flw-item item-qtip")]/div[@class="film-poster"]/a/@href';
static const String nameXpath =
'//*[contains(@class,"flw-item item-qtip")]/div[@class="film-detail"]/h3/text()';
static const String imageXpath =
'//*[contains(@class,"flw-item item-qtip")]/div[@class="film-poster"]/img/@data-src';
// Methods for fetching the manga list (popular, latest & search)
Future<MPages> _getMangaList(String url) async {
final doc = (await client.get(Uri.parse(url))).body;
List<MManga> animeList = [];
final urls = xpath(doc, urlXpath);
final names = xpath(doc, nameXpath);
final images = xpath(doc, imageXpath);
if (urls.isEmpty || names.isEmpty || images.isEmpty) {
return MPages([], false);
}
for (var i = 0; i < names.length; i++) {
MManga anime = MManga();
anime.name = names[i];
anime.imageUrl = images[i];
anime.link = urls[i];
animeList.add(anime);
}
return MPages(animeList, urls.isNotEmpty);
}
@override
Future<MPages> getPopular(int page) async {
return _getMangaList("${source.baseUrl}/most-popular/?page=$page");
}
@override
Future<MPages> getLatestUpdates(int page) async {
return _getMangaList("${source.baseUrl}/recently-added/?page=$page");
}
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
String baseUrl = "${source.baseUrl}/filter?keyword=$query";
Map<String, List<String>> filterMap = {
"type": [],
"status": [],
"season": [],
"lang": [],
"genre": []
};
// Regroupement des filtres avec une logique générique
final filterHandlers = {
"TypeFilter": "type",
"LanguageFilter": "lang",
"SaisonFilter": "season",
"StatusFilter": "status",
"GenreFilter": "genre"
};
for (var filter in filterList.filters) {
if (filterHandlers.containsKey(filter.type)) {
var key = filterHandlers[filter.type]!;
for (var stateItem in filter.state as List) {
if (stateItem.state == true) {
filterMap[key]?.add(stateItem.value as String);
}
}
}
}
//add filters to the url dynamically
for (var entry in filterMap.entries) {
List<String> values = entry.value;
if (values.isNotEmpty) {
baseUrl += '&${entry.key}=${values.join("%2C")}';
}
}
return _getMangaList("$baseUrl&page=$page");
}
Future<MManga> getDetail(String url) async {
MManga anime = MManga();
try {
final doc = (await client.get(Uri.parse(url))).body;
final description = xpath(doc, '//p[contains(@class,"short")]/text()');
anime.description = description.isNotEmpty ? description.first : "";
final statusList = xpath(doc,
'//div[contains(@class,"col2")]//div[contains(@class,"item")]//div[contains(@class,"item-content")]/text()');
if (statusList.isNotEmpty) {
if (statusList[0] == "Terminer") {
anime.status = MStatus.completed;
} else if (statusList[0] == "En cours") {
anime.status = MStatus.ongoing;
} else {
anime.status = MStatus.unknown;
}
} else {
anime.status = MStatus.unknown;
}
anime.genre = xpath(doc,
'//div[contains(@class,"item")]//div[contains(@class,"item-content")]//a[contains(@href,"genre")]/text()');
final regex = RegExp(r'(\d+)$');
final match = regex.firstMatch(url);
if (match == null) {
throw Exception('Numéro de l\'épisode non trouvé dans l\'URL.');
}
final res = (await client.get(Uri.parse(
"${source.baseUrl}/ajax/episode/list/${match.group(1)}")))
.body;
List<MChapter> episodesList = [];
final episodeElements =
parseHtml(json.decode(res)["html"]).select(".ep-item");
// Associer chaque titre à son URL et récupérer les vidéos
for (var element in episodeElements) {
MChapter episode = MChapter();
episode.name = element.attr("title");
String id = substringAfterLast(element.attr("href"), "=");
episode.url = "${source.baseUrl}/ajax/episode/servers?episodeId=$id";
episodesList.add(episode);
}
anime.chapters = episodesList.reversed.toList();
return anime;
} catch (e) {
throw Exception('Erreur lors de la récupération des détails: $e');
}
}
@override
Future<List<MVideo>> getVideoList(String url) async {
final videoRes = (await client
.get(Uri.parse(url), headers: {"Referer": "${source.baseUrl}/"}))
.body;
final lang = xpath(videoRes.replaceAll(r'\', ''),
'//div[contains(@class,"item server-item")]/@data-type');
final links = xpath(videoRes.replaceAll(r'\', ''),
'//div[contains(@class,"item server-item")]/@data-id');
final playersNames = xpath(videoRes.replaceAll(r'\', ''),
'//div[contains(@class,"item server-item")]/text()');
List<Map<String, String>> players = [];
for (int j = 0; j < links.length; j++) {
// schema of players https://v1.animesz.xyz/ajax/episode/servers?episodeId=(id_episode)
// schema or url https://v1.animesz.xyz/ajax/episode/sources?id=(player_id)&epid=(id_episode)
if (playersNames.isNotEmpty && playersNames[j] == "sibnet") {
final playerUrl =
"https://video.sibnet.ru/shell.php?videoid=${links[j]}";
players.add({"lang": lang[j], "player": playerUrl});
} else if (playersNames.isNotEmpty && playersNames[j] == "sendvid") {
final playerUrl = "https://sendvid.com/embed/${links[j]}";
players.add({"lang": lang[j], "player": playerUrl});
} else if (playersNames.isNotEmpty && playersNames[j] == "VidCDN") {
final playerUrl =
"https://r.vidcdn.xyz/v1/api/get_sources/${links[j].replaceFirst(RegExp(r'vidcdn$'), '')}";
players.add({"lang": lang[j], "player": playerUrl});
} else if (playersNames.isNotEmpty && playersNames[j] == "Voe") {
final playerUrl = "https://voe.sx/e/${links[j]}";
players.add({"lang": lang[j], "player": playerUrl});
} else if (playersNames.isNotEmpty && playersNames[j] == "Fmoon") {
final playerUrl =
"https://filemoon.sx/e/${links[j]}&data-realid=${links[j]}&epid=${substringAfter(url, "episodeId=")}";
players.add({"lang": lang[j], "player": playerUrl});
}
}
List<MVideo> videos = [];
for (var player in players) {
String lang = (player["lang"] as String).toUpperCase();
String playerUrl = player["player"];
List<MVideo> a = [];
if (playerUrl.contains("sendvid")) {
a = await sendVidExtractorr(playerUrl, "$lang ");
} else if (playerUrl.contains("sibnet.ru")) {
a = await sibnetExtractor(playerUrl, lang);
} else if (playerUrl.contains("voe.sx")) {
a = await voeExtractor(playerUrl, "$lang ");
} else if (playerUrl.contains("vidcdn")) {
a = await vidcdnExtractor(playerUrl, lang);
} else if (playerUrl.contains("filemoon")) {
a = await filemoonExtractor(playerUrl, "$lang Filemoon - ", "");
} else if (playerUrl.contains("vidhide")) {
a = await streamHideExtractor(playerUrl, lang);
}
videos.addAll(a);
}
return sortVideos(videos, source.id);
}
Future<List<MVideo>> streamHideExtractor(String url, String prefix) async {
final res = (await client.get(Uri.parse(url))).body;
final masterUrl = substringBefore(
substringAfter(
substringAfter(
substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\""),
'"');
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
List<MVideo> videos = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "$prefix StreamHideVid - $quality";
videos.add(video);
}
return videos;
}
@override
List<dynamic> getFilterList() {
return [
GroupFilter("TypeFilter", "Type", [
CheckBoxFilter("Film", "1"),
CheckBoxFilter("Anime", "2"),
CheckBoxFilter("OVA", "3"),
CheckBoxFilter("ONA", "4"),
CheckBoxFilter("Special", "5"),
CheckBoxFilter("Music", "6"),
]),
GroupFilter("LanguageFilter", "Langue", [
CheckBoxFilter("VF", "3"),
CheckBoxFilter("VOSTFR", "4"),
CheckBoxFilter("Multicc", "2"),
CheckBoxFilter("EN", "1"),
]),
GroupFilter("SaisonFilter", "Saison", [
CheckBoxFilter("Printemps", "1"),
CheckBoxFilter("Été", "2"),
CheckBoxFilter("Automne", "3"),
CheckBoxFilter("Hiver", "4"),
]),
GroupFilter("StatusFilter", "Statut", [
CheckBoxFilter("Terminés", "1"),
CheckBoxFilter("En cours", "2"),
CheckBoxFilter("Pas encore diffusés", "3"),
]),
GroupFilter("GenreFilter", "Genre", [
CheckBoxFilter("Action", "1"),
CheckBoxFilter("Aventure", "2"),
CheckBoxFilter("Voitures", "3"),
CheckBoxFilter("Comédie", "4"),
CheckBoxFilter("Démence", "5"),
CheckBoxFilter("Démons", "6"),
CheckBoxFilter("Drame", "8"),
CheckBoxFilter("Ecchi", "9"),
CheckBoxFilter("Fantastique", "10"),
CheckBoxFilter("Jeu", "11"),
CheckBoxFilter("Harem", "35"),
CheckBoxFilter("Historique", "13"),
CheckBoxFilter("Horreur", "14"),
CheckBoxFilter("Isekai", "44"),
CheckBoxFilter("Josei", "43"),
CheckBoxFilter("Enfants", "25"),
CheckBoxFilter("Magie", "16"),
CheckBoxFilter("Arts martiaux", "17"),
CheckBoxFilter("Mecha", "18"),
CheckBoxFilter("Militaire", "38"),
CheckBoxFilter("Musique", "19"),
CheckBoxFilter("Mystère", "7"),
CheckBoxFilter("Parodie", "20"),
CheckBoxFilter("Police", "39"),
CheckBoxFilter("Psychologique", "40"),
CheckBoxFilter("Romance", "22"),
CheckBoxFilter("Samouraï", "21"),
CheckBoxFilter("École", "23"),
CheckBoxFilter("Science-Fiction", "24"),
CheckBoxFilter("Seinen", "42"),
CheckBoxFilter("Shoujo Ai", "26"),
CheckBoxFilter("Shoujo", "25"),
CheckBoxFilter("Shounen Ai", "28"),
CheckBoxFilter("Tranche de vie", "36"),
CheckBoxFilter("Shounen", "27"),
CheckBoxFilter("Espace", "29"),
CheckBoxFilter("Sports", "30"),
CheckBoxFilter("Super Pouvoir", "31"),
CheckBoxFilter("Surnaturel", "37"),
CheckBoxFilter("Vampire", "32"),
CheckBoxFilter("Yaoi", "33"),
CheckBoxFilter("Yuri", "34"),
])
];
}
@override
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Qualité préférée",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
ListPreference(
key: "voices_preference",
title: "Préférence des voix",
summary: "",
valueIndex: 0,
entries: ["Préférer VOSTFR", "Préférer VF"],
entryValues: ["vostfr", "vf"]),
];
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String quality = getPreferenceValue(sourceId, "preferred_quality");
String voice = getPreferenceValue(sourceId, "voices_preference");
videos.sort((MVideo a, MVideo b) {
int qualityMatchA = 0;
if (a.quality.contains(quality) &&
a.quality.toLowerCase().contains(voice)) {
qualityMatchA = 1;
}
int qualityMatchB = 0;
if (b.quality.contains(quality) &&
b.quality.toLowerCase().contains(voice)) {
qualityMatchB = 1;
}
if (qualityMatchA != qualityMatchB) {
return qualityMatchB - qualityMatchA;
}
final regex = RegExp(r'(\d+)p');
final matchA = regex.firstMatch(a.quality);
final matchB = regex.firstMatch(b.quality);
final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0;
final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0;
return qualityNumB - qualityNumA;
});
return videos;
}
Future<List<MVideo>> sendVidExtractorr(String url, String prefix) async {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final masterUrl = document.selectFirst("source#video_source")?.attr("src");
print(masterUrl);
if (masterUrl == null) return [];
final masterHeaders = {
"Accept": "*/*",
"Host": Uri.parse(masterUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
List<MVideo> videos = [];
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
final videoHeaders = {
"Accept": "*/*",
"Host": Uri.parse(videoUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
var video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = prefix + "Sendvid:$quality"
..headers = videoHeaders;
videos.add(video);
}
} else {
var video = MVideo();
video
..url = masterUrl
..originalUrl = masterUrl
..quality = prefix + "Sendvid:default"
..headers = masterHeaders;
videos.add(video);
}
return videos;
}
Future<List<MVideo>> vidcdnExtractor(String url, String prefix) async {
final res = await client.get(Uri.parse(url));
if (res.statusCode != 200) {
print("Erreur lors de la récupération de la page : ${res.statusCode}");
return [];
}
final jsonResponse = jsonDecode(res.body);
String masterUrl = jsonResponse['sources'][0]['file'] ?? '';
final quality = jsonResponse['quality'] ?? '';
List<MVideo> videos = [];
final masterPlaylistRes = await client.get(Uri.parse(masterUrl));
if (masterPlaylistRes.statusCode != 200) {
print(
"Error lors de la récupération de la playlist M3U8 : ${masterPlaylistRes.statusCode}");
return [];
}
final masterPlaylistBody = masterPlaylistRes.body;
final playlistLines = masterPlaylistBody.split("\n");
for (int i = 0; i < playlistLines.length; i++) {
final line = playlistLines[i];
if (line.startsWith("#EXT-X-STREAM-INF")) {
final resolutionLine = line.split("RESOLUTION=").last;
final resolution = resolutionLine.split(",").first;
final width = int.parse(resolution.split("x").first);
final height = int.parse(resolution.split("x").last);
String videoQuality;
if (height >= 1080) {
videoQuality = "1080p";
} else if (height >= 720) {
videoQuality = "720p";
} else if (height >= 480) {
videoQuality = "480p";
} else if (height >= 360) {
videoQuality = "360p";
} else {
videoQuality = "${height}p";
}
String videoUrl = playlistLines[i + 1].trim();
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.substring(0, masterUrl.lastIndexOf('/'))}/$videoUrl";
}
var video = MVideo();
video
..url = masterUrl
..originalUrl = masterUrl
..quality = "$prefix VidCDN:$videoQuality";
videos.add(video);
}
}
return videos;
}
}
AniZone main(MSource source) {
return AniZone(source: source);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -0,0 +1,16 @@
import '../../../../../model/source.dart';
Source get aniZoneSource => _aniZoneSource;
const _aniZoneVersion = "0.0.2";
const _aniZoneSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/anizone.dart";
Source _aniZoneSource = Source(
name: "AniZone",
baseUrl: "https://v1.animesz.xyz",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/icon.png",
sourceCodeUrl: _aniZoneSourceCodeUrl,
version: _aniZoneVersion,
itemType: ItemType.anime);

View file

@ -146,14 +146,14 @@ class FrAnime extends MProvider {
.body;
List<MVideo> a = [];
print(playerName);
if (playerName.contains("vido")) {
videos.add(video
..url = playerUrl
..originalUrl = playerUrl
..quality = "FRAnime (Vido)");
} else if (playerName.contains("sendvid")) {
a = await sendVidExtractor(
playerUrl, json.encode({"Referer": "https://franime.fr/"}), "");
a = await sendVidExtractorr(playerUrl, "");
} else if (playerName.contains("sibnet")) {
a = await sibnetExtractor(playerUrl);
}
@ -335,6 +335,59 @@ class FrAnime extends MProvider {
}
return "";
}
Future<List<MVideo>> sendVidExtractorr(String url, String prefix) async {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final masterUrl = document.selectFirst("source#video_source")?.attr("src");
if (masterUrl == null) return [];
final masterHeaders = {
"Accept": "*/*",
"Host": Uri.parse(masterUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
List<MVideo> videos = [];
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
final videoHeaders = {
"Accept": "*/*",
"Host": Uri.parse(videoUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
var video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = prefix + "Sendvid:$quality"
..headers = videoHeaders;
videos.add(video);
}
} else {
var video = MVideo();
video
..url = masterUrl
..originalUrl = masterUrl
..quality = prefix + "Sendvid:default"
..headers = masterHeaders;
videos.add(video);
}
return videos;
}
}
FrAnime main(MSource source) {

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get franimeSource => _franimeSource;
const _franimeVersion = "0.0.7";
const _franimeVersion = "0.0.75";
const _franimeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/franime/franime.dart";
Source _franimeSource = Source(
@ -14,5 +14,5 @@ Source _franimeSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/franime/icon.png",
sourceCodeUrl: _franimeSourceCodeUrl,
version: _franimeVersion,
isManga: false,
itemType: ItemType.anime,
isFullData: true);

View file

@ -8,11 +8,13 @@ class OtakuFr extends MProvider {
final Client client = Client(source);
@override
String get baseUrl => getPreferenceValue(source.id, "overrideBaseUrl");
@override
Future<MPages> getPopular(int page) async {
final res =
(await client.get(Uri.parse("${source.baseUrl}/en-cours/page/$page")))
.body;
(await client.get(Uri.parse("$baseUrl/en-cours/page/$page"))).body;
List<MManga> animeList = [];
final urls =
xpath(res, '//*[@class="list"]/article/div/div/figure/a/@href');
@ -34,8 +36,7 @@ class OtakuFr extends MProvider {
@override
Future<MPages> getLatestUpdates(int page) async {
final res =
(await client.get(Uri.parse("${source.baseUrl}/page/$page/"))).body;
final res = (await client.get(Uri.parse("$baseUrl/page/$page/"))).body;
List<MManga> animeList = [];
final urls = xpath(res, '//*[@class="episode"]/div/a/@href');
@ -77,19 +78,17 @@ class OtakuFr extends MProvider {
final filters = filterList.filters;
String url = "";
if (query.isNotEmpty) {
url = "${source.baseUrl}/toute-la-liste-affiches/page/$page/?q=$query";
url = "$baseUrl/toute-la-liste-affiches/page/$page/?q=$query";
} else {
for (var filter in filters) {
if (filter.type == "GenreFilter") {
if (filter.state != 0) {
url =
"${source.baseUrl}/${filter.values[filter.state].value}page/$page";
url = "$baseUrl/${filter.values[filter.state].value}page/$page";
}
} else if (filter.type == "SubPageFilter") {
if (url.isEmpty) {
if (filter.state != 0) {
url =
"${source.baseUrl}/${filter.values[filter.state].value}page/$page";
url = "$baseUrl/${filter.values[filter.state].value}page/$page";
}
}
}
@ -122,7 +121,9 @@ class OtakuFr extends MProvider {
final statusList = [
{"En cours": 0, "Terminé": 1}
];
String res = (await client.get(Uri.parse(url))).body;
String res =
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
.body;
MManga anime = MManga();
final originalUrl = xpath(res,
'//*[@class="breadcrumb"]/li[@class="breadcrumb-item"][2]/a/@href');
@ -173,13 +174,16 @@ class OtakuFr extends MProvider {
@override
Future<List<MVideo>> getVideoList(String url) async {
final res = (await client.get(Uri.parse(url))).body;
final res =
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
.body;
final servers = xpath(res, '//*[@id="nav-tabContent"]/div/iframe/@src');
final servers = parseHtml(res).select("div.tab-content iframe[src]");
List<MVideo> videos = [];
final hosterSelection = preferenceHosterSelection(source.id);
for (var url in servers) {
final resServer = (await client.get(Uri.parse(fixUrl(url)),
final urll = url.getSrc != "about:blank" ? url.getSrc : url.getDataSrc;
final resServer = (await client.get(Uri.parse(fixUrl(urll)),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
final serverUrl =
@ -188,27 +192,24 @@ class OtakuFr extends MProvider {
if (serverUrl.contains("https://streamwish") &&
hosterSelection.contains("Streamwish")) {
a = await streamWishExtractor(serverUrl, "StreamWish");
} else if (serverUrl.contains("sibnet") &&
hosterSelection.contains("Sibnet")) {
a = await sibnetExtractor(serverUrl);
} else if (serverUrl.contains("https://doo") &&
hosterSelection.contains("Doodstream")) {
a = await doodExtractor(serverUrl);
} else if (serverUrl.contains("https://voe.sx") &&
hosterSelection.contains("Voe")) {
a = await voeExtractor(serverUrl, null);
} else if (containsVidBom(serverUrl) &&
hosterSelection.contains("VidBom")) {
a = await vidBomExtractor(serverUrl);
} else if (serverUrl.contains("https://ok.ru") &&
hosterSelection.contains("Okru")) {
a = await okruExtractor(serverUrl);
} else if (serverUrl.contains("vadbam") &&
hosterSelection.contains("Vidbm")) {
a = await vidbmExtractor(serverUrl);
} else if (serverUrl.contains("upstream") &&
hosterSelection.contains("Upstream")) {
a = await upstreamExtractor(serverUrl);
} else if (serverUrl.contains("sendvid") &&
hosterSelection.contains("Sendvid")) {
a = await sendVidExtractor(serverUrl, null, "");
a = await sendVidExtractorr(serverUrl, "");
} else if (serverUrl.contains("voe.sx") &&
hosterSelection.contains("Voe")) {
a = await voeExtractor(serverUrl, "");
}
videos.addAll(a);
}
@ -220,6 +221,17 @@ class OtakuFr extends MProvider {
return regExp(url, r"^(?:(?:https?:)?//|www\.)", 'https://', 0, 0);
}
bool containsVidBom(String url) {
url = url;
final list = ["vidbam", "vadbam", "vidbom", "vidbm"];
for (var n in list) {
if (url.contains(n)) {
return true;
}
}
return false;
}
@override
List<dynamic> getFilterList() {
return [
@ -279,6 +291,14 @@ class OtakuFr extends MProvider {
@override
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://otakufr.cc",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://otakufr.cc"),
ListPreference(
key: "preferred_quality",
title: "Qualité préférée",
@ -287,14 +307,14 @@ class OtakuFr extends MProvider {
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
MultiSelectListPreference(
key: "hoster_selection",
key: "hoster_selection_",
title: "Enable/Disable Hosts",
summary: "",
entries: [
"Streamwish",
"Doodstream",
"Sendvid",
"Vidbm",
"VidBom",
"Okru",
"Voe",
"Sibnet",
@ -304,7 +324,7 @@ class OtakuFr extends MProvider {
"Streamwish",
"Doodstream",
"Sendvid",
"Vidbm",
"VidBom",
"Okru",
"Voe",
"Sibnet",
@ -351,7 +371,60 @@ class OtakuFr extends MProvider {
}
List<String> preferenceHosterSelection(int sourceId) {
return getPreferenceValue(sourceId, "hoster_selection");
return getPreferenceValue(sourceId, "hoster_selection_");
}
Future<List<MVideo>> sendVidExtractorr(String url, String prefix) async {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final masterUrl = document.selectFirst("source#video_source")?.attr("src");
if (masterUrl == null) return [];
final masterHeaders = {
"Accept": "*/*",
"Host": Uri.parse(masterUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
List<MVideo> videos = [];
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
final videoHeaders = {
"Accept": "*/*",
"Host": Uri.parse(videoUrl).host,
"Origin": "https://${Uri.parse(url).host}",
"Referer": "https://${Uri.parse(url).host}/",
};
var video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = prefix + "Sendvid:$quality"
..headers = videoHeaders;
videos.add(video);
}
} else {
var video = MVideo();
video
..url = masterUrl
..originalUrl = masterUrl
..quality = prefix + "Sendvid:default"
..headers = masterHeaders;
videos.add(video);
}
return videos;
}
Future<List<MVideo>> upstreamExtractor(String url) async {
@ -385,56 +458,6 @@ class OtakuFr extends MProvider {
}
return videos;
}
Future<List<MVideo>> vidbmExtractor(String url) async {
final res = (await client.get(Uri.parse(url))).body;
final js = xpath(res,
'//script[contains(text(), "m3u8") or contains(text(), "mp4")]/text()');
if (js.isEmpty) {
return [];
}
final masterUrl = substringBefore(substringAfter(js.first, "source"), "\"");
final quality = substringBefore(
substringAfter(
substringBefore(
substringAfter(substringAfter(js.first, "source"), "file"),
"]"),
"label:\""),
"\"");
List<MVideo> videos = [];
if (masterUrl.contains("m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
if (!videoUrl.startsWith("http")) {
videoUrl =
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
}
MVideo video = MVideo();
video
..url = videoUrl
..originalUrl = videoUrl
..quality = "Vidbm - $quality";
videos.add(video);
}
return videos;
} else {
MVideo video = MVideo();
video
..url = masterUrl
..originalUrl = masterUrl
..quality = "Vidbm - $quality";
videos.add(video);
}
return videos;
}
}
OtakuFr main(MSource source) {

View file

@ -1,17 +1,17 @@
import '../../../../../model/source.dart';
Source get otakufr => _otakufr;
const otakufrVersion = "0.0.8";
const otakufrVersion = "0.0.95";
const otakufrCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/otakufr/otakufr.dart";
Source _otakufr = Source(
name: "OtakuFr",
baseUrl: "https://otakufr.co",
baseUrl: "https://otakufr.cc",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/otakufr/icon.png",
sourceCodeUrl: otakufrCodeUrl,
version: otakufrVersion,
isManga: false,
itemType: ItemType.anime,
isFullData: false);

View file

@ -1,7 +1,7 @@
import '../../../../../model/source.dart';
Source get yomoviesSource => _yomoviesSource;
const _yomoviesVersion = "0.0.2";
const _yomoviesVersion = "0.0.25";
const _yomoviesSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/hi/yomovies/yomovies.dart";
Source _yomoviesSource = Source(
@ -13,4 +13,4 @@ Source _yomoviesSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/hi/yomovies/icon.png",
sourceCodeUrl: _yomoviesSourceCodeUrl,
version: _yomoviesVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -213,6 +213,8 @@ class YoMovies extends MProvider {
SelectFilterOption("<select>", ""),
SelectFilterOption("Bollywood", "/genre/bollywood"),
SelectFilterOption("Trending", "/genre/top-rated"),
SelectFilterOption("Bollywood (2024)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2024&wpas=1"),
SelectFilterOption("Bollywood (2023)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2023&wpas=1"),
SelectFilterOption("Bollywood (2022)",

View file

@ -13,4 +13,4 @@ Source _nimegami = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/nimegami/icon.png",
sourceCodeUrl: _nimegamiCodeUrl,
version: _nimegamiVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -13,4 +13,4 @@ Source _oploverz = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/oploverz/icon.png",
sourceCodeUrl: _oploverzCodeUrl,
version: _oploverzVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -13,4 +13,4 @@ Source _otakudesu = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/otakudesu/icon.png",
sourceCodeUrl: _otakudesuCodeUrl,
version: _otakudesuVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -45,7 +45,7 @@ class AnimeSaturn extends MProvider {
final urls = xpath(res, '//*[@class="card mb-4 shadow-sm"]/a/@href');
final names = xpath(res, '///*[@class="card mb-4 shadow-sm"]/a/@title');
final names = xpath(res, '//*[@class="card mb-4 shadow-sm"]/a/@title');
final images = xpath(res,
'//*[@class="card mb-4 shadow-sm"]/a/img[@class="new-anime"]/@src');
@ -149,15 +149,18 @@ class AnimeSaturn extends MProvider {
final res = (await client.get(Uri.parse(url))).body;
MManga anime = MManga();
final details = xpath(res,
'//div[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100 text-white"]/text()')
.first;
final detailsList = xpath(res,
'//div[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100 text-white"]/text()');
if (detailsList.isNotEmpty) {
final details = detailsList.first;
anime.status = parseStatus(
details.substring(
details.indexOf("Stato:") + 6, details.indexOf("Data di uscita:")),
statusList);
anime.author = details.substring(7, details.indexOf("Stato:"));
}
anime.status = parseStatus(
details.substring(
details.indexOf("Stato:") + 6, details.indexOf("Data di uscita:")),
statusList);
anime.author = details.substring(7, details.indexOf("Stato:"));
final description = xpath(res, '//*[@id="shown-trama"]/text()');
final descriptionFull = xpath(res, '//*[@id="full-trama"]/text()');
if (description.isNotEmpty) {
@ -356,4 +359,4 @@ class AnimeSaturn extends MProvider {
AnimeSaturn main(MSource source) {
return AnimeSaturn(source: source);
}
}

View file

@ -1,16 +1,16 @@
import '../../../../../model/source.dart';
Source get animesaturn => _animesaturn;
const _animesaturnVersion = "0.0.35";
const _animesaturnVersion = "0.0.5";
const _animesaturnCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/it/animesaturn/animesaturn.dart";
Source _animesaturn = Source(
name: "AnimeSaturn",
baseUrl: "https://www.animesaturn.tv",
baseUrl: "https://www.animesaturn.cx",
lang: "it",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/it/animesaturn/icon.png",
sourceCodeUrl: _animesaturnCodeUrl,
version: _animesaturnVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -11,7 +11,8 @@ class AnimesVision extends MProvider {
@override
String get baseUrl => source.baseUrl;
Map<String, dynamic> get headers => {
@override
Map<String, String> get headers => {
"Referer": baseUrl,
"Accept-Language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7"
};

View file

@ -13,4 +13,4 @@ Source _animesvision = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/pt/animesvision/icon.png",
sourceCodeUrl: _animesvisionCodeUrl,
version: _animesvisionVersion,
isManga: false);
itemType: ItemType.anime);

View file

@ -6,10 +6,11 @@ class Filma24 extends MProvider {
MSource source;
final Client client = Client(source);
final Client client =
Client(source, json.encode({"useDartHttpClient": true}));
@override
String get baseUrl => getPreferenceValue(source.id, "pref_domain");
String get baseUrl => getPreferenceValue(source.id, "pref_domain_new");
@override
Future<MPages> getPopular(int page) async {
@ -121,13 +122,13 @@ class Filma24 extends MProvider {
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "pref_domain",
key: "pref_domain_new",
title: "Domeni i përdorur aktualisht",
summary: "",
value: "https://www.filma24.pl",
value: "https://www.filma24.band",
dialogTitle: "Domeni i përdorur aktualisht",
dialogMessage: "",
text: "https://www.filma24.pl"),
text: "https://www.filma24.band"),
];
}
@ -136,6 +137,7 @@ class Filma24 extends MProvider {
return [
SelectFilter("ReleaseFilter", "Viti", 0, [
SelectFilterOption("<Select>", ""),
SelectFilterOption("2024", "2024"),
SelectFilterOption("2023", "2023"),
SelectFilterOption("2022", "2022"),
SelectFilterOption("2021", "2021"),

View file

@ -1,16 +1,16 @@
import '../../../../../model/source.dart';
Source get filma24 => _filma24;
const _filma24Version = "0.0.25";
const _filma24Version = "0.0.45";
const _filma24CodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/sq/filma24/filma24.dart";
Source _filma24 = Source(
name: "Filma24",
baseUrl: "https://www.filma24.pl",
baseUrl: "https://www.filma24.band",
lang: "sq",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/sq/filma24/icon.png",
sourceCodeUrl: _filma24CodeUrl,
version: _filma24Version,
isManga: false);
itemType: ItemType.anime);

View file

@ -0,0 +1,213 @@
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';
class DiziWatch extends MProvider {
DiziWatch({required this.source});
MSource source;
final Client client = Client(source);
@override
bool get supportsLatest => true;
@override
Map<String, String> get headers => {};
Future<MPages> parseMainList(int index) async {
MDocument dom = parseHtml((await client.get(Uri.parse(source.baseUrl))) .body);
List<MManga> list = [];
MElement containingElement = dom.select("#list-series-hizala2")[index];
List<MElement> results = containingElement.select("#list-series-main");
for (MElement result in results) {
MElement a = result.selectFirst("a");
MElement img = a.selectFirst("img");
MManga anime = new MManga();
anime.name = img.attr("alt");
anime.link = a.getHref;
anime.imageUrl = img.getSrc;
list.add(anime);
}
return MPages(list, false);
}
@override
Future<MPages> getPopular(int page) async {
return parseMainList(1);
}
@override
Future<MPages> getLatestUpdates(int page) async {
return parseMainList(2);
}
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
String orderby = "";
String year = "";
String imdb = "";
String genre = "";
for (var filter in filterList.filters) {
if (filter.type == "Sort") {
orderby = filter.values[filter.state].value;
} else if (filter.type == "Year") {
year = filter.state;
} else if (filter.type == "MinIMDBRating") {
imdb = filter.values[filter.state].value;
} else if (filter.type == "Genre") {
genre = filter.values[filter.state].value;
}
}
MDocument dom = parseHtml((await client.get(Uri.parse("${source.baseUrl}/anime-arsivi/page/${page}/?orderby=${orderby}&yil=${year}&imdb=${imdb}&isim=${query}&tur=${genre}"))) .body);
List<MElement> results = dom.select("#list-series");
List<MManga> list = [];
for (MElement result in results) {
MElement a = result.select("a")[1];
MElement img = a.selectFirst("img");
MManga anime = new MManga();
anime.name = result.selectFirst("div.cat-title a").text;
anime.link = a.getHref;
anime.imageUrl = img.getSrc;
list.add(anime);
}
MElement paginateLinksDiv = dom.selectFirst("div.paginate-links");
int lastPage = int.parse(paginateLinksDiv.selectFirst("a.next").previousElementSibling.text ?? "1");
return MPages(list, lastPage > page);
}
@override
Future<MManga> getDetail(String url) async {
MDocument dom = parseHtml((await client.get(Uri.parse(url))) .body);
var anime = new MManga();
anime.name = dom.selectFirst("h1.title-border").text;
anime.link = url;
anime.imageUrl = dom.selectFirst("div.category_image img").getSrc;
anime.description = dom.selectFirst("div#series-info").text;
List<String> genres = dom.selectFirst("span.dizi-tur").text.split(", ");
genres.remove("Anime"); // not needed
anime.genre = genres;
List<MElement> results = dom.select("div.bolumust");
List<MChapter> chapters = [];
for (MElement result in results) {
MElement a = result.select("a")[1];
MChapter chapter = new MChapter();
chapter.name = result.selectFirst(".baslik").text + " | " + result.selectFirst("#bolum-ismi").text;
chapter.url = a.getHref;
chapters.add(chapter);
}
anime.chapters = chapters.reversed.toList();
return anime;
}
@override
Future<List<MVideo>> getVideoList(String url) async {
MDocument dom = parseHtml((await client.get(Uri.parse(url))) .body);
String id = dom.selectFirst("#takip_et_izledim_Calis").attr("data-ilanid");
var json = json.decode((await client.get(Uri.parse("${source.baseUrl}/wp-admin/admin-ajax.php?action=playlist&pid=${id}"))).body)[0];
var sources = json["sources"];
List<MVideo> videos = [];
for (var source in sources) {
MVideo video = new MVideo();
video.url = source["file"];
video.originalUrl = source["file"];
video.quality = source["label"];
video.headers = {"Referer": url};
videos.add(video);
}
String quality = getPreferenceValue(source.id, "preferred_quality");
videos.sort((MVideo a, MVideo b) => (b.quality.contains(quality) ? 1 : 0) - (a.quality.contains(quality) ? 1 : 0));
return videos;
}
@override
List<dynamic> getFilterList() {
return [
HeaderFilter("Filtrele"),
SelectFilter("Sort", "Sırala", 0, [
SelectFilterOption("IMDb Puanına Göre", "meta_value"),
SelectFilterOption("Alfabetik", "name"),
SelectFilterOption("Eklenme Tarihine Göre", "ID")
]),
TextFilter("Year", "Yapım Yılı"),
SelectFilter("Genre", "Tür", 0, [
SelectFilterOption("Kategori Seçin", ""),
SelectFilterOption("Aksiyon", "aksiyon"),
SelectFilterOption("Arabalar", "araba"),
SelectFilterOption("Askeri", "askeri"),
SelectFilterOption("Bilim Kurgu", "bilim"),
SelectFilterOption("Büyü", "buyu"),
SelectFilterOption("Doğaüstü Güçler", "doga"),
SelectFilterOption("Dövüş Sanatları", "dovus"),
SelectFilterOption("Dram", "dram"),
SelectFilterOption("Ecchi", "ecchi"),
SelectFilterOption("Fantastik", "fantastik"),
SelectFilterOption("Gerilim", "gerilim"),
SelectFilterOption("Gizem", "gizem"),
SelectFilterOption("Harem", "harem"),
SelectFilterOption("Isekai", "isekai"),
SelectFilterOption("Komedi", "komedi"),
SelectFilterOption("Korku", "korku"),
SelectFilterOption("Macera", "macera"),
SelectFilterOption("Mecha", "mecha"),
SelectFilterOption("Müzik", "muzik"),
SelectFilterOption("Okul", "okul"),
SelectFilterOption("Oyun", "oyun"),
SelectFilterOption("Parodi", "parodi"),
SelectFilterOption("Polisiye", "polisiye"),
SelectFilterOption("Psikolojik", "psikolojik"),
SelectFilterOption("Romantizm", "romantizm"),
SelectFilterOption("Samuray", "samuray"),
SelectFilterOption("Seinen", "seinen"),
SelectFilterOption("Shoujo", "shoujo"),
SelectFilterOption("Shounen", "shounen"),
SelectFilterOption("Spor", "spor"),
SelectFilterOption("Suç", "suc"),
SelectFilterOption("Süper Güçler", "super"),
SelectFilterOption("Şeytanlar", "seytan"),
SelectFilterOption("Şizofreni", "sizofreni"),
SelectFilterOption("Tarihi", "tarihi"),
SelectFilterOption("Uzay", "uzay"),
SelectFilterOption("Vampir", "vampir"),
SelectFilterOption("Yaşamdan Kesitler", "yasam")
]),
SelectFilter("MinIMDBRating", "Min. IMBD Puanı", 0, [
SelectFilterOption("1", "0"), // value 1 looks like buggy so use 0 it wont make any difference.
SelectFilterOption("2", "2"),
SelectFilterOption("3", "3"),
SelectFilterOption("4", "4"),
SelectFilterOption("5", "5"),
SelectFilterOption("6", "6"),
SelectFilterOption("7", "7"),
SelectFilterOption("8", "8"),
SelectFilterOption("9", "9")
])
];
}
@override
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Tercih edilen kalite",
summary: "",
valueIndex: 0,
entries: ["1080p", "480p"], // I only saw 1080p and 480p in diziWatch.
entryValues: ["1080", "480"])
];
}
}
DiziWatch main(MSource source) {
return DiziWatch(source:source);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,16 @@
import '../../../../../model/source.dart';
Source get diziwatchSource => _diziwatchSource;
const _diziwatchVersion = "0.0.1";
const _diziwatchSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/tr/diziwatch/diziwatch.dart";
Source _diziwatchSource = Source(
name: "diziWatch",
baseUrl: "https://diziwatch.net",
lang: "tr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/tr/diziwatch/icon.png",
sourceCodeUrl: _diziwatchSourceCodeUrl,
version: _diziwatchVersion,
itemType: ItemType.anime);

View file

@ -1,26 +1,16 @@
import '../../model/source.dart';
import 'multisrc/heancms/sources.dart';
import 'multisrc/madara/sources.dart';
import 'multisrc/mangabox/sources.dart';
import 'multisrc/mangareader/sources.dart';
import 'multisrc/mmrcms/sources.dart';
import 'multisrc/nepnep/sources.dart';
import 'src/all/batoto/sources.dart';
import 'src/all/comick/sources.dart';
import 'src/all/mangadex/sources.dart';
import 'src/all/nhentai/sources.dart';
import 'src/en/mangahere/source.dart';
List<Source> dartMangasourceList = [
...madaraSourcesList,
...comickSourcesList,
...mangaDexSourcesList,
...mangareaderSourcesList,
...mmrcmsSourcesList,
...heancmsSourcesList,
mangahereSource,
...nepnepSourcesList,
...mangaboxSourcesList,
...batotoSourcesList,
...nhentaiSourcesList
...mangaboxSourcesList
];

View file

@ -1,246 +0,0 @@
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';
class HeanCms extends MProvider {
HeanCms({required this.source});
MSource source;
final Client client = Client(source);
@override
Future<MPages> getPopular(int page) async {
final headers = getHeader(source.baseUrl);
String res = "";
if (!useNewQueryEndpoint(source.name)) {
final url = "${source.apiUrl}/series/querysearch";
final body = {
"page": page,
"order": "desc",
"order_by": "total_views",
"series_status": "Ongoing",
"series_type": "Comic"
};
res = (await client.post(Uri.parse(url), headers: headers, body: body))
.body;
} else {
final newEndpointUrl =
"${source.apiUrl}/query/?page=$page&query_string=&series_status=All&order=desc&orderBy=total_views&perPage=12&tags_ids=[]&series_type=Comic";
res =
(await client.get(Uri.parse(newEndpointUrl), headers: headers)).body;
}
return mMangaRes(res);
}
@override
Future<MPages> getLatestUpdates(int page) async {
final headers = getHeader(source.baseUrl);
String res = "";
if (!useNewQueryEndpoint(source.name)) {
final url = "${source.apiUrl}/series/querysearch";
final body = {
"page": page,
"order": "desc",
"order_by": "latest",
"series_status": "Ongoing",
"series_type": "Comic"
};
res = (await client.post(Uri.parse(url), headers: headers, body: body))
.body;
} else {
final newEndpointUrl =
"${source.apiUrl}/query/?page=$page&query_string=&series_status=All&order=desc&orderBy=latest&perPage=12&tags_ids=[]&series_type=Comic";
res =
(await client.get(Uri.parse(newEndpointUrl), headers: headers)).body;
}
return mMangaRes(res);
}
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final headers = getHeader(source.baseUrl);
String res = "";
if (!useNewQueryEndpoint(source.source)) {
final url = "${source.apiUrl}/series/search";
final body = {"term": query};
res = (await client.post(Uri.parse(url), headers: headers, body: body))
.body;
} else {
final newEndpointUrl =
"${source.apiUrl}/query/?page=$page&query_string=$query&series_status=All&order=desc&orderBy=total_views&perPage=12&tags_ids=[]&series_type=Comic";
res =
(await client.get(Uri.parse(newEndpointUrl), headers: headers)).body;
}
return mMangaRes(res);
}
@override
Future<MManga> getDetail(String url) async {
MManga manga = MManga();
String currentSlug = substringAfterLast(url, "/");
final headers = getHeader(source.baseUrl);
final res = (await client.get(
Uri.parse("${source.apiUrl}/series/$currentSlug"),
headers: headers))
.body;
manga.author = getMapValue(res, "author");
manga.description = getMapValue(res, "description");
manga.genre = jsonPathToString(res, r"$.tags[*].name", "._").split("._");
List<String> chapterTitles = [];
List<String> chapterUrls = [];
List<String> chapterDates = [];
if (!useNewQueryEndpoint(source.name)) {
for (var chapter in json.decode(res)["chapters"]) {
final chapterName = chapter["chapter_name"];
final chapterSlug = chapter["chapter_slug"];
final chapterId = chapter["id"];
final createdAt = chapter["created_at"];
chapterUrls.add("/series/$currentSlug/$chapterSlug#$chapterId");
chapterTitles.add(chapterName);
chapterDates.add(createdAt);
}
} else {
final seasons = json.decode(res)["seasons"].first;
for (var chapter in seasons["chapters"]) {
final chapterName = chapter["chapter_name"];
final chapterSlug = chapter["chapter_slug"];
final chapterId = chapter["id"];
final createdAt = chapter["created_at"];
chapterUrls.add("/series/$currentSlug/$chapterSlug#$chapterId");
chapterTitles.add(chapterName);
chapterDates.add(createdAt);
}
}
final dateUploads =
parseDates(chapterDates, source.dateFormat, source.dateFormatLocale);
List<MChapter>? chaptersList = [];
for (var i = 0; i < chapterTitles.length; i++) {
MChapter chapter = MChapter();
chapter.name = chapterTitles[i];
chapter.url = chapterUrls[i];
chapter.dateUpload = dateUploads[i];
chaptersList.add(chapter);
}
if (!useNewQueryEndpoint(source.name)) {
chaptersList = chaptersList.reversed.toList();
}
manga.chapters = chaptersList;
return manga;
}
@override
Future<List<String>> getPageList(String url) async {
final headers = getHeader(source.baseUrl);
String res = "".toString();
if (!useslugStrategy(source.name)) {
String chapterId = substringAfter(url, '#');
res = (await client.get(
Uri.parse("${source.apiUrl}/series/chapter/$chapterId"),
headers: headers))
.body;
} else {
res = (await client.get(Uri.parse("${source.baseUrl}$url"),
headers: headers))
.body;
List<String> pageUrls = [];
var imagesRes = parseHtml(res)
.selectFirst("div.min-h-screen > div.container > p.items-center")
.innerHtml;
pageUrls = xpath(imagesRes, '//img/@src');
pageUrls.addAll(xpath(imagesRes, '//img/@data-src'));
return pageUrls.where((e) => e.isNotEmpty).toList();
}
final pages = jsonPathToList(res, r"$.content.images[*]", 0);
List<String> pageUrls = [];
for (var u in pages) {
final url = u.replaceAll('"', "");
if (url.startsWith("http")) {
pageUrls.add(url);
} else {
pageUrls.add("${source.apiUrl}/$url");
}
}
return pageUrls;
}
MPages mMangaRes(String res) {
bool hasNextPage = true;
List<MManga> mangaList = [];
List<String> names = [];
List<String> urls = [];
List<String> images = [];
if (res.startsWith("{")) {
for (var a in json.decode(res)["data"]) {
String thumbnail = a["thumbnail"];
if (thumbnail.startsWith("https://")) {
images.add(thumbnail);
} else {
images.add("${source.apiUrl}/cover/$thumbnail");
}
names.add(a["title"]);
final seriesSlug = a["series_slug"];
urls.add("/series/$seriesSlug");
}
} else {
for (var a in json.decode(res)) {
String thumbnail = a["thumbnail"];
if (thumbnail.startsWith("https://")) {
images.add(thumbnail);
} else {
images.add("${source.apiUrl}/cover/$thumbnail");
}
names.add(a["title"]);
final seriesSlug = a["series_slug"];
urls.add("/series/$seriesSlug");
}
hasNextPage = false;
}
for (var i = 0; i < names.length; i++) {
MManga manga = MManga();
manga.name = names[i];
manga.imageUrl = images[i];
manga.link = urls[i];
mangaList.add(manga);
}
return MPages(mangaList, hasNextPage);
}
bool useNewQueryEndpoint(String sourceName) {
List<String> sources = [
"YugenMangas",
"Perf Scan",
"Reaper Scans",
"OmegaScans"
];
return sources.contains(sourceName);
}
bool useslugStrategy(String sourceName) {
List<String> sources = [
"YugenMangas",
"Reaper Scans",
"Perf Scan",
"OmegaScans"
];
return sources.contains(sourceName);
}
}
Map<String, String> getHeader(String url) {
final headers = {'Origin': url, 'Referer': '$url/'};
return headers;
}
HeanCms main(MSource source) {
return HeanCms(source: source);
}

View file

@ -1,22 +0,0 @@
import '../../../../model/source.dart';
import 'src/yugenmangas/yugenmangas.dart';
import 'src/omegascans/omegascans.dart';
import 'src/perfscan/perfscan.dart';
const heancmsVersion = "0.0.75";
const heancmsSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/heancms/heancms.dart";
List<Source> get heancmsSourcesList => _heancmsSourcesList;
List<Source> _heancmsSourcesList = [
//YugenMangas (ES)
yugenmangasSource,
//OmegaScans (EN)
omegascansSource,
//Perf Scan (FR)
perfscanSource,
]
.map((e) => e
..sourceCodeUrl = heancmsSourceCodeUrl
..version = heancmsVersion)
.toList();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -1,16 +0,0 @@
import '../../../../../../model/source.dart';
Source get omegascansSource => _omegascansSource;
Source _omegascansSource = Source(
name: "OmegaScans",
baseUrl: "https://omegascans.org",
apiUrl: "https://api.omegascans.org",
lang: "en",
isNsfw: true,
typeSource: "heancms",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/heancms/src/omegascans/icon.png",
dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
dateFormatLocale: "en",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

View file

@ -1,15 +0,0 @@
import '../../../../../../model/source.dart';
Source get perfscanSource => _perfscanSource;
Source _perfscanSource = Source(
name: "Perf Scan",
baseUrl: "https://perf-scan.fr",
apiUrl: "https://api.perf-scan.fr",
lang: "fr",
typeSource: "heancms",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/heancms/src/perfscan/icon.png",
dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
dateFormatLocale: "en",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,16 +0,0 @@
import '../../../../../../model/source.dart';
Source get yugenmangasSource => _yugenmangasSource;
Source _yugenmangasSource = Source(
name: "YugenMangas",
baseUrl: "https://yugenmangas.lat",
apiUrl: "https://api.yugenmangas.net",
lang: "es",
isNsfw: true,
typeSource: "heancms",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/heancms/src/yugenmangas/icon.png",
dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
dateFormatLocale: "en",
);

View file

@ -168,21 +168,10 @@ class Madara extends MProvider {
"";
final imageElement = document.selectFirst("div.summary_image img");
var image = imageElement?.attr("src") ??
imageElement?.attr("data-src") ??
imageElement?.attr("data-lazy-src") ??
imageElement?.attr("srcset");
if (image != null) {
if (image.contains("dflazy")) {
image = imageElement?.attr("data-src") ??
imageElement?.attr("data-src") ??
imageElement?.attr("data-lazy-src") ??
imageElement?.attr("srcset");
}
if (image != null) {
manga.imageUrl = image;
}
}
manga.imageUrl = imageElement?.attr("data-src") ??
imageElement?.attr("data-lazy-src") ??
imageElement?.attr("srcset") ??
imageElement?.getSrc;
final id = document
.selectFirst("div[id^=manga-chapters-holder]")
@ -228,19 +217,30 @@ class Madara extends MProvider {
@override
Future<List<String>> getPageList(String url) async {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
final pageElement = document.selectFirst(
"div.page-break, li.blocks-gallery-item, .reading-content, .text-left img");
final res = (await client.get(Uri.parse(url)));
final document = parseHtml(res.body);
List<String> imgs = pageElement.select("img").map((e) => e.getSrc).toList();
final pageElements = document.select(
"div.page-break, li.blocks-gallery-item, .reading-content .text-left:not(:has(.blocks-gallery-item)) img");
List<String> imgs = [];
for (var element in pageElements) {
try {
final imgElement = element.selectFirst("img");
final img = imgElement.attr("src") ??
imgElement.attr("data-src") ??
imgElement.attr("data-lazy-src") ??
imgElement.attr("srcset");
imgs.add(img);
} catch (_) {}
}
List<String> pageUrls = [];
if (imgs.length == 1) {
final pagesNumber =
document.selectFirst("#single-pager").select("option").length;
final imgUrl = pageElement.selectFirst("img").getSrc;
final imgUrl = imgs.first;
for (var i = 0; i < pagesNumber; i++) {
final val = i + 1;
if (i.toString().length == 1) {

View file

@ -1,59 +1,31 @@
import '../../../../model/source.dart';
import 'src/firstkissdashmanga/firstkissdashmanga.dart';
import 'src/firstmanhwa/firstmanhwa.dart';
import 'src/manhwaworld/manhwaworld.dart';
import 'src/adultwebtoon/adultwebtoon.dart';
import 'src/akumanotenshi/akumanotenshi.dart';
import 'src/anikiga/anikiga.dart';
import 'src/apollcomics/apollcomics.dart';
import 'src/apolltoons/apolltoons.dart';
import 'src/araznovel/araznovel.dart';
import 'src/arthurscan/arthurscan.dart';
import 'src/astralmanga/astralmanga.dart';
import 'src/asurascansus/asurascansus.dart';
import 'src/bananamanga/bananamanga.dart';
import 'src/barmanga/barmanga.dart';
import 'src/bestmanga/bestmanga.dart';
import 'src/birdtoon/birdtoon.dart';
import 'src/cerisescans/cerisescans.dart';
import 'src/chibimanga/chibimanga.dart';
import 'src/clovermanga/clovermanga.dart';
import 'src/cocorip/cocorip.dart';
import 'src/coffeemanga/coffeemanga.dart';
import 'src/comicznetv2/comicznetv2.dart';
import 'src/decadencescans/decadencescans.dart';
import 'src/dessertscan/dessertscan.dart';
import 'src/doodmanga/doodmanga.dart';
import 'src/elitemanga/elitemanga.dart';
import 'src/emperorscan/emperorscan.dart';
import 'src/evascans/evascans.dart';
import 'src/frscan/frscan.dart';
import 'src/factmanga/factmanga.dart';
import 'src/finalscans/finalscans.dart';
import 'src/flextapescans/flextapescans.dart';
import 'src/freemanga/freemanga.dart';
import 'src/freemangatop/freemangatop.dart';
import 'src/ghostscan/ghostscan.dart';
import 'src/girlslovemanga/girlslovemanga.dart';
import 'src/glorymanga/glorymanga.dart';
import 'src/gooffansub/gooffansub.dart';
import 'src/hm2d/hm2d.dart';
import 'src/harimanga/harimanga.dart';
import 'src/hentaicube/hentaicube.dart';
import 'src/hentaimanga/hentaimanga.dart';
import 'src/hentaiteca/hentaiteca.dart';
import 'src/hentai3z/hentai3z.dart';
import 'src/hentaiwebtoon/hentaiwebtoon.dart';
import 'src/hentaixcomic/hentaixcomic.dart';
import 'src/hentaixyuri/hentaixyuri.dart';
import 'src/hentaizone/hentaizone.dart';
import 'src/hipercool/hipercool.dart';
import 'src/hiperdex/hiperdex.dart';
import 'src/immortalupdates/immortalupdates.dart';
import 'src/imperioscans/imperioscans.dart';
import 'src/inmortalscan/inmortalscan.dart';
import 'src/isekaiscanmanga/isekaiscanmanga.dart';
import 'src/jiangzaitoon/jiangzaitoon.dart';
import 'src/jimanga/jimanga.dart';
import 'src/ksgroupscans/ksgroupscans.dart';
import 'src/kakuseiproject/kakuseiproject.dart';
@ -62,17 +34,11 @@ import 'src/komikchan/komikchan.dart';
import 'src/lhtranslation/lhtranslation.dart';
import 'src/ladyestelarscan/ladyestelarscan.dart';
import 'src/leviatanscans/leviatanscans.dart';
import 'src/linkstartscan/linkstartscan.dart';
import 'src/lolicon/lolicon.dart';
import 'src/luffymanga/luffymanga.dart';
import 'src/maidscan/maidscan.dart';
import 'src/manga18h/manga18h.dart';
import 'src/mangabee/mangabee.dart';
import 'src/mangadistrict/mangadistrict.dart';
import 'src/mangadiyari/mangadiyari.dart';
import 'src/mangafenix/mangafenix.dart';
import 'src/mangagalaxy/mangagalaxy.dart';
import 'src/mangaqueencom/mangaqueencom.dart';
import 'src/mangaread/mangaread.dart';
import 'src/mangatxgg/mangatxgg.dart';
import 'src/mangaweebs/mangaweebs.dart';
@ -80,50 +46,27 @@ import 'src/mangasehri/mangasehri.dart';
import 'src/mangatxunoriginal/mangatxunoriginal.dart';
import 'src/mangaclash/mangaclash.dart';
import 'src/mangafreakonline/mangafreakonline.dart';
import 'src/mangagoyaoi/mangagoyaoi.dart';
import 'src/mangagreat/mangagreat.dart';
import 'src/mangakomi/mangakomi.dart';
import 'src/mangaowlone/mangaowlone.dart';
import 'src/mangapure/mangapure.dart';
import 'src/mangareadorg/mangareadorg.dart';
import 'src/mangarolls/mangarolls.dart';
import 'src/mangarubycom/mangarubycom.dart';
import 'src/mangatyrant/mangatyrant.dart';
import 'src/mangaus/mangaus.dart';
import 'src/mangaland/mangaland.dart';
import 'src/mangaryu/mangaryu.dart';
import 'src/mangasorigines/mangasorigines.dart';
import 'src/mangasushi/mangasushi.dart';
import 'src/mangaxico/mangaxico.dart';
import 'src/mangananquim/mangananquim.dart';
import 'src/manhuaes/manhuaes.dart';
import 'src/manhuazonghe/manhuazonghe.dart';
import 'src/manhuaus/manhuaus.dart';
import 'src/manhuazone/manhuazone.dart';
import 'src/manhwa18app/manhwa18app.dart';
import 'src/manhwa18org/manhwa18org.dart';
import 'src/manhwa68/manhwa68.dart';
import 'src/manhwaclan/manhwaclan.dart';
import 'src/manhwamanhua/manhwamanhua.dart';
import 'src/manhwanew/manhwanew.dart';
import 'src/manhwafull/manhwafull.dart';
import 'src/manhwahentaime/manhwahentaime.dart';
import 'src/mantrazscan/mantrazscan.dart';
import 'src/milftoon/milftoon.dart';
import 'src/momonohanascan/momonohanascan.dart';
import 'src/monarcamanga/monarcamanga.dart';
import 'src/moonwitchinlove/moonwitchinlove.dart';
import 'src/moonloversscan/moonloversscan.dart';
import 'src/murimscan/murimscan.dart';
import 'src/nekopostco/nekopostco.dart';
import 'src/nijitranslations/nijitranslations.dart';
import 'src/novelcrow/novelcrow.dart';
import 'src/pantheonscan/pantheonscan.dart';
import 'src/pawmanga/pawmanga.dart';
import 'src/pinkseaunicorn/pinkseaunicorn.dart';
import 'src/pojokmanga/pojokmanga.dart';
import 'src/portalyaoi/portalyaoi.dart';
import 'src/prismahentais/prismahentais.dart';
import 'src/projetoscanlator/projetoscanlator.dart';
import 'src/mangasoverall/mangasoverall.dart';
import 'src/ragnarokscanlation/ragnarokscanlation.dart';
@ -142,29 +85,107 @@ import 'src/shadowtrad/shadowtrad.dart';
import 'src/shibamanga/shibamanga.dart';
import 'src/sinensis/sinensis.dart';
import 'src/sweettimescan/sweettimescan.dart';
import 'src/taberumangas/taberumangas.dart';
import 'src/tankouhentai/tankouhentai.dart';
import 'src/tatakaescan/tatakaescan.dart';
import 'src/taurusfansub/taurusfansub.dart';
import 'src/thebeginningaftertheend/thebeginningaftertheend.dart';
import 'src/toonizy/toonizy.dart';
import 'src/tortugaceviri/tortugaceviri.dart';
import 'src/valkyriescan/valkyriescan.dart';
import 'src/vermanhwas/vermanhwas.dart';
import 'src/vinmanga/vinmanga.dart';
import 'src/wickedwitchscan/wickedwitchscan.dart';
import 'src/winterscan/winterscan.dart';
import 'src/wonderlandscan/wonderlandscan.dart';
import 'src/yanpfansub/yanpfansub.dart';
import 'src/yaoicomics/yaoicomics.dart';
import 'src/yuriverso/yuriverso.dart';
import 'src/zeroscan/zeroscan.dart';
import 'src/falconmanga/falconmanga.dart';
import 'src/comicarab/comicarab.dart';
import 'src/manga3asq/manga3asq.dart';
import 'src/bakamh/bakamh.dart';
import 'src/grabberzone/grabberzone.dart';
import 'src/gatemanga/gatemanga.dart';
import 'src/gmangasite/gmangasite.dart';
import 'src/mangalink/mangalink.dart';
import 'src/mangalionz/mangalionz.dart';
import 'src/mangarose/mangarose.dart';
import 'src/mangaspark/mangaspark.dart';
import 'src/mangastarz/mangastarz.dart';
import 'src/mangatime/mangatime.dart';
import 'src/olaoe/olaoe.dart';
import 'src/rocksmanga/rocksmanga.dart';
import 'src/dragontea/dragontea.dart';
import 'src/globalbloging/globalbloging.dart';
import 'src/manga347/manga347.dart';
import 'src/mangaeffect/mangaeffect.dart';
import 'src/mangafastcom/mangafastcom.dart';
import 'src/mangaleveling/mangaleveling.dart';
import 'src/neatmanga/neatmanga.dart';
import 'src/nvmanga/nvmanga.dart';
import 'src/pmscans/pmscans.dart';
import 'src/readmanhua/readmanhua.dart';
import 'src/stonescape/stonescape.dart';
import 'src/tappytoonnet/tappytoonnet.dart';
import 'src/zinmanganet/zinmanganet.dart';
import 'src/bokugentranslation/bokugentranslation.dart';
import 'src/daprob/daprob.dart';
import 'src/demanhuas/demanhuas.dart';
import 'src/herenscan/herenscan.dart';
import 'src/housemangas/housemangas.dart';
import 'src/infrafandub/infrafandub.dart';
import 'src/inmoralnofansub/inmoralnofansub.dart';
import 'src/jeazscans/jeazscans.dart';
import 'src/jobsibe/jobsibe.dart';
import 'src/legendsnofansub/legendsnofansub.dart';
import 'src/mangacrab/mangacrab.dart';
import 'src/mangasnosekai/mangasnosekai.dart';
import 'src/manhuaonline/manhuaonline.dart';
import 'src/mhscans/mhscans.dart';
import 'src/noblessetranslations/noblessetranslations.dart';
import 'src/princediciones/princediciones.dart';
import 'src/sapphirescan/sapphirescan.dart';
import 'src/tresdaosscan/tresdaosscan.dart';
import 'src/unitoon/unitoon.dart';
import 'src/mangascantrad/mangascantrad.dart';
import 'src/mangasoriginesfr/mangasoriginesfr.dart';
import 'src/raijinscans/raijinscans.dart';
import 'src/reaperscans/reaperscans.dart';
import 'src/softepsilonscan/softepsilonscan.dart';
import 'src/hwago/hwago.dart';
import 'src/klikmanga/klikmanga.dart';
import 'src/komikuzan/komikuzan.dart';
import 'src/mgkomik/mgkomik.dart';
import 'src/siimanga/siimanga.dart';
import 'src/yubikiri/yubikiri.dart';
import 'src/mangahona/mangahona.dart';
import 'src/alonescanlator/alonescanlator.dart';
import 'src/borutoexplorer/borutoexplorer.dart';
import 'src/crystalcomics/crystalcomics.dart';
import 'src/fayscans/fayscans.dart';
import 'src/galinhasamuraiscan/galinhasamuraiscan.dart';
import 'src/hikariganai/hikariganai.dart';
import 'src/imperiodabritannia/imperiodabritannia.dart';
import 'src/leitordemanga/leitordemanga.dart';
import 'src/lscans/lscans.dart';
import 'src/lunarscan/lunarscan.dart';
import 'src/minitwoscan/minitwoscan.dart';
import 'src/nexoscans/nexoscans.dart';
import 'src/ninjascan/ninjascan.dart';
import 'src/onepieceteca/onepieceteca.dart';
import 'src/prismascans/prismascans.dart';
import 'src/sussyscan/sussyscan.dart';
import 'src/kingsmanga/kingsmanga.dart';
import 'src/mangadeemak/mangadeemak.dart';
import 'src/manhuabug/manhuabug.dart';
import 'src/manhuathai/manhuathai.dart';
import 'src/manhwabreakup/manhwabreakup.dart';
import 'src/atikrost/atikrost.dart';
import 'src/diamondfansub/diamondfansub.dart';
import 'src/garciamanga/garciamanga.dart';
import 'src/guncelmanga/guncelmanga.dart';
import 'src/lilyumfansub/lilyumfansub.dart';
import 'src/mangagezgini/mangagezgini.dart';
import 'src/mangakeyfi/mangakeyfi.dart';
import 'src/mangaoku/mangaoku.dart';
import 'src/mangawow/mangawow.dart';
import 'src/merlinscans/merlinscans.dart';
import 'src/ruyamanga/ruyamanga.dart';
import 'src/turkcemangaoku/turkcemangaoku.dart';
import 'src/webtoonhatti/webtoonhatti.dart';
const madaraVersion = "0.0.95";
const madaraVersion = "0.1.15";
const madaraSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/madara.dart";
@ -172,20 +193,12 @@ List<Source> get madaraSourcesList => _madaraSourcesList;
List<Source> _madaraSourcesList = [
//1st Kiss-Manga (unoriginal) (EN)
firstkissdashmangaSource,
//1st Manhwa (EN)
firstmanhwaSource,
//AQUA Scans (EN)
manhwaworldSource,
//Adult Webtoon (EN)
adultwebtoonSource,
//Akuma no Tenshi (PT-BR)
akumanotenshiSource,
//Anikiga (TR)
anikigaSource,
//ApollComics (ES)
apollcomicsSource,
//Apolltoons (ES)
apolltoonsSource,
//ArazNovel (TR)
araznovelSource,
//Arthur Scan (PT-BR)
@ -194,16 +207,10 @@ List<Source> _madaraSourcesList = [
astralmangaSource,
//Asura Scans.us (unoriginal) (EN)
asurascansusSource,
//Banana Manga (EN)
bananamangaSource,
//BarManga (ES)
barmangaSource,
//BestManga (RU)
bestmangaSource,
//BirdToon (ID)
birdtoonSource,
//Cerise Scan (PT-BR)
cerisescansSource,
//Chibi Manga (EN)
chibimangaSource,
//Clover Manga (TR)
@ -212,12 +219,6 @@ List<Source> _madaraSourcesList = [
cocoripSource,
//Coffee Manga (EN)
coffeemangaSource,
//Comicz.net v2 (ALL)
comicznetv2Source,
//Decadence Scans (EN)
decadencescansSource,
//Dessert Scan (PT-BR)
dessertscanSource,
//Doodmanga (TH)
doodmangaSource,
//Elite Manga (EN)
@ -230,46 +231,12 @@ List<Source> _madaraSourcesList = [
frscanSource,
//FactManga (EN)
factmangaSource,
//Final Scans (PT-BR)
finalscansSource,
//Flex Tape Scans (EN)
flextapescansSource,
//Free Manga (EN)
freemangaSource,
//FreeMangaTop (EN)
freemangatopSource,
//Ghost Scan (PT-BR)
ghostscanSource,
//Girls Love Manga! (EN)
girlslovemangaSource,
//Glory Manga (TR)
glorymangaSource,
//Goof Fansub (PT-BR)
gooffansubSource,
//HM2D (EN)
hm2dSource,
//Harimanga (EN)
harimangaSource,
//Hentai CB (VI)
hentaicubeSource,
//Hentai Manga (EN)
hentaimangaSource,
//Hentai Teca (PT-BR)
hentaitecaSource,
//Hentai3z (EN)
hentai3zSource,
//HentaiWebtoon (EN)
hentaiwebtoonSource,
//HentaiXComic (EN)
hentaixcomicSource,
//HentaiXYuri (EN)
hentaixyuriSource,
//HentaiZone (FR)
hentaizoneSource,
//HipercooL (PT-BR)
hipercoolSource,
//Hiperdex (EN)
hiperdexSource,
//Immortal Updates (EN)
immortalupdatesSource,
//Império Scans (PT-BR)
@ -278,8 +245,6 @@ List<Source> _madaraSourcesList = [
inmortalscanSource,
//IsekaiScanManga (unoriginal) (EN)
isekaiscanmangaSource,
//Jiangzaitoon (TR)
jiangzaitoonSource,
//Jimanga (EN)
jimangaSource,
//KSGroupScans (EN)
@ -296,28 +261,16 @@ List<Source> _madaraSourcesList = [
ladyestelarscanSource,
//Leviatan Scans (EN)
leviatanscansSource,
//Link Start Scan (PT-BR)
linkstartscanSource,
//Lolicon (EN)
loliconSource,
//Luffy Manga (EN)
luffymangaSource,
//Maid Scan (PT-BR)
maidscanSource,
//Manga 18h (EN)
manga18hSource,
//Manga Bee (EN)
mangabeeSource,
//Manga District (EN)
mangadistrictSource,
//Manga Diyari (TR)
mangadiyariSource,
//Manga Fenix (ES)
mangafenixSource,
//Manga Galaxy (EN)
mangagalaxySource,
//Manga Queen.com (EN)
mangaqueencomSource,
//Manga Read (EN)
mangareadSource,
//Manga Tx.gg (unoriginal) (EN)
@ -332,94 +285,48 @@ List<Source> _madaraSourcesList = [
mangaclashSource,
//MangaFreak.online (EN)
mangafreakonlineSource,
//MangaGo Yaoi (EN)
mangagoyaoiSource,
//MangaGreat (EN)
mangagreatSource,
//MangaKomi (EN)
mangakomiSource,
//MangaOwl.one (unoriginal) (EN)
mangaowloneSource,
//MangaPure (EN)
mangapureSource,
//MangaRead.org (EN)
mangareadorgSource,
//MangaRolls (EN)
mangarollsSource,
//MangaRuby.com (EN)
mangarubycomSource,
//MangaTyrant (EN)
mangatyrantSource,
//MangaUS (EN)
mangausSource,
//Mangaland (ES)
mangalandSource,
//Mangaryu (EN)
mangaryuSource,
//Mangas Origines (FR)
mangasoriginesSource,
//Mangasushi (EN)
mangasushiSource,
//Mangaxico (ES)
mangaxicoSource,
//Mangá Nanquim (PT-BR)
mangananquimSource,
//Manhua ES (EN)
manhuaesSource,
//Manhua Zonghe (EN)
manhuazongheSource,
//ManhuaUS (EN)
manhuausSource,
//ManhuaZone (EN)
manhuazoneSource,
//Manhwa18.app (EN)
manhwa18appSource,
//Manhwa18.org (EN)
manhwa18orgSource,
//Manhwa68 (EN)
manhwa68Source,
//ManhwaClan (EN)
manhwaclanSource,
//ManhwaManhua (EN)
manhwamanhuaSource,
//ManhwaNew (EN)
manhwanewSource,
//Manhwafull (EN)
manhwafullSource,
//Manhwahentai.me (EN)
manhwahentaimeSource,
//Mantraz Scan (ES)
mantrazscanSource,
//Milftoon (EN)
milftoonSource,
//Momo no Hana Scan (PT-BR)
momonohanascanSource,
//MonarcaManga (ES)
monarcamangaSource,
//Moon Witch In Love (PT-BR)
moonwitchinloveSource,
//MoonLovers Scan (PT-BR)
moonloversscanSource,
//MurimScan (EN)
murimscanSource,
//NekoPost.co (unoriginal) (TH)
nekopostcoSource,
//Niji Translations (AR)
nijitranslationsSource,
//NovelCrow (EN)
novelcrowSource,
//Pantheon Scan (FR)
pantheonscanSource,
//Paw Manga (EN)
pawmangaSource,
//Pink Sea Unicorn (PT-BR)
pinkseaunicornSource,
//Pojok Manga (ID)
pojokmangaSource,
//Portal Yaoi (PT-BR)
portalyaoiSource,
//Prisma Hentais (PT-BR)
prismahentaisSource,
//Projeto Scanlator (PT-BR)
projetoscanlatorSource,
//ROG Mangás (PT-BR)
@ -456,50 +363,215 @@ List<Source> _madaraSourcesList = [
sinensisSource,
//Sweet Time Scan (PT-BR)
sweettimescanSource,
//Taberu Mangás (PT-BR)
taberumangasSource,
//Tankou Hentai (PT-BR)
tankouhentaiSource,
//Tatakae Scan (PT-BR)
tatakaescanSource,
//Taurus Fansub (ES)
taurusfansubSource,
//The Beginning After The End (FR)
thebeginningaftertheendSource,
//Toonizy (EN)
toonizySource,
//Tortuga Ceviri (TR)
tortugaceviriSource,
//Valkyrie Scan (PT-BR)
valkyriescanSource,
//Ver Manhwas (ES)
vermanhwasSource,
//VinManga (EN)
vinmangaSource,
//Wicked Witch Scan (PT-BR)
wickedwitchscanSource,
//Winter Scan (PT-BR)
winterscanSource,
//Wonderland Scan (PT-BR)
wonderlandscanSource,
//YANP Fansub (PT-BR)
yanpfansubSource,
//Yaoi Comics (PT-BR)
yaoicomicsSource,
//Yuri Verso (PT-BR)
yuriversoSource,
//Zero Scan (PT-BR)
zeroscanSource,
//فالكون مانجا (AR)
falconmangaSource,
//كوميك العرب (AR)
comicarabSource,
//مانجا العاشق (AR)
manga3asqSource,
// (ZH)
bakamhSource
//Grabber Zone (ALL)
grabberzoneSource,
//Gatemanga (AR)
gatemangaSource,
//GMANGA (unoriginal) (AR)
gmangasiteSource,
//مانجا لينك (AR)
mangalinkSource,
//MangaLionz (AR)
mangalionzSource,
//Manga Rose (AR)
mangaroseSource,
//MangaSpark (AR)
mangasparkSource,
//Manga Starz (AR)
mangastarzSource,
//Manga Time (AR)
mangatimeSource,
//Olaoe (AR)
olaoeSource,
//Rocks Manga (AR)
rocksmangaSource,
//DragonTea (EN)
dragonteaSource,
//Global Bloging (EN)
globalblogingSource,
//Manga347 (EN)
manga347Source,
//MangaEffect (EN)
mangaeffectSource,
//Manga-fast.com (EN)
mangafastcomSource,
//Manga Leveling (EN)
mangalevelingSource,
//NeatManga (EN)
neatmangaSource,
//NvManga (EN)
nvmangaSource,
//PMScans (EN)
pmscansSource,
//ReadManhua (EN)
readmanhuaSource,
//StoneScape (EN)
stonescapeSource,
//TappyToon.Net (EN)
tappytoonnetSource,
//Zinmanga.net (EN)
zinmanganetSource,
//BokugenTranslation (ES)
bokugentranslationSource,
//DapRob (ES)
daprobSource,
//DeManhuas (ES)
demanhuasSource,
//HerenScan (ES)
herenscanSource,
//HouseMangas (ES)
housemangasSource,
//InfraFandub (ES)
infrafandubSource,
//Inmoral No Fansub (ES)
inmoralnofansubSource,
//JeazScans (ES)
jeazscansSource,
//Jobsibe (ES)
jobsibeSource,
//LegnMangas (ES)
legendsnofansubSource,
//Manga Crab (ES)
mangacrabSource,
//MMFenix (ES)
mangafenixSource,
//Mangas No Sekai (ES)
mangasnosekaiSource,
//Manhua Online (ES)
manhuaonlineSource,
//MHScans (ES)
mhscansSource,
//Visormonarca (ES)
monarcamangaSource,
//Noblesse Translations (ES)
noblessetranslationsSource,
//Prince Ediciones (ES)
princedicionesSource,
//SapphireScan (ES)
sapphirescanSource,
//Tres Daos Scan (ES)
tresdaosscanSource,
//Unitoon (ES)
unitoonSource,
//Manga-Scantrad (FR)
mangascantradSource,
//Mangas-Origines.fr (FR)
mangasoriginesfrSource,
//Raijin Scans (FR)
raijinscansSource,
//Reaper Scans (EN)
reaperscansSource,
//Soft Epsilon Scan (FR)
softepsilonscanSource,
//Hwago (ID)
hwagoSource,
//KlikManga (ID)
klikmangaSource,
//Komikuzan (ID)
komikuzanSource,
//MG Komik (ID)
mgkomikSource,
//Siimanga (ID)
siimangaSource,
//Yubikiri (ID)
yubikiriSource,
//MangaHoNa (PL)
mangahonaSource,
//Alone Scanlator (PT-BR)
alonescanlatorSource,
//Boruto Explorer (PT-BR)
borutoexplorerSource,
//Crystal Comics (PT-BR)
crystalcomicsSource,
//Fay Scans (PT-BR)
fayscansSource,
//Galinha Samurai Scan (PT-BR)
galinhasamuraiscanSource,
//Hikari Ga Nai (PT-BR)
hikariganaiSource,
//Sagrado Império da Britannia (PT-BR)
imperiodabritanniaSource,
//Neroxus (PT-BR)
imperioscansSource,
//Leitor de Mangá (PT-BR)
leitordemangaSource,
//L Scans (PT-BR)
lscansSource,
//Lunar Scan (PT-BR)
lunarscanSource,
//MiniTwo Scan (PT-BR)
minitwoscanSource,
//Nexo Scans (PT-BR)
nexoscansSource,
//Ninja Scan (PT-BR)
ninjascanSource,
//One Piece TECA (PT-BR)
onepiecetecaSource,
//Demon Sect (PT-BR)
prismascansSource,
//Sussy Scan (PT-BR)
sussyscanSource,
//Kings-Manga (TH)
kingsmangaSource,
//MangaDeemak (TH)
mangadeemakSource,
//ManhuaBug (TH)
manhuabugSource,
//ManhuaThai (TH)
manhuathaiSource,
//ManhwaBreakup (TH)
manhwabreakupSource,
//Atikrost (TR)
atikrostSource,
//DiamondFansub (TR)
diamondfansubSource,
//ManWe (TR)
evascansSource,
//Garcia Manga (TR)
garciamangaSource,
//GuncelManga (TR)
guncelmangaSource,
//LilyumFansub (TR)
lilyumfansubSource,
//MangaGezgini (TR)
mangagezginiSource,
//Manga Keyfi (TR)
mangakeyfiSource,
//Manga Oku (TR)
mangaokuSource,
//MangaWOW (TR)
mangawowSource,
//Merlin Scans (TR)
merlinscansSource,
//Rüya Manga (TR)
ruyamangaSource,
//Türkçe Manga Oku (TR)
turkcemangaokuSource,
//Webtoon Hatti (TR)
webtoonhattiSource,
]
.map((e) => e
..itemType = ItemType.manga
..sourceCodeUrl = madaraSourceCodeUrl
..version = madaraVersion)
.toList();

View file

@ -1,14 +0,0 @@
import '../../../../../../model/source.dart';
Source get adultwebtoonSource => _adultwebtoonSource;
Source _adultwebtoonSource = Source(
name: "Adult Webtoon",
baseUrl: "https://adultwebtoon.com",
lang: "en",
isNsfw:true,
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/adultwebtoon/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -0,0 +1,13 @@
import '../../../../../../model/source.dart';
Source get alonescanlatorSource => _alonescanlatorSource;
Source _alonescanlatorSource = Source(
name: "Alone Scanlator",
baseUrl: "https://alonescanlator.com.br",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/alonescanlator/icon.png",
dateFormat:"dd/MM/yyyy",
dateFormatLocale:"pt-br"
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

@ -1,14 +0,0 @@
import '../../../../../../model/source.dart';
Source get apollcomicsSource => _apollcomicsSource;
Source _apollcomicsSource = Source(
name: "ApollComics",
baseUrl: "https://apollcomics.xyz",
lang: "es",
isNsfw:true,
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/apollcomics/icon.png",
dateFormat:"dd MMMM, yyyy",
dateFormatLocale:"es",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -1,14 +0,0 @@
import '../../../../../../model/source.dart';
Source get apolltoonsSource => _apolltoonsSource;
Source _apolltoonsSource = Source(
name: "Apolltoons",
baseUrl: "https://apolltoons.xyz",
lang: "es",
isNsfw:true,
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/apolltoons/icon.png",
dateFormat:"dd MMMMM, yyyy",
dateFormatLocale:"es",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -0,0 +1,13 @@
import '../../../../../../model/source.dart';
Source get atikrostSource => _atikrostSource;
Source _atikrostSource = Source(
name: "Atikrost",
baseUrl: "https://www.atikrost.com",
lang: "tr",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/atikrost/icon.png",
dateFormat:"d MMMM yyyy",
dateFormatLocale:"tr"
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,14 +0,0 @@
import '../../../../../../model/source.dart';
Source get bakamhSource => _bakamhSource;
Source _bakamhSource = Source(
name: "巴卡漫画",
baseUrl: "https://bakamh.com",
lang: "zh",
isNsfw:true,
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/bakamh/icon.png",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -1,14 +0,0 @@
import '../../../../../../model/source.dart';
Source get bananamangaSource => _bananamangaSource;
Source _bananamangaSource = Source(
name: "Banana Manga",
baseUrl: "https://bananamanga.net",
lang: "en",
isNsfw:true,
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/bananamanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -1,14 +0,0 @@
import '../../../../../../model/source.dart';
Source get birdtoonSource => _birdtoonSource;
Source _birdtoonSource = Source(
name: "BirdToon",
baseUrl: "https://birdtoon.net",
lang: "id",
isNsfw:true,
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/birdtoon/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -0,0 +1,13 @@
import '../../../../../../model/source.dart';
Source get bokugentranslationSource => _bokugentranslationSource;
Source _bokugentranslationSource = Source(
name: "BokugenTranslation",
baseUrl: "https://bokugents.com",
lang: "es",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/bokugentranslation/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"es"
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Some files were not shown because too many files have changed in this diff Show more