diff --git a/src/en/holamovies/AndroidManifest.xml b/src/en/holamovies/AndroidManifest.xml deleted file mode 100644 index 568741e54f..0000000000 --- a/src/en/holamovies/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/src/en/holamovies/build.gradle b/src/en/holamovies/build.gradle deleted file mode 100644 index 13af009e27..0000000000 --- a/src/en/holamovies/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlinx-serialization' - -ext { - extName = 'PobMovies' - pkgNameSuffix = 'en.holamovies' - extClass = '.PobMovies' - extVersionCode = 6 - libVersion = '13' -} - -dependencies { - implementation(project(':lib-googledrive-extractor')) -} - -apply from: "$rootDir/common.gradle" diff --git a/src/en/holamovies/res/mipmap-hdpi/ic_launcher.png b/src/en/holamovies/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index dbae6e62a6..0000000000 Binary files a/src/en/holamovies/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/holamovies/res/mipmap-mdpi/ic_launcher.png b/src/en/holamovies/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 88f195ca85..0000000000 Binary files a/src/en/holamovies/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/holamovies/res/mipmap-xhdpi/ic_launcher.png b/src/en/holamovies/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 3ce518afe7..0000000000 Binary files a/src/en/holamovies/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/holamovies/res/mipmap-xxhdpi/ic_launcher.png b/src/en/holamovies/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 26ce52c120..0000000000 Binary files a/src/en/holamovies/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/holamovies/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/holamovies/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index d3631a21d1..0000000000 Binary files a/src/en/holamovies/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/holamovies/res/web_hi_res_512.png b/src/en/holamovies/res/web_hi_res_512.png deleted file mode 100644 index becee12885..0000000000 Binary files a/src/en/holamovies/res/web_hi_res_512.png and /dev/null differ diff --git a/src/en/holamovies/src/eu/kanade/tachiyomi/animeextension/en/holamovies/PobMovies.kt b/src/en/holamovies/src/eu/kanade/tachiyomi/animeextension/en/holamovies/PobMovies.kt deleted file mode 100644 index cf5bda7a4e..0000000000 --- a/src/en/holamovies/src/eu/kanade/tachiyomi/animeextension/en/holamovies/PobMovies.kt +++ /dev/null @@ -1,331 +0,0 @@ -package eu.kanade.tachiyomi.animeextension.en.holamovies - -import android.app.Application -import android.content.SharedPreferences -import androidx.preference.PreferenceScreen -import eu.kanade.tachiyomi.animeextension.en.holamovies.extractors.GDBotExtractor -import eu.kanade.tachiyomi.animeextension.en.holamovies.extractors.GDFlixExtractor -import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource -import eu.kanade.tachiyomi.animesource.model.AnimeFilterList -import eu.kanade.tachiyomi.animesource.model.SAnime -import eu.kanade.tachiyomi.animesource.model.SEpisode -import eu.kanade.tachiyomi.animesource.model.Video -import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.util.asJsoup -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import rx.Observable -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get - -class PobMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() { - - override val name = "PobMovies" - - override val id = 8957317977172284857 - - override val baseUrl = "https://pobmovies.cam" - - override val lang = "en" - - override val supportsLatest = false - - override val client: OkHttpClient = network.cloudflareClient - - private val preferences: SharedPreferences by lazy { - Injekt.get().getSharedPreferences("source_$id", 0x0000) - } - - // ============================== Popular =============================== - - override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/page/$page/") - - override fun popularAnimeSelector(): String = "div#content > div > div.row > div" - - override fun popularAnimeFromElement(element: Element): SAnime = SAnime.create().apply { - setUrlWithoutDomain(element.selectFirst("a")!!.attr("href")) - thumbnail_url = element.selectFirst("img[src]")?.attr("src") ?: "" - title = element.selectFirst("h1")!!.text() - } - - override fun popularAnimeNextPageSelector(): String = "nav.gridlove-pagination > span.current + a" - - // =============================== Latest =============================== - - override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not used") - - override fun latestUpdatesSelector(): String = throw Exception("Not used") - - override fun latestUpdatesFromElement(element: Element): SAnime = throw Exception("Not used") - - override fun latestUpdatesNextPageSelector(): String = throw Exception("Not used") - - // =============================== Search =============================== - - override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { -// val FILTER_LIST = if (filters.isEmpty()) getFilterList() else filters -// val genreFilter = FILTER_LIST.find { it is GenreFilter } as GenreFilter -// val recentFilter = FILTER_LIST.find { it is RecentFilter } as RecentFilter -// val seasonFilter = FILTER_LIST.find { it is SeasonFilter } as SeasonFilter - - val cleanQuery = query.replace(" ", "+") - - return when { - query.isNotBlank() -> GET("$baseUrl/page/$page/?s=$cleanQuery", headers) -// genreFilter.state != 0 -> GET("$baseUrl/genre/${genreFilter.toUriPart()}?page=$page") -// recentFilter.state != 0 -> GET("https://ajax.gogo-load.com/ajax/page-recent-release.html?page=$page&type=${recentFilter.toUriPart()}") - else -> GET("$baseUrl/popular.html?page=$page") - } - } - override fun searchAnimeSelector(): String = popularAnimeSelector() - - override fun searchAnimeNextPageSelector(): String = popularAnimeNextPageSelector() - - override fun searchAnimeFromElement(element: Element): SAnime = popularAnimeFromElement(element) - - // ============================== FILTERS =============================== - - // Todo - add these when the site starts working again -// override fun getFilterList(): AnimeFilterList = AnimeFilterList( -// AnimeFilter.Header("Text search ignores filters"), -// GenreFilter(), -// ) - - // =========================== Anime Details ============================ - - override fun animeDetailsParse(document: Document): SAnime = SAnime.create().apply { - description = document.selectFirst("div.entry-content > p")?.text() - } - - // ============================== Episodes ============================== - - override fun episodeListParse(response: Response): List { - val document = response.asJsoup() - val episodeList = mutableListOf() - - val sizeRegex = Regex("""[\[\(](\d+\.?\d* ?[KMGT]B)[\]\)]""") - val zipRegex = Regex("""\bZIP\b""") - - document.select("div.entry-content:has(h3,h4,p) > p:has(a[href]):not(:has(span.mb-text))").forEach { - it.select("a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - val info = it.previousElementSiblings().firstOrNull { prevTag -> - arrayOf("h3", "h4", "p").contains(prevTag.normalName()) - }?.text() - - val size = sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = link.text() - episode_number = 1F - date_upload = -1L - url = link.attr("href") - scanlator = "${if (size == null) "" else "$size • "}$info" - }, - ) - } - } - - // We don't want to parse multiple times - if (episodeList.isEmpty()) { - document.select("div.entry-content:has(pre:contains(episode)) > p:has(a[href])").reversed().forEach { - it.select("a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - val info = it.previousElementSiblings().firstOrNull { prevTag -> - prevTag.normalName() == "p" && prevTag.selectFirst("strong") != null - }?.text() - val episodeNumber = it.previousElementSiblings().firstOrNull { prevTag -> - prevTag.normalName() == "pre" && prevTag.text().contains("episode", true) - }?.text()?.substringAfter(" ")?.toFloatOrNull() ?: 1F - - val size = sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = "Ep. $episodeNumber - ${link.text()}" - episode_number = episodeNumber - date_upload = -1L - url = link.attr("href") - scanlator = "${if (size == null) "" else "$size • "}$info" - }, - ) - } - } - } - - if (episodeList.isEmpty()) { - document.select("div.entry-content > p:has(a[href]:has(span.mb-text)), div.entry-content > em p:has(a[href]:has(span.mb-text))").reversed().forEach { - it.select("a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - val title = it.previousElementSiblings().firstOrNull { prevTag -> - arrayOf("p", "h5").contains(prevTag.normalName()) && prevTag.text().isNotBlank() - }?.text() ?: "Item" - - val size = sizeRegex.find(title)?.groupValues?.get(1) - ?: sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = "$title - ${link.text()}" - episode_number = 1F - date_upload = -1L - scanlator = size - url = link.attr("href") - }, - ) - } - } - } - - if (episodeList.isEmpty()) { - document.select("div.entry-content:has(pre:has(em)) > p:has(a[href])").reversed().forEach { - it.select("em a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - if (link.text().contains("click here", true)) return@forEach - val title = it.previousElementSiblings().firstOrNull { prevTag -> - prevTag.normalName() == "pre" - }?.text() - - val size = sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = "$title - ${link.text()}" - episode_number = 1F - date_upload = -1L - scanlator = size - url = link.attr("href") - }, - ) - } - } - } - - if (episodeList.isEmpty()) { - document.select("div.entry-content:has(p:has(em)) > p:has(a[href])").reversed().forEach { - it.select("a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - val info = it.previousElementSiblings().firstOrNull { prevTag -> - prevTag.normalName() == "p" && prevTag.text().isNotBlank() && prevTag.selectFirst("a") == null - }?.text() ?: "Item" - - val size = sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = link.text() - episode_number = 1F - date_upload = -1L - scanlator = "${if (size == null) "" else "$size • "}$info" - url = link.attr("href") - }, - ) - } - } - } - - if (episodeList.isEmpty()) { - document.select("div.entry-content > div.wp-block-buttons").reversed().forEach { - it.select("a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - val info = it.previousElementSiblings().firstOrNull { prevTag -> - prevTag.normalName() == "pre" && prevTag.text().isNotBlank() - }?.text() ?: "" - - val size = sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = link.text() - episode_number = 1F - date_upload = -1L - scanlator = "${if (size == null) "" else "$size • "}$info" - url = link.attr("href") - }, - ) - } - } - } - - if (episodeList.isEmpty()) { - document.select("div.entry-content > figure.wp-block-embed").reversed().forEach { - it.select("a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - val size = sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = link.text() - episode_number = 1F - date_upload = -1L - scanlator = size - url = link.attr("href") - }, - ) - } - } - } - - if (episodeList.isEmpty()) { - document.select("div.entry-content > a[role=button][href]").reversed().forEach { - it.select("a").forEach { link -> - if (zipRegex.find(link.text()) != null) return@forEach - val size = sizeRegex.find(link.text())?.groupValues?.get(1) - - episodeList.add( - SEpisode.create().apply { - name = link.text() - episode_number = 1F - date_upload = -1L - scanlator = size - url = link.attr("href") - }, - ) - } - } - } - - return episodeList - } - - override fun episodeListSelector(): String = throw Exception("Not used") - - override fun episodeFromElement(element: Element): SEpisode = throw Exception("Not used") - - // ============================ Video Links ============================= - - override fun fetchVideoList(episode: SEpisode): Observable> { - val videoList = when { - episode.url.toHttpUrl().host.contains("gdflix") -> { - GDFlixExtractor(client, headers).videosFromUrl(episode.url) - } - episode.url.toHttpUrl().host.contains("gdtot") || - episode.url.toHttpUrl().host.contains("gdbot") -> { - GDBotExtractor(client, headers, preferences).videosFromUrl(episode.url) - } - else -> { throw Exception("Unsupported url: ${episode.url}") } - } - - require(videoList.isNotEmpty()) { "Failed to fetch videos" } - - return Observable.just(videoList.sort()) - } - - override fun videoListSelector(): String = throw Exception("Not Used") - - override fun videoFromElement(element: Element): Video = throw Exception("Not Used") - - override fun videoUrlParse(document: Document): String = throw Exception("Not Used") - - // ============================= Utilities ============================== - - // ============================== Settings ============================== - - override fun setupPreferenceScreen(screen: PreferenceScreen) {} -} diff --git a/src/en/holamovies/src/eu/kanade/tachiyomi/animeextension/en/holamovies/extractors/GDBotExtractor.kt b/src/en/holamovies/src/eu/kanade/tachiyomi/animeextension/en/holamovies/extractors/GDBotExtractor.kt deleted file mode 100644 index 40a5ef1e3e..0000000000 --- a/src/en/holamovies/src/eu/kanade/tachiyomi/animeextension/en/holamovies/extractors/GDBotExtractor.kt +++ /dev/null @@ -1,76 +0,0 @@ -package eu.kanade.tachiyomi.animeextension.en.holamovies.extractors - -import android.content.SharedPreferences -import eu.kanade.tachiyomi.animesource.model.Video -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.util.asJsoup -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.runBlocking -import okhttp3.Headers -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.OkHttpClient - -class GDBotExtractor(private val client: OkHttpClient, private val headers: Headers, private val preferences: SharedPreferences) { - - private val prefBotUrlKey = "bot_url" - - private val defaultUrl = "https://gdtot.pro" - - fun videosFromUrl(serverUrl: String, maxTries: Int = 1): List