From 5c5a8d142fd87db75a55689177314b1891334ccf Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Wed, 10 Aug 2022 01:00:08 +0200 Subject: [PATCH] Ported over all movie providers (some disabled) --- .../build.gradle.kts | 4 +- .../src/main/AndroidManifest.xml | 2 +- .../kotlin/com/lagradost/AkwamProvider.kt | 224 ++++++ .../com/lagradost/AkwamProviderPlugin.kt | 14 + AllMoviesForYouProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/AllMoviesForYouProvider.kt | 206 +++++ .../AllMoviesForYouProviderPlugin.kt | 14 + AltadefinizioneProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/AltadefinizioneProvider.kt | 160 ++++ .../AltadefinizioneProviderPlugin.kt | 14 + AsiaFlixProvider/build.gradle.kts | 22 + AsiaFlixProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/AsiaFlixProvider.kt | 198 +++++ .../com/lagradost/AsiaFlixProviderPlugin.kt | 14 + AsianLoadProvider/build.gradle.kts | 25 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/AsianLoadProvider.kt | 25 + .../com/lagradost/AsianLoadProviderPlugin.kt | 14 + BflixProvider/build.gradle.kts | 22 + BflixProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/BflixProvider.kt | 300 +++++++ .../com/lagradost/BflixProviderPlugin.kt | 14 + CinecalidadProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/CinecalidadProvider.kt | 258 ++++++ .../lagradost/CinecalidadProviderPlugin.kt | 14 + CuevanaProvider/build.gradle.kts | 22 + CuevanaProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/CuevanaProvider.kt | 324 ++++++++ .../com/lagradost/CuevanaProviderPlugin.kt | 14 + DopeboxProvider/build.gradle.kts | 25 + DopeboxProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/DopeboxProvider.kt | 6 + .../com/lagradost/DopeboxProviderPlugin.kt | 14 + DoramasYTProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/DoramasYTProvider.kt | 155 ++++ .../com/lagradost/DoramasYTProviderPlugin.kt | 14 + DramaSeeProvider/build.gradle.kts | 22 + DramaSeeProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/DramaSeeProvider.kt | 217 +++++ .../com/lagradost/DramaSeeProviderPlugin.kt | 14 + DramaidProvider/build.gradle.kts | 22 + DramaidProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/DramaidProvider.kt | 213 +++++ .../com/lagradost/DramaidProviderPlugin.kt | 14 + DubokuProvider/build.gradle.kts | 22 + DubokuProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/DubokuProvider.kt | 133 ++++ .../com/lagradost/DubokuProviderPlugin.kt | 14 + EgyBestProvider/build.gradle.kts | 22 + EgyBestProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/EgyBestProvider.kt | 237 ++++++ .../com/lagradost/EgyBestProviderPlugin.kt | 14 + ElifilmsProvider/build.gradle.kts | 22 + ElifilmsProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/ElifilmsProvider.kt | 94 +++ .../com/lagradost/ElifilmsProviderPlugin.kt | 14 + .../build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../EntrepeliculasyseriesProvider.kt | 177 +++++ .../EntrepeliculasyseriesProviderPlugin.kt | 14 + EstrenosDoramasProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/EstrenosDoramasProvider.kt | 286 +++++++ .../EstrenosDoramasProviderPlugin.kt | 14 + .../kotlin/com/example/ExampleProvider.kt | 21 - FaselHDProvider/build.gradle.kts | 22 + FaselHDProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/FaselHDProvider.kt | 163 ++++ .../com/lagradost/FaselHDProviderPlugin.kt | 14 + FilmanProvider/build.gradle.kts | 22 + FilmanProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/FilmanProvider.kt | 149 ++++ .../com/lagradost/FilmanProviderPlugin.kt | 14 + FilmpertuttiProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/FilmpertuttiProvider.kt | 193 +++++ .../lagradost/FilmpertuttiProviderPlugin.kt | 14 + FmoviesToProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/FmoviesToProvider.kt | 6 + .../com/lagradost/FmoviesToProviderPlugin.kt | 14 + FrenchStreamProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/FrenchStreamProvider.kt | 273 +++++++ .../lagradost/FrenchStreamProviderPlugin.kt | 14 + HDMProvider/build.gradle.kts | 22 + HDMProvider/src/main/AndroidManifest.xml | 2 + .../main/kotlin/com/lagradost/HDMProvider.kt | 116 +++ .../kotlin/com/lagradost/HDMProviderPlugin.kt | 14 + HDMovie5/build.gradle.kts | 22 + HDMovie5/src/main/AndroidManifest.xml | 2 + .../src/main/kotlin/com/lagradost/HDMovie5.kt | 154 ++++ .../kotlin/com/lagradost/HDMovie5Plugin.kt | 7 +- HDTodayProvider/build.gradle.kts | 22 + HDTodayProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/HDTodayProvider.kt | 6 + .../com/lagradost/HDTodayProviderPlugin.kt | 14 + HDrezkaProvider/build.gradle.kts | 22 + HDrezkaProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/HDrezkaProvider.kt | 408 ++++++++++ .../com/lagradost/HDrezkaProviderPlugin.kt | 14 + IHaveNoTvProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/IHaveNoTvProvider.kt | 222 ++++++ .../com/lagradost/IHaveNoTvProviderPlugin.kt | 14 + IdlixProvider/build.gradle.kts | 22 + IdlixProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/IdlixProvider.kt | 385 +++++++++ .../com/lagradost/IdlixProviderPlugin.kt | 14 + .../build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../IlGenioDelloStreamingProvider.kt | 181 +++++ .../IlGenioDelloStreamingProviderPlugin.kt | 14 + KdramaHoodProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/KdramaHoodProvider.kt | 296 +++++++ .../com/lagradost/KdramaHoodProviderPlugin.kt | 14 + KisskhProvider/build.gradle.kts | 22 + KisskhProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/KisskhProvider.kt | 208 +++++ .../com/lagradost/KisskhProviderPlugin.kt | 14 + LayarKacaProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/LayarKacaProvider.kt | 176 ++++ .../com/lagradost/LayarKacaProviderPlugin.kt | 14 + MeloMovieProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/MeloMovieProvider.kt | 195 +++++ .../com/lagradost/MeloMovieProviderPlugin.kt | 14 + MultiplexProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/MultiplexProvider.kt | 188 +++++ .../com/lagradost/MultiplexProviderPlugin.kt | 14 + MyCimaProvider/build.gradle.kts | 22 + MyCimaProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/MyCimaProvider.kt | 327 ++++++++ .../com/lagradost/MyCimaProviderPlugin.kt | 14 + NginxProvider/build.gradle.kts | 22 + NginxProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/NginxProvider.kt | 286 +++++++ .../com/lagradost/NginxProviderPlugin.kt | 14 + OlgplyProvider/build.gradle.kts | 22 + OlgplyProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/OlgplyProvider.kt | 111 +++ .../com/lagradost/OlgplyProviderPlugin.kt | 14 + OpenVidsProvider/build.gradle.kts | 22 + OpenVidsProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/OpenVidsProvider.kt | 133 ++++ .../com/lagradost/OpenVidsProviderPlugin.kt | 14 + PeliSmartProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/PeliSmartProvider.kt | 160 ++++ .../com/lagradost/PeliSmartProviderPlugin.kt | 14 + PelisflixProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/PelisflixProvider.kt | 231 ++++++ .../com/lagradost/PelisflixProviderPlugin.kt | 14 + PelisplusHDProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/PelisplusHDProvider.kt | 173 ++++ .../lagradost/PelisplusHDProviderPlugin.kt | 14 + PelisplusProvider/build.gradle.kts | 25 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/PelisplusProvider.kt | 26 + .../com/lagradost/PelisplusProviderPlugin.kt | 14 + PelisplusProviderTemplate/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../lagradost/PelisplusProviderTemplate.kt | 260 ++++++ .../PelisplusProviderTemplatePlugin.kt | 14 + PhimmoichillProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/PhimmoichillProvider.kt | 222 ++++++ .../lagradost/PhimmoichillProviderPlugin.kt | 14 + PinoyHDXyzProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/PinoyHDXyzProvider.kt | 237 ++++++ .../com/lagradost/PinoyHDXyzProviderPlugin.kt | 14 + PinoyMoviePediaProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/PinoyMoviePediaProvider.kt | 239 ++++++ .../PinoyMoviePediaProviderPlugin.kt | 14 + PinoyMoviesEsProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/PinoyMoviesEsProvider.kt | 252 ++++++ .../lagradost/PinoyMoviesEsProviderPlugin.kt | 14 + RebahinProvider/build.gradle.kts | 22 + RebahinProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/RebahinProvider.kt | 324 ++++++++ .../com/lagradost/RebahinProviderPlugin.kt | 14 + SeriesflixProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/SeriesflixProvider.kt | 226 ++++++ .../com/lagradost/SeriesflixProviderPlugin.kt | 14 + SflixProProvider/build.gradle.kts | 22 + SflixProProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/SflixProProvider.kt | 6 + .../com/lagradost/SflixProProviderPlugin.kt | 14 + SflixProvider/build.gradle.kts | 22 + SflixProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/SflixProvider.kt | 749 ++++++++++++++++++ .../com/lagradost/SflixProviderPlugin.kt | 14 + SoaptwoDayProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/SoaptwoDayProvider.kt | 263 ++++++ .../com/lagradost/SoaptwoDayProviderPlugin.kt | 14 + SolarmovieProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/SolarmovieProvider.kt | 6 + .../com/lagradost/SolarmovieProviderPlugin.kt | 14 + StreamingcommunityProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../lagradost/StreamingcommunityProvider.kt | 438 ++++++++++ .../StreamingcommunityProviderPlugin.kt | 14 + SuperStream/build.gradle.kts | 22 + SuperStream/src/main/AndroidManifest.xml | 2 + .../main/kotlin/com/lagradost/SuperStream.kt | 663 ++++++++++++++++ .../kotlin/com/lagradost/SuperStreamPlugin.kt | 14 + TantiFilmProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/TantiFilmProvider.kt | 234 ++++++ .../com/lagradost/TantiFilmProviderPlugin.kt | 14 + TheFlixToProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/TheFlixToProvider.kt | 604 ++++++++++++++ .../com/lagradost/TheFlixToProviderPlugin.kt | 14 + TrailersTwoProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/TrailersTwoProvider.kt | 319 ++++++++ .../lagradost/TrailersTwoProviderPlugin.kt | 14 + TwoEmbedProvider/build.gradle.kts | 22 + TwoEmbedProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/TwoEmbedProvider.kt | 79 ++ .../com/lagradost/TwoEmbedProviderPlugin.kt | 14 + UakinoProvider/build.gradle.kts | 22 + UakinoProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/UakinoProvider.kt | 181 +++++ .../com/lagradost/UakinoProviderPlugin.kt | 14 + VMoveeProvider/build.gradle.kts | 22 + VMoveeProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/VMoveeProvider.kt | 125 +++ .../com/lagradost/VMoveeProviderPlugin.kt | 14 + VfFilmProvider/build.gradle.kts | 22 + VfFilmProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/VfFilmProvider.kt | 122 +++ .../com/lagradost/VfFilmProviderPlugin.kt | 14 + VfSerieProvider/build.gradle.kts | 22 + VfSerieProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/VfSerieProvider.kt | 179 +++++ .../com/lagradost/VfSerieProviderPlugin.kt | 14 + VidEmbedProvider/build.gradle.kts | 22 + VidEmbedProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/VidEmbedProvider.kt | 30 + .../com/lagradost/VidEmbedProviderPlugin.kt | 14 + VidSrcProvider/build.gradle.kts | 22 + VidSrcProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/VidSrcProvider.kt | 51 ++ .../com/lagradost/VidSrcProviderPlugin.kt | 14 + VidstreamProviderTemplate/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../lagradost/VidstreamProviderTemplate.kt | 337 ++++++++ .../VidstreamProviderTemplatePlugin.kt | 14 + WatchAsianProvider/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 2 + .../com/lagradost/WatchAsianProvider.kt | 250 ++++++ .../com/lagradost/WatchAsianProviderPlugin.kt | 14 + XcineProvider/build.gradle.kts | 22 + XcineProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/XcineProvider.kt | 256 ++++++ .../com/lagradost/XcineProviderPlugin.kt | 14 + YomoviesProvider/build.gradle.kts | 22 + YomoviesProvider/src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/YomoviesProvider.kt | 161 ++++ .../com/lagradost/YomoviesProviderPlugin.kt | 14 + build.gradle.kts | 12 +- gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 57 +- gradlew.bat | 45 +- settings.gradle.kts | 70 +- 283 files changed, 17532 insertions(+), 76 deletions(-) rename {ExampleProvider => AkwamProvider}/build.gradle.kts (84%) rename {ExampleProvider => AkwamProvider}/src/main/AndroidManifest.xml (52%) create mode 100644 AkwamProvider/src/main/kotlin/com/lagradost/AkwamProvider.kt create mode 100644 AkwamProvider/src/main/kotlin/com/lagradost/AkwamProviderPlugin.kt create mode 100644 AllMoviesForYouProvider/build.gradle.kts create mode 100644 AllMoviesForYouProvider/src/main/AndroidManifest.xml create mode 100644 AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProvider.kt create mode 100644 AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProviderPlugin.kt create mode 100644 AltadefinizioneProvider/build.gradle.kts create mode 100644 AltadefinizioneProvider/src/main/AndroidManifest.xml create mode 100644 AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProvider.kt create mode 100644 AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProviderPlugin.kt create mode 100644 AsiaFlixProvider/build.gradle.kts create mode 100644 AsiaFlixProvider/src/main/AndroidManifest.xml create mode 100644 AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProvider.kt create mode 100644 AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProviderPlugin.kt create mode 100644 AsianLoadProvider/build.gradle.kts create mode 100644 AsianLoadProvider/src/main/AndroidManifest.xml create mode 100644 AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProvider.kt create mode 100644 AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProviderPlugin.kt create mode 100644 BflixProvider/build.gradle.kts create mode 100644 BflixProvider/src/main/AndroidManifest.xml create mode 100644 BflixProvider/src/main/kotlin/com/lagradost/BflixProvider.kt create mode 100644 BflixProvider/src/main/kotlin/com/lagradost/BflixProviderPlugin.kt create mode 100644 CinecalidadProvider/build.gradle.kts create mode 100644 CinecalidadProvider/src/main/AndroidManifest.xml create mode 100644 CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProvider.kt create mode 100644 CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProviderPlugin.kt create mode 100644 CuevanaProvider/build.gradle.kts create mode 100644 CuevanaProvider/src/main/AndroidManifest.xml create mode 100644 CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProvider.kt create mode 100644 CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProviderPlugin.kt create mode 100644 DopeboxProvider/build.gradle.kts create mode 100644 DopeboxProvider/src/main/AndroidManifest.xml create mode 100644 DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProvider.kt create mode 100644 DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProviderPlugin.kt create mode 100644 DoramasYTProvider/build.gradle.kts create mode 100644 DoramasYTProvider/src/main/AndroidManifest.xml create mode 100644 DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProvider.kt create mode 100644 DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProviderPlugin.kt create mode 100644 DramaSeeProvider/build.gradle.kts create mode 100644 DramaSeeProvider/src/main/AndroidManifest.xml create mode 100644 DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProvider.kt create mode 100644 DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProviderPlugin.kt create mode 100644 DramaidProvider/build.gradle.kts create mode 100644 DramaidProvider/src/main/AndroidManifest.xml create mode 100644 DramaidProvider/src/main/kotlin/com/lagradost/DramaidProvider.kt create mode 100644 DramaidProvider/src/main/kotlin/com/lagradost/DramaidProviderPlugin.kt create mode 100644 DubokuProvider/build.gradle.kts create mode 100644 DubokuProvider/src/main/AndroidManifest.xml create mode 100644 DubokuProvider/src/main/kotlin/com/lagradost/DubokuProvider.kt create mode 100644 DubokuProvider/src/main/kotlin/com/lagradost/DubokuProviderPlugin.kt create mode 100644 EgyBestProvider/build.gradle.kts create mode 100644 EgyBestProvider/src/main/AndroidManifest.xml create mode 100644 EgyBestProvider/src/main/kotlin/com/lagradost/EgyBestProvider.kt create mode 100644 EgyBestProvider/src/main/kotlin/com/lagradost/EgyBestProviderPlugin.kt create mode 100644 ElifilmsProvider/build.gradle.kts create mode 100644 ElifilmsProvider/src/main/AndroidManifest.xml create mode 100644 ElifilmsProvider/src/main/kotlin/com/lagradost/ElifilmsProvider.kt create mode 100644 ElifilmsProvider/src/main/kotlin/com/lagradost/ElifilmsProviderPlugin.kt create mode 100644 EntrepeliculasyseriesProvider/build.gradle.kts create mode 100644 EntrepeliculasyseriesProvider/src/main/AndroidManifest.xml create mode 100644 EntrepeliculasyseriesProvider/src/main/kotlin/com/lagradost/EntrepeliculasyseriesProvider.kt create mode 100644 EntrepeliculasyseriesProvider/src/main/kotlin/com/lagradost/EntrepeliculasyseriesProviderPlugin.kt create mode 100644 EstrenosDoramasProvider/build.gradle.kts create mode 100644 EstrenosDoramasProvider/src/main/AndroidManifest.xml create mode 100644 EstrenosDoramasProvider/src/main/kotlin/com/lagradost/EstrenosDoramasProvider.kt create mode 100644 EstrenosDoramasProvider/src/main/kotlin/com/lagradost/EstrenosDoramasProviderPlugin.kt delete mode 100644 ExampleProvider/src/main/kotlin/com/example/ExampleProvider.kt create mode 100644 FaselHDProvider/build.gradle.kts create mode 100644 FaselHDProvider/src/main/AndroidManifest.xml create mode 100644 FaselHDProvider/src/main/kotlin/com/lagradost/FaselHDProvider.kt create mode 100644 FaselHDProvider/src/main/kotlin/com/lagradost/FaselHDProviderPlugin.kt create mode 100644 FilmanProvider/build.gradle.kts create mode 100644 FilmanProvider/src/main/AndroidManifest.xml create mode 100644 FilmanProvider/src/main/kotlin/com/lagradost/FilmanProvider.kt create mode 100644 FilmanProvider/src/main/kotlin/com/lagradost/FilmanProviderPlugin.kt create mode 100644 FilmpertuttiProvider/build.gradle.kts create mode 100644 FilmpertuttiProvider/src/main/AndroidManifest.xml create mode 100644 FilmpertuttiProvider/src/main/kotlin/com/lagradost/FilmpertuttiProvider.kt create mode 100644 FilmpertuttiProvider/src/main/kotlin/com/lagradost/FilmpertuttiProviderPlugin.kt create mode 100644 FmoviesToProvider/build.gradle.kts create mode 100644 FmoviesToProvider/src/main/AndroidManifest.xml create mode 100644 FmoviesToProvider/src/main/kotlin/com/lagradost/FmoviesToProvider.kt create mode 100644 FmoviesToProvider/src/main/kotlin/com/lagradost/FmoviesToProviderPlugin.kt create mode 100644 FrenchStreamProvider/build.gradle.kts create mode 100644 FrenchStreamProvider/src/main/AndroidManifest.xml create mode 100644 FrenchStreamProvider/src/main/kotlin/com/lagradost/FrenchStreamProvider.kt create mode 100644 FrenchStreamProvider/src/main/kotlin/com/lagradost/FrenchStreamProviderPlugin.kt create mode 100644 HDMProvider/build.gradle.kts create mode 100644 HDMProvider/src/main/AndroidManifest.xml create mode 100644 HDMProvider/src/main/kotlin/com/lagradost/HDMProvider.kt create mode 100644 HDMProvider/src/main/kotlin/com/lagradost/HDMProviderPlugin.kt create mode 100644 HDMovie5/build.gradle.kts create mode 100644 HDMovie5/src/main/AndroidManifest.xml create mode 100644 HDMovie5/src/main/kotlin/com/lagradost/HDMovie5.kt rename ExampleProvider/src/main/kotlin/com/example/ExamplePlugin.kt => HDMovie5/src/main/kotlin/com/lagradost/HDMovie5Plugin.kt (77%) create mode 100644 HDTodayProvider/build.gradle.kts create mode 100644 HDTodayProvider/src/main/AndroidManifest.xml create mode 100644 HDTodayProvider/src/main/kotlin/com/lagradost/HDTodayProvider.kt create mode 100644 HDTodayProvider/src/main/kotlin/com/lagradost/HDTodayProviderPlugin.kt create mode 100644 HDrezkaProvider/build.gradle.kts create mode 100644 HDrezkaProvider/src/main/AndroidManifest.xml create mode 100644 HDrezkaProvider/src/main/kotlin/com/lagradost/HDrezkaProvider.kt create mode 100644 HDrezkaProvider/src/main/kotlin/com/lagradost/HDrezkaProviderPlugin.kt create mode 100644 IHaveNoTvProvider/build.gradle.kts create mode 100644 IHaveNoTvProvider/src/main/AndroidManifest.xml create mode 100644 IHaveNoTvProvider/src/main/kotlin/com/lagradost/IHaveNoTvProvider.kt create mode 100644 IHaveNoTvProvider/src/main/kotlin/com/lagradost/IHaveNoTvProviderPlugin.kt create mode 100644 IdlixProvider/build.gradle.kts create mode 100644 IdlixProvider/src/main/AndroidManifest.xml create mode 100644 IdlixProvider/src/main/kotlin/com/lagradost/IdlixProvider.kt create mode 100644 IdlixProvider/src/main/kotlin/com/lagradost/IdlixProviderPlugin.kt create mode 100644 IlGenioDelloStreamingProvider/build.gradle.kts create mode 100644 IlGenioDelloStreamingProvider/src/main/AndroidManifest.xml create mode 100644 IlGenioDelloStreamingProvider/src/main/kotlin/com/lagradost/IlGenioDelloStreamingProvider.kt create mode 100644 IlGenioDelloStreamingProvider/src/main/kotlin/com/lagradost/IlGenioDelloStreamingProviderPlugin.kt create mode 100644 KdramaHoodProvider/build.gradle.kts create mode 100644 KdramaHoodProvider/src/main/AndroidManifest.xml create mode 100644 KdramaHoodProvider/src/main/kotlin/com/lagradost/KdramaHoodProvider.kt create mode 100644 KdramaHoodProvider/src/main/kotlin/com/lagradost/KdramaHoodProviderPlugin.kt create mode 100644 KisskhProvider/build.gradle.kts create mode 100644 KisskhProvider/src/main/AndroidManifest.xml create mode 100644 KisskhProvider/src/main/kotlin/com/lagradost/KisskhProvider.kt create mode 100644 KisskhProvider/src/main/kotlin/com/lagradost/KisskhProviderPlugin.kt create mode 100644 LayarKacaProvider/build.gradle.kts create mode 100644 LayarKacaProvider/src/main/AndroidManifest.xml create mode 100644 LayarKacaProvider/src/main/kotlin/com/lagradost/LayarKacaProvider.kt create mode 100644 LayarKacaProvider/src/main/kotlin/com/lagradost/LayarKacaProviderPlugin.kt create mode 100644 MeloMovieProvider/build.gradle.kts create mode 100644 MeloMovieProvider/src/main/AndroidManifest.xml create mode 100644 MeloMovieProvider/src/main/kotlin/com/lagradost/MeloMovieProvider.kt create mode 100644 MeloMovieProvider/src/main/kotlin/com/lagradost/MeloMovieProviderPlugin.kt create mode 100644 MultiplexProvider/build.gradle.kts create mode 100644 MultiplexProvider/src/main/AndroidManifest.xml create mode 100644 MultiplexProvider/src/main/kotlin/com/lagradost/MultiplexProvider.kt create mode 100644 MultiplexProvider/src/main/kotlin/com/lagradost/MultiplexProviderPlugin.kt create mode 100644 MyCimaProvider/build.gradle.kts create mode 100644 MyCimaProvider/src/main/AndroidManifest.xml create mode 100644 MyCimaProvider/src/main/kotlin/com/lagradost/MyCimaProvider.kt create mode 100644 MyCimaProvider/src/main/kotlin/com/lagradost/MyCimaProviderPlugin.kt create mode 100644 NginxProvider/build.gradle.kts create mode 100644 NginxProvider/src/main/AndroidManifest.xml create mode 100644 NginxProvider/src/main/kotlin/com/lagradost/NginxProvider.kt create mode 100644 NginxProvider/src/main/kotlin/com/lagradost/NginxProviderPlugin.kt create mode 100644 OlgplyProvider/build.gradle.kts create mode 100644 OlgplyProvider/src/main/AndroidManifest.xml create mode 100644 OlgplyProvider/src/main/kotlin/com/lagradost/OlgplyProvider.kt create mode 100644 OlgplyProvider/src/main/kotlin/com/lagradost/OlgplyProviderPlugin.kt create mode 100644 OpenVidsProvider/build.gradle.kts create mode 100644 OpenVidsProvider/src/main/AndroidManifest.xml create mode 100644 OpenVidsProvider/src/main/kotlin/com/lagradost/OpenVidsProvider.kt create mode 100644 OpenVidsProvider/src/main/kotlin/com/lagradost/OpenVidsProviderPlugin.kt create mode 100644 PeliSmartProvider/build.gradle.kts create mode 100644 PeliSmartProvider/src/main/AndroidManifest.xml create mode 100644 PeliSmartProvider/src/main/kotlin/com/lagradost/PeliSmartProvider.kt create mode 100644 PeliSmartProvider/src/main/kotlin/com/lagradost/PeliSmartProviderPlugin.kt create mode 100644 PelisflixProvider/build.gradle.kts create mode 100644 PelisflixProvider/src/main/AndroidManifest.xml create mode 100644 PelisflixProvider/src/main/kotlin/com/lagradost/PelisflixProvider.kt create mode 100644 PelisflixProvider/src/main/kotlin/com/lagradost/PelisflixProviderPlugin.kt create mode 100644 PelisplusHDProvider/build.gradle.kts create mode 100644 PelisplusHDProvider/src/main/AndroidManifest.xml create mode 100644 PelisplusHDProvider/src/main/kotlin/com/lagradost/PelisplusHDProvider.kt create mode 100644 PelisplusHDProvider/src/main/kotlin/com/lagradost/PelisplusHDProviderPlugin.kt create mode 100644 PelisplusProvider/build.gradle.kts create mode 100644 PelisplusProvider/src/main/AndroidManifest.xml create mode 100644 PelisplusProvider/src/main/kotlin/com/lagradost/PelisplusProvider.kt create mode 100644 PelisplusProvider/src/main/kotlin/com/lagradost/PelisplusProviderPlugin.kt create mode 100644 PelisplusProviderTemplate/build.gradle.kts create mode 100644 PelisplusProviderTemplate/src/main/AndroidManifest.xml create mode 100644 PelisplusProviderTemplate/src/main/kotlin/com/lagradost/PelisplusProviderTemplate.kt create mode 100644 PelisplusProviderTemplate/src/main/kotlin/com/lagradost/PelisplusProviderTemplatePlugin.kt create mode 100644 PhimmoichillProvider/build.gradle.kts create mode 100644 PhimmoichillProvider/src/main/AndroidManifest.xml create mode 100644 PhimmoichillProvider/src/main/kotlin/com/lagradost/PhimmoichillProvider.kt create mode 100644 PhimmoichillProvider/src/main/kotlin/com/lagradost/PhimmoichillProviderPlugin.kt create mode 100644 PinoyHDXyzProvider/build.gradle.kts create mode 100644 PinoyHDXyzProvider/src/main/AndroidManifest.xml create mode 100644 PinoyHDXyzProvider/src/main/kotlin/com/lagradost/PinoyHDXyzProvider.kt create mode 100644 PinoyHDXyzProvider/src/main/kotlin/com/lagradost/PinoyHDXyzProviderPlugin.kt create mode 100644 PinoyMoviePediaProvider/build.gradle.kts create mode 100644 PinoyMoviePediaProvider/src/main/AndroidManifest.xml create mode 100644 PinoyMoviePediaProvider/src/main/kotlin/com/lagradost/PinoyMoviePediaProvider.kt create mode 100644 PinoyMoviePediaProvider/src/main/kotlin/com/lagradost/PinoyMoviePediaProviderPlugin.kt create mode 100644 PinoyMoviesEsProvider/build.gradle.kts create mode 100644 PinoyMoviesEsProvider/src/main/AndroidManifest.xml create mode 100644 PinoyMoviesEsProvider/src/main/kotlin/com/lagradost/PinoyMoviesEsProvider.kt create mode 100644 PinoyMoviesEsProvider/src/main/kotlin/com/lagradost/PinoyMoviesEsProviderPlugin.kt create mode 100644 RebahinProvider/build.gradle.kts create mode 100644 RebahinProvider/src/main/AndroidManifest.xml create mode 100644 RebahinProvider/src/main/kotlin/com/lagradost/RebahinProvider.kt create mode 100644 RebahinProvider/src/main/kotlin/com/lagradost/RebahinProviderPlugin.kt create mode 100644 SeriesflixProvider/build.gradle.kts create mode 100644 SeriesflixProvider/src/main/AndroidManifest.xml create mode 100644 SeriesflixProvider/src/main/kotlin/com/lagradost/SeriesflixProvider.kt create mode 100644 SeriesflixProvider/src/main/kotlin/com/lagradost/SeriesflixProviderPlugin.kt create mode 100644 SflixProProvider/build.gradle.kts create mode 100644 SflixProProvider/src/main/AndroidManifest.xml create mode 100644 SflixProProvider/src/main/kotlin/com/lagradost/SflixProProvider.kt create mode 100644 SflixProProvider/src/main/kotlin/com/lagradost/SflixProProviderPlugin.kt create mode 100644 SflixProvider/build.gradle.kts create mode 100644 SflixProvider/src/main/AndroidManifest.xml create mode 100644 SflixProvider/src/main/kotlin/com/lagradost/SflixProvider.kt create mode 100644 SflixProvider/src/main/kotlin/com/lagradost/SflixProviderPlugin.kt create mode 100644 SoaptwoDayProvider/build.gradle.kts create mode 100644 SoaptwoDayProvider/src/main/AndroidManifest.xml create mode 100644 SoaptwoDayProvider/src/main/kotlin/com/lagradost/SoaptwoDayProvider.kt create mode 100644 SoaptwoDayProvider/src/main/kotlin/com/lagradost/SoaptwoDayProviderPlugin.kt create mode 100644 SolarmovieProvider/build.gradle.kts create mode 100644 SolarmovieProvider/src/main/AndroidManifest.xml create mode 100644 SolarmovieProvider/src/main/kotlin/com/lagradost/SolarmovieProvider.kt create mode 100644 SolarmovieProvider/src/main/kotlin/com/lagradost/SolarmovieProviderPlugin.kt create mode 100644 StreamingcommunityProvider/build.gradle.kts create mode 100644 StreamingcommunityProvider/src/main/AndroidManifest.xml create mode 100644 StreamingcommunityProvider/src/main/kotlin/com/lagradost/StreamingcommunityProvider.kt create mode 100644 StreamingcommunityProvider/src/main/kotlin/com/lagradost/StreamingcommunityProviderPlugin.kt create mode 100644 SuperStream/build.gradle.kts create mode 100644 SuperStream/src/main/AndroidManifest.xml create mode 100644 SuperStream/src/main/kotlin/com/lagradost/SuperStream.kt create mode 100644 SuperStream/src/main/kotlin/com/lagradost/SuperStreamPlugin.kt create mode 100644 TantiFilmProvider/build.gradle.kts create mode 100644 TantiFilmProvider/src/main/AndroidManifest.xml create mode 100644 TantiFilmProvider/src/main/kotlin/com/lagradost/TantiFilmProvider.kt create mode 100644 TantiFilmProvider/src/main/kotlin/com/lagradost/TantiFilmProviderPlugin.kt create mode 100644 TheFlixToProvider/build.gradle.kts create mode 100644 TheFlixToProvider/src/main/AndroidManifest.xml create mode 100644 TheFlixToProvider/src/main/kotlin/com/lagradost/TheFlixToProvider.kt create mode 100644 TheFlixToProvider/src/main/kotlin/com/lagradost/TheFlixToProviderPlugin.kt create mode 100644 TrailersTwoProvider/build.gradle.kts create mode 100644 TrailersTwoProvider/src/main/AndroidManifest.xml create mode 100644 TrailersTwoProvider/src/main/kotlin/com/lagradost/TrailersTwoProvider.kt create mode 100644 TrailersTwoProvider/src/main/kotlin/com/lagradost/TrailersTwoProviderPlugin.kt create mode 100644 TwoEmbedProvider/build.gradle.kts create mode 100644 TwoEmbedProvider/src/main/AndroidManifest.xml create mode 100644 TwoEmbedProvider/src/main/kotlin/com/lagradost/TwoEmbedProvider.kt create mode 100644 TwoEmbedProvider/src/main/kotlin/com/lagradost/TwoEmbedProviderPlugin.kt create mode 100644 UakinoProvider/build.gradle.kts create mode 100644 UakinoProvider/src/main/AndroidManifest.xml create mode 100644 UakinoProvider/src/main/kotlin/com/lagradost/UakinoProvider.kt create mode 100644 UakinoProvider/src/main/kotlin/com/lagradost/UakinoProviderPlugin.kt create mode 100644 VMoveeProvider/build.gradle.kts create mode 100644 VMoveeProvider/src/main/AndroidManifest.xml create mode 100644 VMoveeProvider/src/main/kotlin/com/lagradost/VMoveeProvider.kt create mode 100644 VMoveeProvider/src/main/kotlin/com/lagradost/VMoveeProviderPlugin.kt create mode 100644 VfFilmProvider/build.gradle.kts create mode 100644 VfFilmProvider/src/main/AndroidManifest.xml create mode 100644 VfFilmProvider/src/main/kotlin/com/lagradost/VfFilmProvider.kt create mode 100644 VfFilmProvider/src/main/kotlin/com/lagradost/VfFilmProviderPlugin.kt create mode 100644 VfSerieProvider/build.gradle.kts create mode 100644 VfSerieProvider/src/main/AndroidManifest.xml create mode 100644 VfSerieProvider/src/main/kotlin/com/lagradost/VfSerieProvider.kt create mode 100644 VfSerieProvider/src/main/kotlin/com/lagradost/VfSerieProviderPlugin.kt create mode 100644 VidEmbedProvider/build.gradle.kts create mode 100644 VidEmbedProvider/src/main/AndroidManifest.xml create mode 100644 VidEmbedProvider/src/main/kotlin/com/lagradost/VidEmbedProvider.kt create mode 100644 VidEmbedProvider/src/main/kotlin/com/lagradost/VidEmbedProviderPlugin.kt create mode 100644 VidSrcProvider/build.gradle.kts create mode 100644 VidSrcProvider/src/main/AndroidManifest.xml create mode 100644 VidSrcProvider/src/main/kotlin/com/lagradost/VidSrcProvider.kt create mode 100644 VidSrcProvider/src/main/kotlin/com/lagradost/VidSrcProviderPlugin.kt create mode 100644 VidstreamProviderTemplate/build.gradle.kts create mode 100644 VidstreamProviderTemplate/src/main/AndroidManifest.xml create mode 100644 VidstreamProviderTemplate/src/main/kotlin/com/lagradost/VidstreamProviderTemplate.kt create mode 100644 VidstreamProviderTemplate/src/main/kotlin/com/lagradost/VidstreamProviderTemplatePlugin.kt create mode 100644 WatchAsianProvider/build.gradle.kts create mode 100644 WatchAsianProvider/src/main/AndroidManifest.xml create mode 100644 WatchAsianProvider/src/main/kotlin/com/lagradost/WatchAsianProvider.kt create mode 100644 WatchAsianProvider/src/main/kotlin/com/lagradost/WatchAsianProviderPlugin.kt create mode 100644 XcineProvider/build.gradle.kts create mode 100644 XcineProvider/src/main/AndroidManifest.xml create mode 100644 XcineProvider/src/main/kotlin/com/lagradost/XcineProvider.kt create mode 100644 XcineProvider/src/main/kotlin/com/lagradost/XcineProviderPlugin.kt create mode 100644 YomoviesProvider/build.gradle.kts create mode 100644 YomoviesProvider/src/main/AndroidManifest.xml create mode 100644 YomoviesProvider/src/main/kotlin/com/lagradost/YomoviesProvider.kt create mode 100644 YomoviesProvider/src/main/kotlin/com/lagradost/YomoviesProviderPlugin.kt diff --git a/ExampleProvider/build.gradle.kts b/AkwamProvider/build.gradle.kts similarity index 84% rename from ExampleProvider/build.gradle.kts rename to AkwamProvider/build.gradle.kts index 62ee453..e7d2158 100644 --- a/ExampleProvider/build.gradle.kts +++ b/AkwamProvider/build.gradle.kts @@ -5,8 +5,8 @@ version = 1 cloudstream { // All of these properties are optional, you can safely remove them - description = "Lorem Ipsum" - authors = listOf("Cloudburst") + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") /** * Status int as the following: diff --git a/ExampleProvider/src/main/AndroidManifest.xml b/AkwamProvider/src/main/AndroidManifest.xml similarity index 52% rename from ExampleProvider/src/main/AndroidManifest.xml rename to AkwamProvider/src/main/AndroidManifest.xml index 1863f02..29aec9d 100644 --- a/ExampleProvider/src/main/AndroidManifest.xml +++ b/AkwamProvider/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/AkwamProvider/src/main/kotlin/com/lagradost/AkwamProvider.kt b/AkwamProvider/src/main/kotlin/com/lagradost/AkwamProvider.kt new file mode 100644 index 0000000..b262f3a --- /dev/null +++ b/AkwamProvider/src/main/kotlin/com/lagradost/AkwamProvider.kt @@ -0,0 +1,224 @@ +package com.lagradost + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addActors +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities +import org.jsoup.nodes.Element + +class AkwamProvider : MainAPI() { + override var lang = "ar" + override var mainUrl = "https://akwam.to" + override var name = "Akwam" + override val usesWebView = false + override val hasMainPage = true + override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie, TvType.Anime, TvType.Cartoon) + + private fun Element.toSearchResponse(): SearchResponse? { + val url = select("a.box").attr("href") ?: return null + if (url.contains("/games/") || url.contains("/programs/")) return null + val poster = select("picture > img") + val title = poster.attr("alt") + val posterUrl = poster.attr("data-src") + val year = select(".badge-secondary").text().toIntOrNull() + + // If you need to differentiate use the url. + return MovieSearchResponse( + title, + url, + this@AkwamProvider.name, + TvType.TvSeries, + posterUrl, + year, + null, + ) + } + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + // Title, Url + val moviesUrl = listOf( + "Movies" to "$mainUrl/movies", + "Series" to "$mainUrl/series", + "Shows" to "$mainUrl/shows" + ) + val pages = moviesUrl.apmap { + val doc = app.get(it.second).document + val list = doc.select("div.col-lg-auto.col-md-4.col-6.mb-12").mapNotNull { element -> + element.toSearchResponse() + } + HomePageList(it.first, list) + }.sortedBy { it.name } + return HomePageResponse(pages) + } + + override suspend fun search(query: String): List { + val url = "$mainUrl/search?q=$query" + val doc = app.get(url).document + return doc.select("div.col-lg-auto").mapNotNull { + it.toSearchResponse() + } + } + + private fun String.getIntFromText(): Int? { + return Regex("""\d+""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull() + } + + private fun Element.toEpisode(): Episode { + val a = select("a.text-white") + val url = a.attr("href") + val title = a.text() + val thumbUrl = select("picture > img").attr("src") + val date = select("p.entry-date").text() + return newEpisode(url) { + name = title + episode = title.getIntFromText() + posterUrl = thumbUrl + addDate(date) + } + } + + + override suspend fun load(url: String): LoadResponse { + val doc = app.get(url).document + val isMovie = url.contains("/movie/") + val title = doc.select("h1.entry-title").text() + val posterUrl = doc.select("picture > img").attr("src") + + val year = + doc.select("div.font-size-16.text-white.mt-2").firstOrNull { + it.text().contains("السنة") + }?.text()?.getIntFromText() + + // A bit iffy to parse twice like this, but it'll do. + val duration = + doc.select("div.font-size-16.text-white.mt-2").firstOrNull { + it.text().contains("مدة الفيلم") + }?.text()?.getIntFromText() + + val synopsis = doc.select("div.widget-body p:first-child").text() + + val rating = doc.select("span.mx-2").text().split("/").lastOrNull()?.toRatingInt() + + val tags = doc.select("div.font-size-16.d-flex.align-items-center.mt-3 > a").map { + it.text() + } + + val actors = doc.select("div.widget-body > div > div.entry-box > a").mapNotNull { + val name = it?.selectFirst("div > .entry-title")?.text() ?: return@mapNotNull null + val image = it.selectFirst("div > img")?.attr("src") ?: return@mapNotNull null + Actor(name, image) + } + + val recommendations = + doc.select("div > div.widget-body > div.row > div > div.entry-box").mapNotNull { + val recTitle = it?.selectFirst("div.entry-body > .entry-title > .text-white") + ?: return@mapNotNull null + val href = recTitle.attr("href") ?: return@mapNotNull null + val name = recTitle.text() ?: return@mapNotNull null + val poster = it.selectFirst(".entry-image > a > picture > img")?.attr("data-src") + ?: return@mapNotNull null + MovieSearchResponse(name, href, this.name, TvType.Movie, fixUrl(poster)) + } + + return if (isMovie) { + newMovieLoadResponse( + title, + url, + TvType.Movie, + url + ) { + this.posterUrl = posterUrl + this.year = year + this.plot = synopsis + this.rating = rating + this.tags = tags + this.duration = duration + this.recommendations = recommendations + addActors(actors) + } + } else { + val episodes = doc.select("div.bg-primary2.p-4.col-lg-4.col-md-6.col-12").map { + it.toEpisode() + }.let { + val isReversed = (it.lastOrNull()?.episode ?: 1) < (it.firstOrNull()?.episode ?: 0) + if (isReversed) + it.reversed() + else it + } + + newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { + this.duration = duration + this.posterUrl = posterUrl + this.tags = tags.filterNotNull() + this.rating = rating + this.year = year + this.plot = synopsis + this.recommendations = recommendations + addActors(actors) + } + } + } + + +// // Maybe possible to not use the url shortener but cba investigating that. +// private suspend fun skipUrlShortener(url: String): AppResponse { +// return app.get(app.get(url).document.select("a.download-link").attr("href")) +// } + + private fun getQualityFromId(id: Int?): Qualities { + return when (id) { + 2 -> Qualities.P360 // Extrapolated + 3 -> Qualities.P480 + 4 -> Qualities.P720 + 5 -> Qualities.P1080 + else -> Qualities.Unknown + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val doc = app.get(data).document + + val links = doc.select("div.tab-content.quality").map { element -> + val quality = getQualityFromId(element.attr("id").getIntFromText()) + element.select(".col-lg-6 > a:contains(تحميل)").map { linkElement -> + if (linkElement.attr("href").contains("/download/")) { + Pair( + linkElement.attr("href"), + quality, + ) + } else { + val url = "$mainUrl/download${ + linkElement.attr("href").split("/link")[1] + }${data.split("/movie|/episode|/show/episode".toRegex())[1]}" + Pair( + url, + quality, + ) + // just in case if they add the shorts urls again + } + } + }.flatten() + + links.map { + val linkDoc = app.get(it.first).document + val button = linkDoc.select("div.btn-loader > a") + val url = button.attr("href") + + callback.invoke( + ExtractorLink( + this.name, + this.name, + url, + this.mainUrl, + it.second.value + ) + ) + } + return true + } +} diff --git a/AkwamProvider/src/main/kotlin/com/lagradost/AkwamProviderPlugin.kt b/AkwamProvider/src/main/kotlin/com/lagradost/AkwamProviderPlugin.kt new file mode 100644 index 0000000..9f65a9c --- /dev/null +++ b/AkwamProvider/src/main/kotlin/com/lagradost/AkwamProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class AkwamProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(AkwamProvider()) + } +} \ No newline at end of file diff --git a/AllMoviesForYouProvider/build.gradle.kts b/AllMoviesForYouProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/AllMoviesForYouProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/AllMoviesForYouProvider/src/main/AndroidManifest.xml b/AllMoviesForYouProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/AllMoviesForYouProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProvider.kt b/AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProvider.kt new file mode 100644 index 0000000..5cda4d2 --- /dev/null +++ b/AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProvider.kt @@ -0,0 +1,206 @@ +package com.lagradost + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addDuration +import com.lagradost.cloudstream3.mvvm.logError +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor +import org.jsoup.Jsoup + +class AllMoviesForYouProvider : MainAPI() { + companion object { + fun getType(t: String): TvType { + return when { + t.contains("series") -> TvType.TvSeries + t.contains("movies") -> TvType.Movie + else -> TvType.Movie + } + } + } + + // Fetching movies will not work if this link is outdated. + override var mainUrl = "https://allmoviesforyou.net" + override var name = "AllMoviesForYou" + override val hasMainPage = true + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries + ) + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + val items = ArrayList() + val soup = app.get(mainUrl).document + val urls = listOf( + Pair("Movies", "section[data-id=movies] article.TPost.B"), + Pair("TV Series", "section[data-id=series] article.TPost.B"), + ) + for ((name, element) in urls) { + try { + val home = soup.select(element).map { + val title = it.selectFirst("h2.title")!!.text() + val link = it.selectFirst("a")!!.attr("href") + TvSeriesSearchResponse( + title, + link, + this.name, + TvType.Movie, + fixUrl(it.selectFirst("figure img")!!.attr("data-src")), + null, + null, + ) + } + + items.add(HomePageList(name, home)) + } catch (e: Exception) { + logError(e) + } + } + if (items.size <= 0) throw ErrorLoadingException() + return HomePageResponse(items) + } + + override suspend fun search(query: String): List { + val url = "$mainUrl/?s=$query" + val document = app.get(url).document + + val items = document.select("ul.MovieList > li > article > a") + return items.map { item -> + val href = item.attr("href") + val title = item.selectFirst("> h2.Title")!!.text() + val img = fixUrl(item.selectFirst("> div.Image > figure > img")!!.attr("data-src")) + val type = getType(href) + if (type == TvType.Movie) { + MovieSearchResponse(title, href, this.name, type, img, null) + } else { + TvSeriesSearchResponse( + title, + href, + this.name, + type, + img, + null, + null + ) + } + } + } + +// private fun getLink(document: Document): List? { +// val list = ArrayList() +// Regex("iframe src=\"(.*?)\"").find(document.html())?.groupValues?.get(1)?.let { +// list.add(it) +// } +// document.select("div.OptionBx")?.forEach { element -> +// val baseElement = element.selectFirst("> a.Button") +// val elementText = element.selectFirst("> p.AAIco-dns")?.text() +// if (elementText == "Streamhub" || elementText == "Dood") { +// baseElement?.attr("href")?.let { href -> +// list.add(href) +// } +// } +// } +// +// return if (list.isEmpty()) null else list +// } + + override suspend fun load(url: String): LoadResponse { + val type = getType(url) + + val document = app.get(url).document + + val title = document.selectFirst("h1.Title")!!.text() + val descipt = document.selectFirst("div.Description > p")!!.text() + val rating = + document.selectFirst("div.Vote > div.post-ratings > span")?.text()?.toRatingInt() + val year = document.selectFirst("span.Date")?.text() + val duration = document.selectFirst("span.Time")!!.text() + val backgroundPoster = + fixUrlNull(document.selectFirst("div.Image > figure > img")?.attr("data-src")) + + if (type == TvType.TvSeries) { + val list = ArrayList>() + + document.select("main > section.SeasonBx > div > div.Title > a").forEach { element -> + val season = element.selectFirst("> span")?.text()?.toIntOrNull() + val href = element.attr("href") + if (season != null && season > 0 && !href.isNullOrBlank()) { + list.add(Pair(season, fixUrl(href))) + } + } + if (list.isEmpty()) throw ErrorLoadingException("No Seasons Found") + + val episodeList = ArrayList() + + for (season in list) { + val seasonResponse = app.get(season.second).text + val seasonDocument = Jsoup.parse(seasonResponse) + val episodes = seasonDocument.select("table > tbody > tr") + if (episodes.isNotEmpty()) { + episodes.forEach { episode -> + val epNum = episode.selectFirst("> td > span.Num")?.text()?.toIntOrNull() + val poster = episode.selectFirst("> td.MvTbImg > a > img")?.attr("data-src") + val aName = episode.selectFirst("> td.MvTbTtl > a") + val name = aName!!.text() + val href = aName.attr("href") + val date = episode.selectFirst("> td.MvTbTtl > span")?.text() + + episodeList.add( + newEpisode(href) { + this.name = name + this.season = season.first + this.episode = epNum + this.posterUrl = fixUrlNull(poster) + addDate(date) + } + ) + } + } + } + return TvSeriesLoadResponse( + title, + url, + this.name, + type, + episodeList, + backgroundPoster, + year?.toIntOrNull(), + descipt, + null, + rating + ) + } else { + return newMovieLoadResponse( + title, + url, + type, + fixUrl(url) + ) { + posterUrl = backgroundPoster + this.year = year?.toIntOrNull() + this.plot = descipt + this.rating = rating + addDuration(duration) + } + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val doc = app.get(data).document + val iframe = doc.select("body iframe").map { fixUrl(it.attr("src")) } + iframe.apmap { id -> + if (id.contains("trembed")) { + val soup = app.get(id).document + soup.select("body iframe").map { + val link = fixUrl(it.attr("src").replace("streamhub.to/d/", "streamhub.to/e/")) + loadExtractor(link, data, subtitleCallback, callback) + } + } else loadExtractor(id, data, subtitleCallback, callback) + } + return true + } +} diff --git a/AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProviderPlugin.kt b/AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProviderPlugin.kt new file mode 100644 index 0000000..bc59d5f --- /dev/null +++ b/AllMoviesForYouProvider/src/main/kotlin/com/lagradost/AllMoviesForYouProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class AllMoviesForYouProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(AllMoviesForYouProvider()) + } +} \ No newline at end of file diff --git a/AltadefinizioneProvider/build.gradle.kts b/AltadefinizioneProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/AltadefinizioneProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/AltadefinizioneProvider/src/main/AndroidManifest.xml b/AltadefinizioneProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/AltadefinizioneProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProvider.kt b/AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProvider.kt new file mode 100644 index 0000000..1a3fa77 --- /dev/null +++ b/AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProvider.kt @@ -0,0 +1,160 @@ +package com.lagradost + +//import androidx.core.text.parseAsHtml +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor +import com.lagradost.cloudstream3.utils.AppUtils.html + + +class AltadefinizioneProvider : MainAPI() { + override var lang = "it" + override var mainUrl = "https://altadefinizione.tienda" + override var name = "Altadefinizione" + override val hasMainPage = true + override val hasChromecastSupport = true + override val supportedTypes = setOf( + TvType.Movie + ) + + override val mainPage = mainPageOf( + Pair("$mainUrl/cerca/anno/2022/page/", "Ultimi Film"), + Pair("$mainUrl/cerca/openload-quality/HD/page/", "Film in HD"), + Pair("$mainUrl/cinema/page/", "Ora al cinema") + ) + + override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse { + val url = request.data + page + + val soup = app.get(url).document + val home = soup.select("div.box").map { + val title = it.selectFirst("img")!!.attr("alt") + val link = it.selectFirst("a")!!.attr("href") + val image = mainUrl + it.selectFirst("img")!!.attr("src") + val quality = getQualityFromString(it.selectFirst("span")!!.text()) + + MovieSearchResponse( + title, + link, + this.name, + TvType.Movie, + image, + null, + null, + quality, + ) + } + return newHomePageResponse(request.name, home) + } + + override suspend fun search(query: String): List { + val doc = app.post( + "$mainUrl/index.php", data = mapOf( + "do" to "search", + "subaction" to "search", + "story" to query, + "sortby" to "news_read" + ) + ).document + return doc.select("div.box").map { + val title = it.selectFirst("img")!!.attr("alt") + val link = it.selectFirst("a")!!.attr("href") + val image = mainUrl + it.selectFirst("img")!!.attr("src") + val quality = getQualityFromString(it.selectFirst("span")!!.text()) + + MovieSearchResponse( + title, + link, + this.name, + TvType.Movie, + image, + null, + null, + quality, + ) + } + } + + override suspend fun load(url: String): LoadResponse { + val page = app.get(url) + val document = page.document + val title = document.selectFirst(" h1 > a")!!.text().replace("streaming", "") + val description = document.select("#sfull").toString().substringAfter("altadefinizione") + .substringBeforeLast("fonte trama").html().toString() + val rating = null + + val year = document.selectFirst("#details > li:nth-child(2)")!!.childNode(2).toString() + .filter { it.isDigit() }.toInt() + + val poster = fixUrl(document.selectFirst("div.thumbphoto > img")!!.attr("src")) + + val recomm = document.select("ul.related-list > li").map { + val href = it.selectFirst("a")!!.attr("href") + val posterUrl = mainUrl + it.selectFirst("img")!!.attr("src") + val name = it.selectFirst("img")!!.attr("alt") + MovieSearchResponse( + name, + href, + this.name, + TvType.Movie, + posterUrl, + null + ) + + } + + + val actors: List = + document.select("#staring > a").map { + ActorData(actor = Actor(it.text())) + } + + val tags: List = document.select("#details > li:nth-child(1) > a").map { it.text() } + + val trailerurl = document.selectFirst("#showtrailer > div > div > iframe")?.attr("src") + + return newMovieLoadResponse( + title, + url, + TvType.Movie, + url + ) { + posterUrl = fixUrlNull(poster) + this.year = year + this.plot = description + this.rating = rating + this.recommendations = recomm + this.duration = null + this.actors = actors + this.tags = tags + addTrailer(trailerurl) + } + } + + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val doc = app.get(data).document + if (doc.select("div.guardahd-player").isNullOrEmpty()) { + val videoUrl = + doc.select("input").last { it.hasAttr("data-mirror") }.attr("value") + loadExtractor(videoUrl, data, subtitleCallback, callback) + doc.select("#mirrors > li > a").forEach { + loadExtractor(fixUrl(it.attr("data-target")), data, subtitleCallback, callback) + } + } else { + val pagelinks = doc.select("div.guardahd-player").select("iframe").attr("src") + val docLinks = app.get(pagelinks).document + docLinks.select("body > div > ul > li").forEach { + loadExtractor(fixUrl(it.attr("data-link")), data, subtitleCallback, callback) + } + } + + return true + } +} \ No newline at end of file diff --git a/AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProviderPlugin.kt b/AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProviderPlugin.kt new file mode 100644 index 0000000..1e9a49b --- /dev/null +++ b/AltadefinizioneProvider/src/main/kotlin/com/lagradost/AltadefinizioneProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class AltadefinizioneProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(AltadefinizioneProvider()) + } +} \ No newline at end of file diff --git a/AsiaFlixProvider/build.gradle.kts b/AsiaFlixProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/AsiaFlixProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/AsiaFlixProvider/src/main/AndroidManifest.xml b/AsiaFlixProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/AsiaFlixProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProvider.kt b/AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProvider.kt new file mode 100644 index 0000000..cc8d3ad --- /dev/null +++ b/AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProvider.kt @@ -0,0 +1,198 @@ +package com.lagradost + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.module.kotlin.readValue +import com.lagradost.cloudstream3.* +//import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.getStatus +import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.getQualityFromName +import java.net.URI + +class AsiaFlixProvider : MainAPI() { + companion object { + fun getType(t: String): TvType { + return if (t.contains("OVA") || t.contains("Special")) TvType.OVA + else if (t.contains("Movie")) TvType.AnimeMovie + else TvType.Anime + } + + fun getStatus(t: String): ShowStatus { + return when (t) { + "Completed" -> ShowStatus.Completed + "Ongoing" -> ShowStatus.Ongoing + else -> ShowStatus.Completed + } + } + } + + override var mainUrl = "https://asiaflix.app" + override var name = "AsiaFlix" + override val hasQuickSearch = false + override val hasMainPage = true + override val hasChromecastSupport = false + override val supportedTypes = setOf(TvType.AsianDrama) + + private val apiUrl = "https://api.asiaflix.app/api/v2" + + data class DashBoardObject( + @JsonProperty("sectionName") val sectionName: String, + @JsonProperty("type") val type: String?, + @JsonProperty("data") val data: List? + ) + + data class Episodes( + @JsonProperty("_id") val _id: String, + @JsonProperty("epUrl") val epUrl: String?, + @JsonProperty("number") val number: Int?, + @JsonProperty("type") val type: String?, + @JsonProperty("extracted") val extracted: String?, + @JsonProperty("videoUrl") val videoUrl: String? + ) + + + data class Data( + @JsonProperty("_id") val _id: String, + @JsonProperty("name") val name: String, + @JsonProperty("altNames") val altNames: String?, + @JsonProperty("image") val image: String?, + @JsonProperty("tvStatus") val tvStatus: String?, + @JsonProperty("genre") val genre: String?, + @JsonProperty("releaseYear") val releaseYear: Int?, + @JsonProperty("createdAt") val createdAt: Long?, + @JsonProperty("episodes") val episodes: List?, + @JsonProperty("views") val views: Int? + ) + + + data class DramaPage( + @JsonProperty("_id") val _id: String, + @JsonProperty("name") val name: String, + @JsonProperty("altNames") val altNames: String?, + @JsonProperty("synopsis") val synopsis: String?, + @JsonProperty("image") val image: String?, + @JsonProperty("language") val language: String?, + @JsonProperty("dramaUrl") val dramaUrl: String?, + @JsonProperty("published") val published: Boolean?, + @JsonProperty("tvStatus") val tvStatus: String?, + @JsonProperty("firstAirDate") val firstAirDate: String?, + @JsonProperty("genre") val genre: String?, + @JsonProperty("releaseYear") val releaseYear: Int?, + @JsonProperty("createdAt") val createdAt: Long?, + @JsonProperty("modifiedAt") val modifiedAt: Long?, + @JsonProperty("episodes") val episodes: List, + @JsonProperty("__v") val __v: Int?, + @JsonProperty("cdnImage") val cdnImage: String?, + @JsonProperty("views") val views: Int? + ) + + private fun Data.toSearchResponse(): TvSeriesSearchResponse { + return TvSeriesSearchResponse( + name, + _id, + this@AsiaFlixProvider.name, + TvType.AsianDrama, + image, + releaseYear, + episodes?.size, + ) + } + + private fun Episodes.toEpisode(): Episode? { + if (videoUrl != null && videoUrl.contains("watch/null") || number == null) return null + return videoUrl?.let { + Episode( + it, + null, + number, + ) + } + } + + private fun DramaPage.toLoadResponse(): TvSeriesLoadResponse { + return TvSeriesLoadResponse( + name, + "$mainUrl$dramaUrl/$_id".replace("drama-detail", "show-details"), + this@AsiaFlixProvider.name, + TvType.AsianDrama, + episodes.mapNotNull { it.toEpisode() }.sortedBy { it.episode }, + image, + releaseYear, + synopsis, + getStatus(tvStatus ?: ""), + null, + genre?.split(",")?.map { it.trim() } + ) + } + + override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse { + val headers = mapOf("X-Requested-By" to "asiaflix-web") + val response = app.get("$apiUrl/dashboard", headers = headers).text + + val customMapper = + mapper.copy().configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true) + // Hack, because it can either be object or a list + val cleanedResponse = Regex(""""data":(\{.*?),\{"sectionName"""").replace(response) { + """"data":null},{"sectionName"""" + } + + val dashBoard = customMapper.readValue?>(cleanedResponse) + + val listItems = dashBoard?.mapNotNull { + it.data?.map { data -> + data.toSearchResponse() + }?.let { searchResponse -> + HomePageList(it.sectionName, searchResponse) + } + } + return HomePageResponse(listItems ?: listOf()) + } + + data class Link( + @JsonProperty("url") val url: String?, + ) + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + if (isCasting) return false + val headers = mapOf("X-Requested-By" to "asiaflix-web") + app.get( + "$apiUrl/utility/get-stream-links?url=$data", + headers = headers + ).text.toKotlinObject().url?.let { +// val fixedUrl = "https://api.asiaflix.app/api/v2/utility/cors-proxy/playlist/${URLEncoder.encode(it, StandardCharsets.UTF_8.toString())}" + callback.invoke( + ExtractorLink( + name, + name, + it, + "https://asianload1.com/", + /** <------ This provider should be added instead */ + getQualityFromName(it), + URI(it).path.endsWith(".m3u8") + ) + ) + } + return true + } + + override suspend fun search(query: String): List? { + val headers = mapOf("X-Requested-By" to "asiaflix-web") + val url = "$apiUrl/drama/search?q=$query" + val response = app.get(url, headers = headers).text + return mapper.readValue?>(response)?.map { it.toSearchResponse() } + } + + override suspend fun load(url: String): LoadResponse { + val headers = mapOf("X-Requested-By" to "asiaflix-web") + val requestUrl = "$apiUrl/drama?id=${url.split("/").lastOrNull()}" + val response = app.get(requestUrl, headers = headers).text + val dramaPage = response.toKotlinObject() + return dramaPage.toLoadResponse() + } +} diff --git a/AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProviderPlugin.kt b/AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProviderPlugin.kt new file mode 100644 index 0000000..f6656e4 --- /dev/null +++ b/AsiaFlixProvider/src/main/kotlin/com/lagradost/AsiaFlixProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class AsiaFlixProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(AsiaFlixProvider()) + } +} \ No newline at end of file diff --git a/AsianLoadProvider/build.gradle.kts b/AsianLoadProvider/build.gradle.kts new file mode 100644 index 0000000..df3927d --- /dev/null +++ b/AsianLoadProvider/build.gradle.kts @@ -0,0 +1,25 @@ +dependencies { + implementation(project(mapOf("path" to ":VidstreamProviderTemplate"))) +} +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/AsianLoadProvider/src/main/AndroidManifest.xml b/AsianLoadProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/AsianLoadProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProvider.kt b/AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProvider.kt new file mode 100644 index 0000000..58bafdf --- /dev/null +++ b/AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProvider.kt @@ -0,0 +1,25 @@ +package com.lagradost + +import com.lagradost.cloudstream3.TvType + +/** Needs to inherit from MainAPI() to + * make the app know what functions to call + */ +class AsianLoadProvider : VidstreamProviderTemplate() { + override var name = "AsianLoad" + override var mainUrl = "https://asianembed.io" + override val homePageUrlList = listOf( + mainUrl, + "$mainUrl/recently-added-raw", + "$mainUrl/movies", + "$mainUrl/kshow", + "$mainUrl/popular", + "$mainUrl/ongoing-series" + ) + + override val iv = "9262859232435825" + override val secretKey = "93422192433952489752342908585752" + override val secretDecryptKey = secretKey + + override val supportedTypes = setOf(TvType.AsianDrama) +} diff --git a/AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProviderPlugin.kt b/AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProviderPlugin.kt new file mode 100644 index 0000000..09cfea2 --- /dev/null +++ b/AsianLoadProvider/src/main/kotlin/com/lagradost/AsianLoadProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class AsianLoadProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(AsianLoadProvider()) + } +} \ No newline at end of file diff --git a/BflixProvider/build.gradle.kts b/BflixProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/BflixProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/BflixProvider/src/main/AndroidManifest.xml b/BflixProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/BflixProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/BflixProvider/src/main/kotlin/com/lagradost/BflixProvider.kt b/BflixProvider/src/main/kotlin/com/lagradost/BflixProvider.kt new file mode 100644 index 0000000..1129895 --- /dev/null +++ b/BflixProvider/src/main/kotlin/com/lagradost/BflixProvider.kt @@ -0,0 +1,300 @@ +package com.lagradost + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.animeproviders.NineAnimeProvider.Companion.decodeVrf +import com.lagradost.cloudstream3.animeproviders.NineAnimeProvider.Companion.encode +import com.lagradost.cloudstream3.animeproviders.NineAnimeProvider.Companion.encodeVrf +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor +import org.jsoup.Jsoup + +open class BflixProvider : MainAPI() { + override var mainUrl = "https://bflix.ru" + override var name = "Bflix" + override val hasMainPage = true + override val hasChromecastSupport = true + override val hasDownloadSupport = true + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + ) + + //override val uniqueId: Int by lazy { "BflixProvider".hashCode() } + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + val items = ArrayList() + val soup = app.get("$mainUrl/home").document + val testa = listOf( + Pair("Movies", "div.tab-content[data-name=movies] div.filmlist div.item"), + Pair("Shows", "div.tab-content[data-name=shows] div.filmlist div.item"), + Pair("Trending", "div.tab-content[data-name=trending] div.filmlist div.item"), + Pair( + "Latest Movies", + "div.container section.bl:contains(Latest Movies) div.filmlist div.item" + ), + Pair( + "Latest TV-Series", + "div.container section.bl:contains(Latest TV-Series) div.filmlist div.item" + ), + ) + for ((name, element) in testa) try { + val test = soup.select(element).map { + val title = it.selectFirst("h3 a")!!.text() + val link = fixUrl(it.selectFirst("a")!!.attr("href")) + val qualityInfo = it.selectFirst("div.quality")!!.text() + val quality = getQualityFromString(qualityInfo) + TvSeriesSearchResponse( + title, + link, + this.name, + if (link.contains("/movie/")) TvType.Movie else TvType.TvSeries, + it.selectFirst("a.poster img")!!.attr("src"), + null, + null, + quality = quality + ) + } + items.add(HomePageList(name, test)) + } catch (e: Exception) { + e.printStackTrace() + } + + if (items.size <= 0) throw ErrorLoadingException() + return HomePageResponse(items) + } + + override suspend fun search(query: String): List? { + val encodedquery = encodeVrf(query, mainKey) + val url = "$mainUrl/search?keyword=$query&vrf=$encodedquery" + val html = app.get(url).text + val document = Jsoup.parse(html) + + return document.select(".filmlist div.item").map { + val title = it.selectFirst("h3 a")!!.text() + val href = fixUrl(it.selectFirst("a")!!.attr("href")) + val image = it.selectFirst("a.poster img")!!.attr("src") + val isMovie = href.contains("/movie/") + val qualityInfo = it.selectFirst("div.quality")!!.text() + val quality = getQualityFromString(qualityInfo) + + if (isMovie) { + MovieSearchResponse( + title, + href, + this.name, + TvType.Movie, + image, + null, + quality = quality + ) + } else { + TvSeriesSearchResponse( + title, + href, + this.name, + TvType.TvSeries, + image, + null, + null, + quality = quality + ) + } + } + } + + data class Response( + @JsonProperty("html") val html: String + ) + + companion object { + val mainKey = "OrAimkpzm6phmN3j" + } + + override suspend fun load(url: String): LoadResponse? { + val soup = app.get(url).document + val movieid = soup.selectFirst("div#watch")!!.attr("data-id") + val movieidencoded = encodeVrf(movieid, mainKey) + val title = soup.selectFirst("div.info h1")!!.text() + val description = soup.selectFirst(".info .desc")?.text()?.trim() + val poster: String? = try { + soup.selectFirst("img.poster")!!.attr("src") + } catch (e: Exception) { + soup.selectFirst(".info .poster img")!!.attr("src") + } + + val tags = soup.select("div.info .meta div:contains(Genre) a").map { it.text() } + val vrfUrl = "$mainUrl/ajax/film/servers?id=$movieid&vrf=$movieidencoded" + println("VRF___ $vrfUrl") + val episodes = Jsoup.parse( + app.get( + vrfUrl + ).parsed().html + ).select("div.episode").map { + val a = it.selectFirst("a") + val href = fixUrl(a!!.attr("href")) + val extraData = a.attr("data-kname").let { str -> + str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() } + } + val isValid = extraData.size == 2 + val episode = if (isValid) extraData.getOrNull(1) else null + val season = if (isValid) extraData.getOrNull(0) else null + + val eptitle = it.selectFirst(".episode a span.name")!!.text() + val secondtitle = it.selectFirst(".episode a span")!!.text() + .replace(Regex("(Episode (\\d+):|Episode (\\d+)-|Episode (\\d+))"), "") ?: "" + Episode( + href, + secondtitle + eptitle, + season, + episode, + ) + } + val tvType = + if (url.contains("/movie/") && episodes.size == 1) TvType.Movie else TvType.TvSeries + val recommendations = + soup.select("div.bl-2 section.bl div.content div.filmlist div.item") + .mapNotNull { element -> + val recTitle = element.select("h3 a").text() ?: return@mapNotNull null + val image = element.select("a.poster img")?.attr("src") + val recUrl = fixUrl(element.select("a").attr("href")) + MovieSearchResponse( + recTitle, + recUrl, + this.name, + if (recUrl.contains("/movie/")) TvType.Movie else TvType.TvSeries, + image, + year = null + ) + } + val rating = soup.selectFirst(".info span.imdb")?.text()?.toRatingInt() + val durationdoc = soup.selectFirst("div.info div.meta").toString() + val durationregex = Regex("((\\d+) min)") + val yearegex = Regex("(\\d+)") + val duration = if (durationdoc.contains("na min")) null + else durationregex.find(durationdoc)?.destructured?.component1()?.replace(" min", "") + ?.toIntOrNull() + val year = if (mainUrl == "https://bflix.ru") { + yearegex.find(durationdoc)?.destructured?.component1() + ?.replace(Regex("|"), "") + } else null + return when (tvType) { + TvType.TvSeries -> { + TvSeriesLoadResponse( + title, + url, + this.name, + tvType, + episodes, + poster, + year?.toIntOrNull(), + description, + null, + rating, + tags, + recommendations = recommendations, + duration = duration, + ) + } + TvType.Movie -> { + MovieLoadResponse( + title, + url, + this.name, + tvType, + url, + poster, + year?.toIntOrNull(), + description, + rating, + tags, + recommendations = recommendations, + duration = duration + ) + } + else -> null + } + } + + + data class Subtitles( + @JsonProperty("file") val file: String, + @JsonProperty("label") val label: String, + @JsonProperty("kind") val kind: String + ) + + data class Links( + @JsonProperty("url") val url: String + ) + + data class Servers( + @JsonProperty("28") val mcloud: String?, + @JsonProperty("35") val mp4upload: String?, + @JsonProperty("40") val streamtape: String?, + @JsonProperty("41") val vidstream: String?, + @JsonProperty("43") val videovard: String? + ) + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val soup = app.get(data).document + + val movieid = encode(soup.selectFirst("div#watch")?.attr("data-id") ?: return false) + val movieidencoded = encodeVrf(movieid, mainKey) + Jsoup.parse( + parseJson( + app.get( + "$mainUrl/ajax/film/servers?id=$movieid&vrf=$movieidencoded" + ).text + ).html + ) + .select("html body #episodes").map { + val cleandata = data.replace(mainUrl, "") + val a = it.select("a").map { + it.attr("data-kname") + } + val tvType = + if (data.contains("movie/") && a.size == 1) TvType.Movie else TvType.TvSeries + val servers = if (tvType == TvType.Movie) it.select(".episode a").attr("data-ep") + else + it.select(".episode a[href=$cleandata]").attr("data-ep") + ?: it.select(".episode a[href=${cleandata.replace("/1-full", "")}]") + .attr("data-ep") + val jsonservers = parseJson(servers) ?: return@map + listOfNotNull( + jsonservers.vidstream, + jsonservers.mcloud, + jsonservers.mp4upload, + jsonservers.streamtape, + jsonservers.videovard, + ).mapNotNull { + val epserver = app.get("$mainUrl/ajax/episode/info?id=$it").text + (if (epserver.contains("url")) { + parseJson(epserver) + } else null)?.url?.let { + decodeVrf(it, mainKey) + } + }.apmap { url -> + loadExtractor( + url, data, subtitleCallback, callback + ) + } + //Apparently any server works, I haven't found any diference + val sublink = + app.get("$mainUrl/ajax/episode/subtitles/${jsonservers.mcloud}").text + val jsonsub = parseJson>(sublink) + jsonsub.forEach { subtitle -> + subtitleCallback( + SubtitleFile(subtitle.label, subtitle.file) + ) + } + } + + return true + } +} diff --git a/BflixProvider/src/main/kotlin/com/lagradost/BflixProviderPlugin.kt b/BflixProvider/src/main/kotlin/com/lagradost/BflixProviderPlugin.kt new file mode 100644 index 0000000..fd7de36 --- /dev/null +++ b/BflixProvider/src/main/kotlin/com/lagradost/BflixProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class BflixProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(BflixProvider()) + } +} \ No newline at end of file diff --git a/CinecalidadProvider/build.gradle.kts b/CinecalidadProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/CinecalidadProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/CinecalidadProvider/src/main/AndroidManifest.xml b/CinecalidadProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/CinecalidadProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProvider.kt b/CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProvider.kt new file mode 100644 index 0000000..fbeca40 --- /dev/null +++ b/CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProvider.kt @@ -0,0 +1,258 @@ +package com.lagradost + +import com.lagradost.cloudstream3.* +// import com.lagradost.cloudstream3.extractors.Cinestart +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor + +class CinecalidadProvider : MainAPI() { + override var mainUrl = "https://cinecalidad.lol" + override var name = "Cinecalidad" + override var lang = "es" + override val hasMainPage = true + override val hasChromecastSupport = true + override val hasDownloadSupport = true + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + ) + override val vpnStatus = VPNStatus.MightBeNeeded //Due to evoload sometimes not loading + + override val mainPage = mainPageOf( + Pair("$mainUrl/ver-serie/page/", "Series"), + Pair("$mainUrl/page/", "Peliculas"), + Pair("$mainUrl/genero-de-la-pelicula/peliculas-en-calidad-4k/page/", "4K UHD"), + ) + + override suspend fun getMainPage( + page: Int, + request : MainPageRequest + ): HomePageResponse { + val url = request.data + page + + val soup = app.get(url).document + val home = soup.select(".item.movies").map { + val title = it.selectFirst("div.in_title")!!.text() + val link = it.selectFirst("a")!!.attr("href") + TvSeriesSearchResponse( + title, + link, + this.name, + if (link.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries, + it.selectFirst(".poster.custom img")!!.attr("data-src"), + null, + null, + ) + } + + return newHomePageResponse(request.name, home) + } + + override suspend fun search(query: String): List { + val url = "$mainUrl/?s=${query}" + val document = app.get(url).document + + return document.select("article").map { + val title = it.selectFirst("div.in_title")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst(".poster.custom img")!!.attr("data-src") + val isMovie = href.contains("/ver-pelicula/") + + if (isMovie) { + MovieSearchResponse( + title, + href, + this.name, + TvType.Movie, + image, + null + ) + } else { + TvSeriesSearchResponse( + title, + href, + this.name, + TvType.TvSeries, + image, + null, + null + ) + } + } + } + + + override suspend fun load(url: String): LoadResponse? { + val soup = app.get(url, timeout = 120).document + + val title = soup.selectFirst(".single_left h1")!!.text() + val description = soup.selectFirst("div.single_left table tbody tr td p")?.text()?.trim() + val poster: String? = soup.selectFirst(".alignnone")!!.attr("data-src") + val episodes = soup.select("div.se-c div.se-a ul.episodios li").map { li -> + val href = li.selectFirst("a")!!.attr("href") + val epThumb = li.selectFirst("img.lazy")!!.attr("data-src") + val name = li.selectFirst(".episodiotitle a")!!.text() + val seasonid = + li.selectFirst(".numerando")!!.text().replace(Regex("(S|E)"), "").let { str -> + str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() } + } + val isValid = seasonid.size == 2 + val episode = if (isValid) seasonid.getOrNull(1) else null + val season = if (isValid) seasonid.getOrNull(0) else null + Episode( + href, + name, + season, + episode, + if (epThumb.contains("svg")) null else epThumb + ) + } + return when (val tvType = + if (url.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries) { + TvType.TvSeries -> { + TvSeriesLoadResponse( + title, + url, + this.name, + tvType, + episodes, + poster, + null, + description, + ) + } + TvType.Movie -> { + MovieLoadResponse( + title, + url, + this.name, + tvType, + url, + poster, + null, + description, + ) + } + else -> null + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + val datam = app.get(data) + val doc = datam.document + val datatext = datam.text + + doc.select(".dooplay_player_option").apmap { + val url = it.attr("data-option") +// if (url.startsWith("https://cinestart.net")) { +// val extractor = Cinestart() +// extractor.getSafeUrl(url, null, subtitleCallback, callback) +// } else { + loadExtractor(url, mainUrl, subtitleCallback, callback) +// } + if (url.startsWith("https://cinecalidad.lol")) { + val cineurlregex = + Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + cineurlregex.findAll(url).map { + it.value.replace("/play/", "/play/r.php") + }.toList().apmap { + app.get( + it, + headers = mapOf( + "Host" to "cinecalidad.lol", + "User-Agent" to USER_AGENT, + "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language" to "en-US,en;q=0.5", + "DNT" to "1", + "Connection" to "keep-alive", + "Referer" to data, + "Upgrade-Insecure-Requests" to "1", + "Sec-Fetch-Dest" to "iframe", + "Sec-Fetch-Mode" to "navigate", + "Sec-Fetch-Site" to "same-origin", + "Sec-Fetch-User" to "?1", + ), + allowRedirects = false + ).okhttpResponse.headers.values("location").apmap { extractedurl -> + if (extractedurl.contains("cinestart")) { + loadExtractor(extractedurl, mainUrl, subtitleCallback, callback) + } + } + } + } + } + if (datatext.contains("en castellano")) app.get("$data?ref=es").document.select(".dooplay_player_option") + .apmap { + val url = it.attr("data-option") +// if (url.startsWith("https://cinestart.net")) { +// val extractor = Cinestart() +// extractor.getSafeUrl(url, null, subtitleCallback, callback) +// } else { + loadExtractor(url, mainUrl, subtitleCallback, callback) +// } + + if (url.startsWith("https://cinecalidad.lol")) { + val cineurlregex = + Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + cineurlregex.findAll(url).map { + it.value.replace("/play/", "/play/r.php") + }.toList().apmap { + app.get( + it, + headers = mapOf( + "Host" to "cinecalidad.lol", + "User-Agent" to USER_AGENT, + "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language" to "en-US,en;q=0.5", + "DNT" to "1", + "Connection" to "keep-alive", + "Referer" to data, + "Upgrade-Insecure-Requests" to "1", + "Sec-Fetch-Dest" to "iframe", + "Sec-Fetch-Mode" to "navigate", + "Sec-Fetch-Site" to "same-origin", + "Sec-Fetch-User" to "?1", + ), + allowRedirects = false + ).okhttpResponse.headers.values("location").apmap { extractedurl -> + if (extractedurl.contains("cinestart")) { + loadExtractor(extractedurl, mainUrl, subtitleCallback, callback) + } + } + } + } + } + if (datatext.contains("Subtítulo LAT") || datatext.contains("Forzados LAT")) { + doc.select("#panel_descarga.pane a").apmap { + val link = + if (data.contains("serie") || data.contains("episodio")) "${data}${it.attr("href")}" + else it.attr("href") + val docsub = app.get(link) + val linksub = docsub.document + val validsub = docsub.text + if (validsub.contains("Subtítulo") || validsub.contains("Forzados")) { + val langregex = Regex("(Subtítulo.*\$|Forzados.*\$)") + val langdoc = linksub.selectFirst("div.titulo h3")!!.text() + val reallang = langregex.find(langdoc)?.destructured?.component1() + linksub.select("a.link").apmap { + val sublink = + if (data.contains("serie") || data.contains("episodio")) "${data}${ + it.attr("href") + }" + else it.attr("href") + subtitleCallback( + SubtitleFile(reallang!!, sublink) + ) + } + } + } + } + return true + } +} diff --git a/CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProviderPlugin.kt b/CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProviderPlugin.kt new file mode 100644 index 0000000..cf4a2ca --- /dev/null +++ b/CinecalidadProvider/src/main/kotlin/com/lagradost/CinecalidadProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class CinecalidadProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(CinecalidadProvider()) + } +} \ No newline at end of file diff --git a/CuevanaProvider/build.gradle.kts b/CuevanaProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/CuevanaProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/CuevanaProvider/src/main/AndroidManifest.xml b/CuevanaProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/CuevanaProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProvider.kt b/CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProvider.kt new file mode 100644 index 0000000..9aab603 --- /dev/null +++ b/CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProvider.kt @@ -0,0 +1,324 @@ +package com.lagradost + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.mvvm.logError +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor + +class CuevanaProvider : MainAPI() { + override var mainUrl = "https://cuevana3.me" + override var name = "Cuevana" + override var lang = "es" + override val hasMainPage = true + override val hasChromecastSupport = true + override val hasDownloadSupport = true + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + ) + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + val items = ArrayList() + val urls = listOf( + Pair(mainUrl, "Recientemente actualizadas"), + Pair("$mainUrl/estrenos/", "Estrenos"), + ) + items.add( + HomePageList( + "Series", + app.get("$mainUrl/serie", timeout = 120).document.select("section.home-series li") + .map { + val title = it.selectFirst("h2.Title")!!.text() + val poster = it.selectFirst("img.lazy")!!.attr("data-src") + val url = it.selectFirst("a")!!.attr("href") + TvSeriesSearchResponse( + title, + url, + this.name, + TvType.Anime, + poster, + null, + null, + ) + }) + ) + for ((url, name) in urls) { + try { + val soup = app.get(url).document + val home = soup.select("section li.xxx.TPostMv").map { + val title = it.selectFirst("h2.Title")!!.text() + val link = it.selectFirst("a")!!.attr("href") + TvSeriesSearchResponse( + title, + link, + this.name, + if (link.contains("/pelicula/")) TvType.Movie else TvType.TvSeries, + it.selectFirst("img.lazy")!!.attr("data-src"), + null, + null, + ) + } + + items.add(HomePageList(name, home)) + } catch (e: Exception) { + logError(e) + } + } + + if (items.size <= 0) throw ErrorLoadingException() + return HomePageResponse(items) + } + + override suspend fun search(query: String): List { + val url = "$mainUrl/?s=${query}" + val document = app.get(url).document + + return document.select("li.xxx.TPostMv").map { + val title = it.selectFirst("h2.Title")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst("img.lazy")!!.attr("data-src") + val isSerie = href.contains("/serie/") + + if (isSerie) { + TvSeriesSearchResponse( + title, + href, + this.name, + TvType.TvSeries, + image, + null, + null + ) + } else { + MovieSearchResponse( + title, + href, + this.name, + TvType.Movie, + image, + null + ) + } + } + } + + override suspend fun load(url: String): LoadResponse? { + val soup = app.get(url, timeout = 120).document + val title = soup.selectFirst("h1.Title")!!.text() + val description = soup.selectFirst(".Description p")?.text()?.trim() + val poster: String? = soup.selectFirst(".movtv-info div.Image img")!!.attr("data-src") + val year1 = soup.selectFirst("footer p.meta").toString() + val yearRegex = Regex("(\\d+)") + val yearf = + yearRegex.find(year1)?.destructured?.component1()?.replace(Regex("|"), "") + val year = if (yearf.isNullOrBlank()) null else yearf.toIntOrNull() + val episodes = soup.select(".all-episodes li.TPostMv article").map { li -> + val href = li.select("a").attr("href") + val epThumb = + li.selectFirst("div.Image img")?.attr("data-src") ?: li.selectFirst("img.lazy")!! + .attr("data-srcc") + val seasonid = li.selectFirst("span.Year")!!.text().let { str -> + str.split("x").mapNotNull { subStr -> subStr.toIntOrNull() } + } + val isValid = seasonid.size == 2 + val episode = if (isValid) seasonid.getOrNull(1) else null + val season = if (isValid) seasonid.getOrNull(0) else null + Episode( + href, + null, + season, + episode, + fixUrl(epThumb) + ) + } + val tags = soup.select("ul.InfoList li.AAIco-adjust:contains(Genero) a").map { it.text() } + val tvType = if (episodes.isEmpty()) TvType.Movie else TvType.TvSeries + val recelement = + if (tvType == TvType.TvSeries) "main section div.series_listado.series div.xxx" + else "main section ul.MovieList li" + val recommendations = + soup.select(recelement).mapNotNull { element -> + val recTitle = element.select("h2.Title").text() ?: return@mapNotNull null + val image = element.select("figure img")?.attr("data-src") + val recUrl = fixUrl(element.select("a").attr("href")) + MovieSearchResponse( + recTitle, + recUrl, + this.name, + TvType.Movie, + image, + year = null + ) + } + + return when (tvType) { + TvType.TvSeries -> { + TvSeriesLoadResponse( + title, + url, + this.name, + tvType, + episodes, + poster, + year, + description, + tags = tags, + recommendations = recommendations + ) + } + TvType.Movie -> { + MovieLoadResponse( + title, + url, + this.name, + tvType, + url, + poster, + year, + description, + tags = tags, + recommendations = recommendations + ) + } + else -> null + } + } + + data class Femcuevana( + @JsonProperty("url") val url: String, + ) + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + app.get(data).document.select("div.TPlayer.embed_div iframe").apmap { + val iframe = fixUrl(it.attr("data-src")) + if (iframe.contains("api.cuevana3.me/fembed/")) { + val femregex = + Regex("(https.\\/\\/api\\.cuevana3\\.me\\/fembed\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + femregex.findAll(iframe).map { femreg -> + femreg.value + }.toList().apmap { fem -> + val key = fem.replace("https://api.cuevana3.me/fembed/?h=", "") + val url = app.post( + "https://api.cuevana3.me/fembed/api.php", + allowRedirects = false, + headers = mapOf( + "Host" to "api.cuevana3.me", + "User-Agent" to USER_AGENT, + "Accept" to "application/json, text/javascript, */*; q=0.01", + "Accept-Language" to "en-US,en;q=0.5", + "Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8", + "X-Requested-With" to "XMLHttpRequest", + "Origin" to "https://api.cuevana3.me", + "DNT" to "1", + "Connection" to "keep-alive", + "Sec-Fetch-Dest" to "empty", + "Sec-Fetch-Mode" to "cors", + "Sec-Fetch-Site" to "same-origin", + ), + data = mapOf(Pair("h", key)) + ).text + val json = parseJson(url) + val link = json.url + if (link.contains("fembed")) { + loadExtractor(link, data, subtitleCallback, callback) + } + } + } + if (iframe.contains("tomatomatela")) { + val tomatoRegex = + Regex("(\\/\\/apialfa.tomatomatela.com\\/ir\\/player.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + tomatoRegex.findAll(iframe).map { tomreg -> + tomreg.value + }.toList().apmap { tom -> + val tomkey = tom.replace("//apialfa.tomatomatela.com/ir/player.php?h=", "") + app.post( + "https://apialfa.tomatomatela.com/ir/rd.php", allowRedirects = false, + headers = mapOf( + "Host" to "apialfa.tomatomatela.com", + "User-Agent" to USER_AGENT, + "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language" to "en-US,en;q=0.5", + "Content-Type" to "application/x-www-form-urlencoded", + "Origin" to "null", + "DNT" to "1", + "Connection" to "keep-alive", + "Upgrade-Insecure-Requests" to "1", + "Sec-Fetch-Dest" to "iframe", + "Sec-Fetch-Mode" to "navigate", + "Sec-Fetch-Site" to "same-origin", + ), + data = mapOf(Pair("url", tomkey)) + ).okhttpResponse.headers.values("location").apmap { loc -> + if (loc.contains("goto_ddh.php")) { + val gotoregex = + Regex("(\\/\\/api.cuevana3.me\\/ir\\/goto_ddh.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + gotoregex.findAll(loc).map { goreg -> + goreg.value.replace("//api.cuevana3.me/ir/goto_ddh.php?h=", "") + }.toList().apmap { gotolink -> + app.post( + "https://api.cuevana3.me/ir/redirect_ddh.php", + allowRedirects = false, + headers = mapOf( + "Host" to "api.cuevana3.me", + "User-Agent" to USER_AGENT, + "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language" to "en-US,en;q=0.5", + "Content-Type" to "application/x-www-form-urlencoded", + "Origin" to "null", + "DNT" to "1", + "Connection" to "keep-alive", + "Upgrade-Insecure-Requests" to "1", + "Sec-Fetch-Dest" to "iframe", + "Sec-Fetch-Mode" to "navigate", + "Sec-Fetch-Site" to "same-origin", + ), + data = mapOf(Pair("url", gotolink)) + ).okhttpResponse.headers.values("location").apmap { golink -> + loadExtractor(golink, data, subtitleCallback, callback) + } + } + } + if (loc.contains("index.php?h=")) { + val indexRegex = + Regex("(\\/\\/api.cuevana3.me\\/sc\\/index.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + indexRegex.findAll(loc).map { indreg -> + indreg.value.replace("//api.cuevana3.me/sc/index.php?h=", "") + }.toList().apmap { inlink -> + app.post( + "https://api.cuevana3.me/sc/r.php", allowRedirects = false, + headers = mapOf( + "Host" to "api.cuevana3.me", + "User-Agent" to USER_AGENT, + "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language" to "en-US,en;q=0.5", + "Accept-Encoding" to "gzip, deflate, br", + "Content-Type" to "application/x-www-form-urlencoded", + "Origin" to "null", + "DNT" to "1", + "Connection" to "keep-alive", + "Upgrade-Insecure-Requests" to "1", + "Sec-Fetch-Dest" to "iframe", + "Sec-Fetch-Mode" to "navigate", + "Sec-Fetch-Site" to "same-origin", + "Sec-Fetch-User" to "?1", + ), + data = mapOf(Pair("h", inlink)) + ).okhttpResponse.headers.values("location").apmap { link -> + loadExtractor(link, data, subtitleCallback, callback) + } + } + } + } + } + } + } + return true + } +} \ No newline at end of file diff --git a/CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProviderPlugin.kt b/CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProviderPlugin.kt new file mode 100644 index 0000000..a126075 --- /dev/null +++ b/CuevanaProvider/src/main/kotlin/com/lagradost/CuevanaProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class CuevanaProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(CuevanaProvider()) + } +} \ No newline at end of file diff --git a/DopeboxProvider/build.gradle.kts b/DopeboxProvider/build.gradle.kts new file mode 100644 index 0000000..704695e --- /dev/null +++ b/DopeboxProvider/build.gradle.kts @@ -0,0 +1,25 @@ +dependencies { +// implementation(project(mapOf("path" to ":SflixProvider"))) +} +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/DopeboxProvider/src/main/AndroidManifest.xml b/DopeboxProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/DopeboxProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProvider.kt b/DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProvider.kt new file mode 100644 index 0000000..fbcb65e --- /dev/null +++ b/DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProvider.kt @@ -0,0 +1,6 @@ +package com.lagradost + +class DopeboxProvider : SflixProvider() { + override var mainUrl = "https://dopebox.to" + override var name = "Dopebox" +} \ No newline at end of file diff --git a/DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProviderPlugin.kt b/DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProviderPlugin.kt new file mode 100644 index 0000000..431e308 --- /dev/null +++ b/DopeboxProvider/src/main/kotlin/com/lagradost/DopeboxProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class DopeboxProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(DopeboxProvider()) + } +} \ No newline at end of file diff --git a/DoramasYTProvider/build.gradle.kts b/DoramasYTProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/DoramasYTProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/DoramasYTProvider/src/main/AndroidManifest.xml b/DoramasYTProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/DoramasYTProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProvider.kt b/DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProvider.kt new file mode 100644 index 0000000..f4d0e99 --- /dev/null +++ b/DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProvider.kt @@ -0,0 +1,155 @@ +package com.lagradost + +import com.lagradost.cloudstream3.* +//import com.lagradost.cloudstream3.extractors.FEmbed +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor +import java.util.* + + +class DoramasYTProvider : MainAPI() { + companion object { + fun getType(t: String): TvType { + return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA + else if (t.contains("Pelicula")) TvType.Movie + else TvType.TvSeries + } + fun getDubStatus(title: String): DubStatus { + return if (title.contains("Latino") || title.contains("Castellano")) + DubStatus.Dubbed + else DubStatus.Subbed + } + } + + override var mainUrl = "https://doramasyt.com" + override var name = "DoramasYT" + override var lang = "es" + override val hasMainPage = true + override val hasChromecastSupport = true + override val hasDownloadSupport = true + override val supportedTypes = setOf( + TvType.AsianDrama, + ) + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + val urls = listOf( + Pair("$mainUrl/emision", "En emisión"), + Pair( + "$mainUrl/doramas?categoria=pelicula&genero=false&fecha=false&letra=false", + "Peliculas" + ), + Pair("$mainUrl/doramas", "Doramas"), + Pair( + "$mainUrl/doramas?categoria=live-action&genero=false&fecha=false&letra=false", + "Live Action" + ), + ) + + val items = ArrayList() + + items.add( + HomePageList( + "Capítulos actualizados", + app.get(mainUrl, timeout = 120).document.select(".col-6").map { + val title = it.selectFirst("p")!!.text() + val poster = it.selectFirst(".chapter img")!!.attr("src") + val epRegex = Regex("episodio-(\\d+)") + val url = it.selectFirst("a")!!.attr("href").replace("ver/", "dorama/") + .replace(epRegex, "sub-espanol") + val epNum = it.selectFirst("h3")!!.text().toIntOrNull() + newAnimeSearchResponse(title,url) { + this.posterUrl = fixUrl(poster) + addDubStatus(getDubStatus(title), epNum) + } + }) + ) + + for (i in urls) { + try { + val home = app.get(i.first, timeout = 120).document.select(".col-6").map { + val title = it.selectFirst(".animedtls p")!!.text() + val poster = it.selectFirst(".anithumb img")!!.attr("src") + newAnimeSearchResponse(title, fixUrl(it.selectFirst("a")!!.attr("href"))) { + this.posterUrl = fixUrl(poster) + addDubStatus(getDubStatus(title)) + } + } + + items.add(HomePageList(i.second, home)) + } catch (e: Exception) { + e.printStackTrace() + } + } + + if (items.size <= 0) throw ErrorLoadingException() + return HomePageResponse(items) + } + + override suspend fun search(query: String): List { + return app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map { + val title = it.selectFirst(".animedtls p")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst(".animes img")!!.attr("src") + AnimeSearchResponse( + title, + href, + this.name, + TvType.Anime, + image, + null, + if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( + DubStatus.Dubbed + ) else EnumSet.of(DubStatus.Subbed), + ) + } + } + + override suspend fun load(url: String): LoadResponse { + val doc = app.get(url, timeout = 120).document + val poster = doc.selectFirst("div.flimimg img.img1")!!.attr("src") + val title = doc.selectFirst("h1")!!.text() + val type = doc.selectFirst("h4")!!.text() + val description = doc.selectFirst("p.textComplete")!!.text().replace("Ver menos", "") + val genres = doc.select(".nobel a").map { it.text() } + val status = when (doc.selectFirst(".state h6")?.text()) { + "Estreno" -> ShowStatus.Ongoing + "Finalizado" -> ShowStatus.Completed + else -> null + } + val episodes = doc.select(".heromain .col-item").map { + val name = it.selectFirst(".dtlsflim p")!!.text() + val link = it.selectFirst("a")!!.attr("href") + val epThumb = it.selectFirst(".flimimg img.img1")!!.attr("src") + Episode(link, name, posterUrl = epThumb) + } + return newAnimeLoadResponse(title, url, getType(type)) { + posterUrl = poster + addEpisodes(DubStatus.Subbed, episodes) + showStatus = status + plot = description + tags = genres + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + app.get(data).document.select("div.playother p").apmap { + val encodedurl = it.select("p").attr("data-player") + val urlDecoded = base64Decode(encodedurl) + val url = (urlDecoded).replace("https://doramasyt.com/reproductor?url=", "") +// if (url.startsWith("https://www.fembed.com")) { +// val extractor = FEmbed() +// extractor.getUrl(url).forEach { link -> +// callback.invoke(link) +// } +// } else { + loadExtractor(url, mainUrl, subtitleCallback, callback) +// } + } + return true + } +} \ No newline at end of file diff --git a/DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProviderPlugin.kt b/DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProviderPlugin.kt new file mode 100644 index 0000000..e5652d9 --- /dev/null +++ b/DoramasYTProvider/src/main/kotlin/com/lagradost/DoramasYTProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class DoramasYTProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(DoramasYTProvider()) + } +} \ No newline at end of file diff --git a/DramaSeeProvider/build.gradle.kts b/DramaSeeProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/DramaSeeProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/DramaSeeProvider/src/main/AndroidManifest.xml b/DramaSeeProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/DramaSeeProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProvider.kt b/DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProvider.kt new file mode 100644 index 0000000..22ccc56 --- /dev/null +++ b/DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProvider.kt @@ -0,0 +1,217 @@ +package com.lagradost + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor + +class DramaSeeProvider : MainAPI() { + override var mainUrl = "https://dramasee.net" + override var name = "DramaSee" + override val hasQuickSearch = false + override val hasMainPage = true + override val hasChromecastSupport = false + override val hasDownloadSupport = true + override val supportedTypes = setOf(TvType.AsianDrama) + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + val headers = mapOf("X-Requested-By" to mainUrl) + val document = app.get(mainUrl, headers = headers).document + val mainbody = document.getElementsByTag("body") + + return HomePageResponse( + mainbody.select("section.block_area.block_area_home")?.map { main -> + val title = main.select("h2.cat-heading").text() ?: "Main" + val inner = main.select("div.flw-item") ?: return@map null + + HomePageList( + title, + inner.mapNotNull { + val innerBody = it?.selectFirst("a") + // Fetch details + val link = fixUrlNull(innerBody?.attr("href")) ?: return@mapNotNull null + val image = fixUrlNull(it.select("img").attr("data-src")) ?: "" + val name = innerBody?.attr("title") ?: "" + //Log.i(this.name, "Result => (innerBody, image) ${innerBody} / ${image}") + MovieSearchResponse( + name, + link, + this.name, + TvType.AsianDrama, + image, + year = null, + id = null, + ) + }.distinctBy { c -> c.url }) + }?.filterNotNull() ?: listOf() + ) + } + + override suspend fun search(query: String): List { + val url = "$mainUrl/search?q=$query" + val document = app.get(url).document + val posters = document.select("div.film-poster") + + + return posters.mapNotNull { + val innerA = it.select("a") ?: return@mapNotNull null + val link = fixUrlNull(innerA.attr("href")) ?: return@mapNotNull null + val title = innerA.attr("title") ?: return@mapNotNull null + val year = + Regex(""".*\((\d{4})\)""").find(title)?.groupValues?.getOrNull(1)?.toIntOrNull() + val imgSrc = it.select("img")?.attr("data-src") ?: return@mapNotNull null + val image = fixUrlNull(imgSrc) + + MovieSearchResponse( + name = title, + url = link, + apiName = this.name, + type = TvType.Movie, + posterUrl = image, + year = year + ) + } + } + + override suspend fun load(url: String): LoadResponse { + val doc = app.get(url).document + val body = doc.getElementsByTag("body") + val inner = body?.select("div.anis-content") + + // Video details + val poster = fixUrlNull(inner?.select("img.film-poster-img")?.attr("src")) ?: "" + //Log.i(this.name, "Result => (imgLinkCode) ${imgLinkCode}") + val title = inner?.select("h2.film-name.dynamic-name")?.text() ?: "" + val year = if (title.length > 5) { + title.substring(title.length - 5) + .trim().trimEnd(')').toIntOrNull() + } else { + null + } + //Log.i(this.name, "Result => (year) ${title.substring(title.length - 5)}") + val descript = body?.firstOrNull()?.select("div.film-description.m-hide")?.text() + val tags = inner?.select("div.item.item-list > a") + ?.mapNotNull { it?.text()?.trim() ?: return@mapNotNull null } + val recs = body.select("div.flw-item")?.mapNotNull { + val a = it.select("a") ?: return@mapNotNull null + val aUrl = fixUrlNull(a.attr("href")) ?: return@mapNotNull null + val aImg = fixUrlNull(it.select("img")?.attr("data-src")) + val aName = a.attr("title") ?: return@mapNotNull null + val aYear = aName.trim().takeLast(5).removeSuffix(")").toIntOrNull() + MovieSearchResponse( + url = aUrl, + name = aName, + type = TvType.Movie, + posterUrl = aImg, + year = aYear, + apiName = this.name + ) + } + + // Episodes Links + val episodeUrl = body.select("a.btn.btn-radius.btn-primary.btn-play").attr("href") + val episodeDoc = app.get(episodeUrl).document + + + val episodeList = episodeDoc.select("div.ss-list.ss-list-min > a").mapNotNull { ep -> + val episodeNumber = ep.attr("data-number").toIntOrNull() + val epLink = fixUrlNull(ep.attr("href")) ?: return@mapNotNull null + +// if (epLink.isNotBlank()) { +// // Fetch video links +// val epVidLinkEl = app.get(epLink, referer = mainUrl).document +// val ajaxUrl = epVidLinkEl.select("div#js-player")?.attr("embed") +// //Log.i(this.name, "Result => (ajaxUrl) ${ajaxUrl}") +// if (!ajaxUrl.isNullOrEmpty()) { +// val innerPage = app.get(fixUrl(ajaxUrl), referer = epLink).document +// val listOfLinks = mutableListOf() +// innerPage.select("div.player.active > main > div")?.forEach { em -> +// val href = fixUrlNull(em.attr("src")) ?: "" +// if (href.isNotBlank()) { +// listOfLinks.add(href) +// } +// } +// +// //Log.i(this.name, "Result => (listOfLinks) ${listOfLinks.toJson()}") +// +// } +// } + Episode( + name = null, + season = null, + episode = episodeNumber, + data = epLink, + posterUrl = null, + date = null + ) + } + + //If there's only 1 episode, consider it a movie. + if (episodeList.size == 1) { + return MovieLoadResponse( + name = title, + url = url, + apiName = this.name, + type = TvType.Movie, + dataUrl = episodeList.first().data, + posterUrl = poster, + year = year, + plot = descript, + recommendations = recs, + tags = tags + ) + } + return TvSeriesLoadResponse( + name = title, + url = url, + apiName = this.name, + type = TvType.AsianDrama, + episodes = episodeList, + posterUrl = poster, + year = year, + plot = descript, + recommendations = recs, + tags = tags + ) + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + println("DATATATAT $data") + + val document = app.get(data).document + val iframeUrl = document.select("iframe").attr("src") + val iframe = app.get(iframeUrl) + val iframeDoc = iframe.document + + argamap({ + iframeDoc.select(".list-server-items > .linkserver") + .forEach { element -> + val status = element.attr("data-status") ?: return@forEach + if (status != "1") return@forEach + val extractorData = element.attr("data-video") ?: return@forEach + loadExtractor(extractorData, iframe.url, subtitleCallback, callback) + } + }, { + val iv = "9262859232435825" + val secretKey = "93422192433952489752342908585752" + val secretDecryptKey = "93422192433952489752342908585752" + extractVidstream( + iframe.url, + this.name, + callback, + iv, + secretKey, + secretDecryptKey, + isUsingAdaptiveKeys = false, + isUsingAdaptiveData = true, + iframeDocument = iframeDoc + ) + }) + return true + } +} diff --git a/DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProviderPlugin.kt b/DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProviderPlugin.kt new file mode 100644 index 0000000..ea2b88a --- /dev/null +++ b/DramaSeeProvider/src/main/kotlin/com/lagradost/DramaSeeProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class DramaSeeProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(DramaSeeProvider()) + } +} \ No newline at end of file diff --git a/DramaidProvider/build.gradle.kts b/DramaidProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/DramaidProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/DramaidProvider/src/main/AndroidManifest.xml b/DramaidProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/DramaidProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/DramaidProvider/src/main/kotlin/com/lagradost/DramaidProvider.kt b/DramaidProvider/src/main/kotlin/com/lagradost/DramaidProvider.kt new file mode 100644 index 0000000..318a5ca --- /dev/null +++ b/DramaidProvider/src/main/kotlin/com/lagradost/DramaidProvider.kt @@ -0,0 +1,213 @@ +package com.lagradost + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.cloudstream3.utils.loadExtractor +import org.jsoup.Jsoup +import org.jsoup.nodes.Element + +class DramaidProvider : MainAPI() { + override var mainUrl = "https://185.224.83.103" + override var name = "DramaId" + override val hasQuickSearch = false + override val hasMainPage = true + override var lang = "id" + override val hasDownloadSupport = true + override val hasChromecastSupport = false + override val supportedTypes = setOf(TvType.AsianDrama) + + companion object { + fun getStatus(t: String): ShowStatus { + return when (t) { + "Completed" -> ShowStatus.Completed + "Ongoing" -> ShowStatus.Ongoing + else -> ShowStatus.Completed + } + } + } + + override val mainPage = mainPageOf( + "&status=&type=&order=update" to "Drama Terbaru", + "&order=latest" to "Baru Ditambahkan", + "&status=&type=&order=popular" to "Drama Popular", + ) + + override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse { + val document = app.get("$mainUrl/series/?page=$page${request.data}").document + val home = document.select("article[itemscope=itemscope]").mapNotNull { + it.toSearchResult() + } + return newHomePageResponse(request.name, home) + } + + private fun getProperDramaLink(uri: String): String { + return if (uri.contains("/series/")) { + uri + } else { + "$mainUrl/series/" + Regex("$mainUrl/(.+)-ep.+").find(uri)?.groupValues?.get(1) + .toString() + } + } + + private fun Element.toSearchResult(): SearchResponse? { + val href = getProperDramaLink(this.selectFirst("a.tip")!!.attr("href")) + val title = this.selectFirst("h2[itemprop=headline]")?.text()?.trim() ?: return null + val posterUrl = fixUrlNull(this.selectFirst(".limit > noscript > img")?.attr("src")) + + return newTvSeriesSearchResponse(title, href, TvType.AsianDrama) { + this.posterUrl = posterUrl + } + } + + override suspend fun search(query: String): List { + val link = "$mainUrl/?s=$query" + val document = app.get(link).document + + return document.select("article[itemscope=itemscope]").map { + val title = it.selectFirst("h2[itemprop=headline]")!!.text().trim() + val poster = it.selectFirst(".limit > noscript > img")!!.attr("src") + val href = it.selectFirst("a.tip")!!.attr("href") + + newTvSeriesSearchResponse(title, href, TvType.AsianDrama) { + this.posterUrl = poster + } + } + } + + override suspend fun load(url: String): LoadResponse { + val document = app.get(url).document + + val title = document.selectFirst("h1.entry-title")!!.text().trim() + val poster = document.select(".thumb > noscript > img").attr("src") + val tags = document.select(".genxed > a").map { it.text() } + + val year = Regex("\\d, ([0-9]*)").find( + document.selectFirst(".info-content > .spe > span > time")!!.text().trim() + )?.groupValues?.get(1).toString().toIntOrNull() + val status = getStatus( + document.select(".info-content > .spe > span:nth-child(1)") + .text().trim().replace("Status: ", "") + ) + val description = document.select(".entry-content > p").text().trim() + + val episodes = document.select(".eplister > ul > li").map { + val name = it.selectFirst("a > .epl-title")!!.text().trim() + val link = it.select("a").attr("href") + val epNum = it.selectFirst("a > .epl-num")!!.text().trim().toIntOrNull() + newEpisode(link) { + this.name = name + this.episode = epNum + } + }.reversed() + + val recommendations = + document.select(".listupd > article[itemscope=itemscope]").map { rec -> + val epTitle = rec.selectFirst("h2[itemprop=headline]")!!.text().trim() + val epPoster = rec.selectFirst(".limit > noscript > img")!!.attr("src") + val epHref = fixUrl(rec.selectFirst("a.tip")!!.attr("href")) + + newTvSeriesSearchResponse(epTitle, epHref, TvType.AsianDrama) { + this.posterUrl = epPoster + } + } + + if (episodes.size == 1) { + return newMovieLoadResponse(title, url, TvType.Movie, episodes[0].data) { + posterUrl = poster + this.year = year + plot = description + this.tags = tags + this.recommendations = recommendations + } + } else { + return newTvSeriesLoadResponse(title, url, TvType.AsianDrama, episodes = episodes) { + posterUrl = poster + this.year = year + showStatus = status + plot = description + this.tags = tags + this.recommendations = recommendations + } + } + + } + + private data class Sources( + @JsonProperty("file") val file: String, + @JsonProperty("label") val label: String, + @JsonProperty("type") val type: String, + @JsonProperty("default") val default: Boolean? + ) + + private data class Tracks( + @JsonProperty("file") val file: String, + @JsonProperty("label") val label: String, + @JsonProperty("kind") val type: String, + @JsonProperty("default") val default: Boolean? + ) + + private suspend fun invokeDriveSource( + url: String, + name: String, + subCallback: (SubtitleFile) -> Unit, + sourceCallback: (ExtractorLink) -> Unit + ) { + val server = app.get(url).document.selectFirst(".picasa")?.nextElementSibling()?.data() + + val source = "[${server!!.substringAfter("sources: [").substringBefore("],")}]".trimIndent() + val trackers = server.substringAfter("tracks:[").substringBefore("],") + .replace("//language", "") + .replace("file", "\"file\"") + .replace("label", "\"label\"") + .replace("kind", "\"kind\"").trimIndent() + + tryParseJson>(source)?.map { + sourceCallback( + ExtractorLink( + name, + "Drive", + fixUrl(it.file), + referer = "https://motonews.club/", + quality = getQualityFromName(it.label) + ) + ) + } + + tryParseJson(trackers)?.let { + subCallback.invoke( + SubtitleFile( + if (it.label.contains("Indonesia")) "${it.label}n" else it.label, + it.file + ) + ) + } + + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val document = app.get(data).document + val sources = document.select(".mobius > .mirror > option").mapNotNull { + fixUrl(Jsoup.parse(base64Decode(it.attr("value"))).select("iframe").attr("src")) + } + + sources.map { + it.replace("https://ndrama.xyz", "https://www.fembed.com") + }.apmap { + when { + it.contains("motonews.club") -> invokeDriveSource(it, this.name, subtitleCallback, callback) + else -> loadExtractor(it, data, subtitleCallback, callback) + } + } + + return true + } + +} diff --git a/DramaidProvider/src/main/kotlin/com/lagradost/DramaidProviderPlugin.kt b/DramaidProvider/src/main/kotlin/com/lagradost/DramaidProviderPlugin.kt new file mode 100644 index 0000000..4ee73cb --- /dev/null +++ b/DramaidProvider/src/main/kotlin/com/lagradost/DramaidProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class DramaidProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(DramaidProvider()) + } +} \ No newline at end of file diff --git a/DubokuProvider/build.gradle.kts b/DubokuProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/DubokuProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/DubokuProvider/src/main/AndroidManifest.xml b/DubokuProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/DubokuProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/DubokuProvider/src/main/kotlin/com/lagradost/DubokuProvider.kt b/DubokuProvider/src/main/kotlin/com/lagradost/DubokuProvider.kt new file mode 100644 index 0000000..a71d781 --- /dev/null +++ b/DubokuProvider/src/main/kotlin/com/lagradost/DubokuProvider.kt @@ -0,0 +1,133 @@ +package com.lagradost + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addActors +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.M3u8Helper +import org.jsoup.nodes.Element + +class DubokuProvider : MainAPI() { + override var mainUrl = "https://www.duboku.tv" + override var name = "Duboku" + override val hasMainPage = true + override var lang = "zh" + override val hasDownloadSupport = true + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + TvType.AsianDrama, + ) + + override val mainPage = mainPageOf( + "$mainUrl/vodshow/2--time------" to "连续剧 时间", + "$mainUrl/vodshow/2--hits------" to "连续剧 人气", + "$mainUrl/vodshow/13--time------" to "陆剧 时间", + "$mainUrl/vodshow/13--hits------" to "陆剧 人气", + "$mainUrl/vodshow/15--time------" to "日韩剧 时间", + "$mainUrl/vodshow/15--hits------" to "日韩剧 人气", + "$mainUrl/vodshow/21--time------" to "短剧 时间", + "$mainUrl/vodshow/21--hits------" to "短剧 人气", + "$mainUrl/vodshow/16--time------" to "英美剧 时间", + "$mainUrl/vodshow/16--hits------" to "英美剧 人气", + "$mainUrl/vodshow/14--time------" to "台泰剧 时间", + "$mainUrl/vodshow/14--hits------" to "台泰剧 人气", + "$mainUrl/vodshow/20--time------" to "港剧 时间", + "$mainUrl/vodshow/20--hits------" to "港剧 人气", + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val document = app.get("${request.data}$page---.html").document + val home = document.select("ul.myui-vodlist.clearfix li").mapNotNull { + it.toSearchResult() + } + return newHomePageResponse(request.name, home) + } + + private fun Element.toSearchResult(): SearchResponse? { + val title = this.selectFirst("h4.title a")?.text()?.trim() ?: return null + val href = fixUrl(this.selectFirst("a")?.attr("href").toString()) + val posterUrl = fixUrlNull(this.selectFirst("a")?.attr("data-original")) + val episode = this.selectFirst("span.pic-text.text-right")?.text()?.filter { it.isDigit() } + ?.toIntOrNull() + + return newAnimeSearchResponse(title, href, TvType.Movie) { + this.posterUrl = posterUrl + addSub(episode) + } + } + + override suspend fun search(query: String): List { + val document = app.get("$mainUrl/vodsearch/-------------.html?wd=$query&submit=").document + + return document.select("ul#searchList li").mapNotNull { + it.toSearchResult() + } + } + + override suspend fun load(url: String): LoadResponse? { + val document = app.get(url).document + + val title = document.selectFirst("h1.title")?.text()?.trim() ?: return null + val tvType = if (document.select("ul.myui-content__list li").size == 1 + ) TvType.Movie else TvType.TvSeries + val actors = document.select("p.data")[2].select("a").map { it.text() } + + val episodes = document.select("ul.myui-content__list li").map { + val href = fixUrl(it.select("a").attr("href")) + val name = it.select("a").text().trim() + Episode( + data = href, + name = name, + ) + } + return newTvSeriesLoadResponse(title, url, tvType, episodes) { + this.posterUrl = fixUrlNull( + document.selectFirst("a.myui-vodlist__thumb.picture img")?.attr("data-original") + ) + this.year = + document.select("p.data")[0].select("a").last()?.text()?.trim()?.toIntOrNull() + this.plot = document.selectFirst("span.sketch.content")?.text()?.trim() + this.tags = document.select("p.data")[0].select("a").map { it.text() } + this.rating = document.select("div#rating span.branch").text().toRatingInt() + addActors(actors) + } + + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + app.get(data).document.select("script").map { script -> + if (script.data().contains("var player_data={")) { + val dataJson = + script.data().substringAfter("var player_data={").substringBefore("}") + tryParseJson("{$dataJson}")?.let { source -> + M3u8Helper.generateM3u8( + this.name, + source.url ?: return@map, + referer = "https://w.duboku.io/", + headers = mapOf("Origin" to "https://w.duboku.io") + ).forEach(callback) + } + } + } + + + return true + } + + data class Sources( + @JsonProperty("url") val url: String?, + ) + + +} \ No newline at end of file diff --git a/DubokuProvider/src/main/kotlin/com/lagradost/DubokuProviderPlugin.kt b/DubokuProvider/src/main/kotlin/com/lagradost/DubokuProviderPlugin.kt new file mode 100644 index 0000000..4c77005 --- /dev/null +++ b/DubokuProvider/src/main/kotlin/com/lagradost/DubokuProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class DubokuProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(DubokuProvider()) + } +} \ No newline at end of file diff --git a/EgyBestProvider/build.gradle.kts b/EgyBestProvider/build.gradle.kts new file mode 100644 index 0000000..e7d2158 --- /dev/null +++ b/EgyBestProvider/build.gradle.kts @@ -0,0 +1,22 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + // authors = listOf("Cloudburst") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + + // Set to true to get an 18+ symbol next to the plugin + adult = false // will be false if unspecified +} \ No newline at end of file diff --git a/EgyBestProvider/src/main/AndroidManifest.xml b/EgyBestProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/EgyBestProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/EgyBestProvider/src/main/kotlin/com/lagradost/EgyBestProvider.kt b/EgyBestProvider/src/main/kotlin/com/lagradost/EgyBestProvider.kt new file mode 100644 index 0000000..933b0f2 --- /dev/null +++ b/EgyBestProvider/src/main/kotlin/com/lagradost/EgyBestProvider.kt @@ -0,0 +1,237 @@ +package com.lagradost + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer +import org.jsoup.nodes.Element + +class EgyBestProvider : MainAPI() { + override var lang = "ar" + override var mainUrl = "https://www.egy.best" + override var name = "EgyBest" + override val usesWebView = false + override val hasMainPage = true + override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie, TvType.Anime) + + private fun String.getIntFromText(): Int? { + return Regex("""\d+""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull() + } + + private fun Element.toSearchResponse(): SearchResponse? { + val url = this.attr("href") ?: return null + val posterUrl = select("img")?.attr("src") + var title = select("span.title").text() + val year = title.getYearFromTitle() + val isMovie = Regex(".*/movie/.*|.*/masrahiya/.*").matches(url) + val tvType = if (isMovie) TvType.Movie else TvType.TvSeries + title = if (year !== null) title else title.split(" (")[0].trim() + val quality = select("span.ribbon span").text().replace("-", "") + // If you need to differentiate use the url. + return MovieSearchResponse( + title, + url, + this@EgyBestProvider.name, + tvType, + posterUrl, + year, + null, + quality = getQualityFromString(quality) + ) + } + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + // url, title + val doc = app.get(mainUrl).document + val pages = arrayListOf() + doc.select("#mainLoad div.mbox").apmap { + val name = it.select(".bdb.pda > strong").text() + if (it.select(".movie").first()?.attr("href")?.contains("season-(.....)|ep-(.....)".toRegex()) == true) return@apmap + val list = arrayListOf() + it.select(".movie").map { element -> + list.add(element.toSearchResponse()!!) + } + pages.add(HomePageList(name, list)) + } + return HomePageResponse(pages) + } + + override suspend fun search(query: String): List { + val q = query.replace(" ","%20") + val result = arrayListOf() + listOf("$mainUrl/explore/?q=$q").apmap { url -> + val d = app.get(url).document + d.select("div.movies a").not("a.auto.load.btn.b").mapNotNull { + it.toSearchResponse()?.let { it1 -> result.add(it1) } + } + } + return result.distinct().sortedBy { it.name } + } + + private fun String.getYearFromTitle(): Int? { + return Regex("""\(\d{4}\)""").find(this)?.groupValues?.firstOrNull()?.toIntOrNull() + } + + override suspend fun load(url: String): LoadResponse { + val doc = app.get(url).document + val isMovie = Regex(".*/movie/.*|.*/masrahiya/.*").matches(url) + val posterUrl = doc.select("div.movie_img a img")?.attr("src") + val year = doc.select("div.movie_title h1 a")?.text()?.toIntOrNull() + val title = doc.select("div.movie_title h1 span").text() + val youtubeTrailer = doc.select("div.play")?.attr("url") + + val synopsis = doc.select("div.mbox").firstOrNull { + it.text().contains("القصة") + }?.text()?.replace("القصة ", "") + + val tags = doc.select("table.movieTable tbody tr").firstOrNull { + it.text().contains("النوع") + }?.select("a")?.map { it.text() } + + val actors = doc.select("div.cast_list .cast_item").mapNotNull { + val name = it.selectFirst("div > a > img")?.attr("alt") ?: return@mapNotNull null + val image = it.selectFirst("div > a > img")?.attr("src") ?: return@mapNotNull null + val roleString = it.selectFirst("div > span")!!.text() + val mainActor = Actor(name, image) + ActorData(actor = mainActor, roleString = roleString) + } + + return if (isMovie) { + val recommendations = doc.select(".movies_small .movie").mapNotNull { element -> + element.toSearchResponse() + } + + newMovieLoadResponse( + title, + url, + TvType.Movie, + url + ) { + this.posterUrl = posterUrl + this.year = year + this.recommendations = recommendations + this.plot = synopsis + this.tags = tags + this.actors = actors + addTrailer(youtubeTrailer) + } + } else { + val episodes = ArrayList() + doc.select("#mainLoad > div:nth-child(2) > div.h_scroll > div a").map { + it.attr("href") + }.apmap { + val d = app.get(it).document + val season = Regex("season-(.....)").find(it)?.groupValues?.getOrNull(1)?.getIntFromText() + if(d.select("tr.published").isNotEmpty()) { + d.select("tr.published").map { element -> + val ep = Regex("ep-(.....)").find(element.select(".ep_title a").attr("href"))?.groupValues?.getOrNull(1)?.getIntFromText() + episodes.add( + Episode( + element.select(".ep_title a").attr("href"), + name = element.select("td.ep_title").html().replace(".*|".toRegex(), ""), + season, + ep, + rating = element.select("td.tam:not(.date, .ep_len)").text().getIntFromText() + ) + ) + } + } else { + d.select("#mainLoad > div:nth-child(3) > div.movies_small a").map { eit -> + val ep = Regex("ep-(.....)").find(eit.attr("href"))?.groupValues?.getOrNull(1)?.getIntFromText() + episodes.add( + Episode( + eit.attr("href"), + eit.select("span.title").text(), + season, + ep, + ) + ) + } + } + } + newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes.distinct().sortedBy { it.episode }) { + this.posterUrl = posterUrl + this.tags = tags + this.year = year + this.plot = synopsis + this.actors = actors + addTrailer(youtubeTrailer) + } + } + } + data class Sources ( + @JsonProperty("quality") val quality: Int?, + @JsonProperty("link") val link: String + ) + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + /*val baseURL = data.split("/")[0] + "//" + data.split("/")[2] + val episodeSoup = app.get(data).document + + val vidstreamURL = fixUrlNull(episodeSoup.selectFirst("iframe.auto-size")?.attr("src") ) ?: throw ErrorLoadingException("No iframe") + val videoSoup = app.get(vidstreamURL).document + fixUrlNull( videoSoup.select("source").firstOrNull { it.hasAttr("src") }?.attr("src"))?.let { + callback.invoke(ExtractorLink(this.name,this.name,it,"",Qualities.Unknown.value,it.contains(".m3u8"))) + } ?: run { + var jsCode = videoSoup.select("script")[1].data() + + val verificationToken = Regex("{'[0-9a-zA-Z_]*':'ok'}").findAll(jsCode)[0][2:-7] + val encodedAdLinkVar = Regex("([0-9a-zA-Z_]{2,12}\[Math").findAll(jsCode)[0][1:-5] + val encodingArraysRegEx = Regex(",[0-9a-zA-Z_]{2,12}=\[\]").findAll(jsCode) + val firstEncodingArray = encodingArraysRegEx[1][1:-3] + val secondEncodingArray = encodingArraysRegEx[2][1:-3] + + jsCode = Regex("^