fix(ar/animerco): Update baseUrl + fix episode list (#2096)

This commit is contained in:
Claudemirovsky
2023-08-29 09:07:03 -03:00
committed by GitHub
parent 68e02edc1d
commit 1b655e5cd5
6 changed files with 206 additions and 336 deletions

View File

@ -1,11 +1,13 @@
apply plugin: 'com.android.application' plugins {
apply plugin: 'kotlin-android' alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
}
ext { ext {
extName = 'Animerco' extName = 'Animerco'
pkgNameSuffix = 'ar.animerco' pkgNameSuffix = 'ar.animerco'
extClass = '.Animerco' extClass = '.Animerco'
extVersionCode = 30 extVersionCode = 31
libVersion = '13' libVersion = '13'
} }
@ -13,7 +15,11 @@ dependencies {
implementation(project(':lib-gdriveplayer-extractor')) implementation(project(':lib-gdriveplayer-extractor'))
implementation(project(':lib-streamtape-extractor')) implementation(project(':lib-streamtape-extractor'))
implementation(project(':lib-dood-extractor')) implementation(project(':lib-dood-extractor'))
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1" implementation(project(':lib-vidbom-extractor'))
implementation(project(':lib-mp4upload-extractor'))
implementation(project(':lib-streamwish-extractor'))
implementation(project(':lib-yourupload-extractor'))
implementation(project(':lib-okru-extractor'))
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View File

@ -6,7 +6,6 @@ import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.ar.animerco.extractors.SharedExtractor import eu.kanade.tachiyomi.animeextension.ar.animerco.extractors.SharedExtractor
import eu.kanade.tachiyomi.animeextension.ar.animerco.extractors.UQLoadExtractor import eu.kanade.tachiyomi.animeextension.ar.animerco.extractors.UQLoadExtractor
import eu.kanade.tachiyomi.animeextension.ar.animerco.extractors.VidBomExtractor
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
@ -15,12 +14,20 @@ import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
import eu.kanade.tachiyomi.lib.gdriveplayerextractor.GdrivePlayerExtractor import eu.kanade.tachiyomi.lib.gdriveplayerextractor.GdrivePlayerExtractor
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
import eu.kanade.tachiyomi.lib.vidbomextractor.VidBomExtractor
import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -29,191 +36,186 @@ import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.lang.Exception import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.Locale
class Animerco : ConfigurableAnimeSource, ParsedAnimeHttpSource() { class Animerco : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override val name = "Animerco" override val name = "Animerco"
override val baseUrl = "https://animerco.com" override val baseUrl = "https://animerco.org"
override val lang = "ar" override val lang = "ar"
override val supportsLatest = false override val supportsLatest = false
private val dateFormat: SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.US)
override val client: OkHttpClient = network.cloudflareClient override val client: OkHttpClient = network.cloudflareClient
private val preferences: SharedPreferences by lazy { private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
// Popular Anime // ============================== Popular ===============================
override fun popularAnimeRequest(page: Int) = GET("$baseUrl/animes/page/$page/")
override fun popularAnimeSelector(): String = "div.media-block" override fun popularAnimeSelector() = "div.media-block > div > a.image"
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/animes/page/$page/") // page/$page override fun popularAnimeFromElement(element: Element) = SAnime.create().apply {
setUrlWithoutDomain(element.attr("href"))
override fun popularAnimeFromElement(element: Element): SAnime { thumbnail_url = element.attr("data-src")
val anime = SAnime.create() title = element.attr("title")
anime.setUrlWithoutDomain(element.select("a").attr("href"))
anime.thumbnail_url = element.select("a").attr("data-src")
anime.title = element.select("div.info a h3").text()
return anime
} }
override fun popularAnimeNextPageSelector(): String = "a.ti-arrow-left-c" override fun popularAnimeNextPageSelector() = "ul.pagination li a:has(i.fa-left-long)"
// Episodes // =============================== 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")
override fun episodeListSelector() = throw Exception("not used") // =============================== Search ===============================
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList) = GET("$baseUrl/page/$page/?s=$query")
override fun searchAnimeSelector() = popularAnimeSelector()
override fun searchAnimeFromElement(element: Element) = popularAnimeFromElement(element)
override fun searchAnimeNextPageSelector() = popularAnimeNextPageSelector()
// =========================== Anime Details ============================
override fun animeDetailsParse(document: Document) = SAnime.create().apply {
document.selectFirst("a.poster")?.run {
thumbnail_url = attr("data-src")
title = attr("title").ifEmpty {
document.selectFirst("div.media-title h1")!!.text()
}
}
val infosDiv = document.selectFirst("ul.media-info")!!
author = infosDiv.select("li:contains(الشبكات) a").eachText()
.joinToString()
.takeIf(String::isNotBlank)
artist = infosDiv.select("li:contains(الأستوديو) a").eachText()
.joinToString()
.takeIf(String::isNotBlank)
genre = document.select("nav.Nvgnrs a, ul.media-info li:contains(النوع) a")
.eachText()
.joinToString()
description = buildString {
document.selectFirst("div.media-story p")?.also {
append(it.text())
}
document.selectFirst("div.media-title > h3.alt-title")?.also {
append("\n\nAlternative title: " + it.text())
}
}
status = document.select("ul.chapters-list a.se-title > span.badge")
.eachText()
.let { items ->
when {
items.all { it.contains("مكتمل") } -> SAnime.COMPLETED
items.any { it.contains("يعرض الأن") } -> SAnime.ONGOING
else -> SAnime.UNKNOWN
}
}
}
// ============================== Episodes ==============================
override fun episodeListSelector() = "ul.chapters-list li a:has(h3)"
override fun episodeListParse(response: Response): List<SEpisode> { override fun episodeListParse(response: Response): List<SEpisode> {
val document = response.asJsoup() val document = response.use { it.asJsoup() }
val episodeList = mutableListOf<SEpisode>() if (document.location().contains("/movies/")) {
// val seriesLink1 = document.select("ol[itemscope] li:last-child a").attr("href") return listOf(
val seriesLink = document.select("link[rel=canonical]").attr("href") SEpisode.create().apply {
val type = document.select("link[rel=canonical]").attr("href") setUrlWithoutDomain(document.location())
if (type.contains("animes")) { episode_number = 1F
val seasonsHtml = client.newCall( name = "Movie"
GET( },
seriesLink, )
// headers = Headers.headersOf("Referer", document.location())
),
).execute().asJsoup()
val seasonsElements = seasonsHtml.select("ul.chapters-list li a.title")
seasonsElements.reversed().forEach {
val seasonEpList = parseEpisodesFromSeries(it)
episodeList.addAll(seasonEpList)
}
} else {
val movieUrl = seriesLink
val episode = SEpisode.create()
episode.name = document.select("span.alt-title").text()
episode.episode_number = 1F
episode.setUrlWithoutDomain(movieUrl)
episodeList.add(episode)
}
return episodeList
} }
private fun parseEpisodesFromSeries(element: Element): List<SEpisode> { return document.select(episodeListSelector()).flatMap { el ->
val seasonName = element.text() val doc = client.newCall(GET(el.attr("abs:href"), headers)).execute()
val episodesUrl = element.attr("abs:href") .use { it.asJsoup() }
val episodesHtml = client.newCall( val seasonName = doc.selectFirst("div.media-title h1")!!.text()
GET( val seasonNum = seasonName.substringAfterLast(" ").toIntOrNull() ?: 1
episodesUrl, doc.select(episodeListSelector()).map {
), episodeFromElement(it, seasonName, seasonNum)
).execute().asJsoup() }.reversed()
val episodeElements = episodesHtml.select("ul.chapters-list li") }.reversed()
return episodeElements.map { episodeFromElement(it) }
} }
override fun episodeFromElement(element: Element): SEpisode { private fun episodeFromElement(element: Element, seasonName: String, seasonNum: Int) = SEpisode.create().apply {
val episode = SEpisode.create() setUrlWithoutDomain(element.attr("href"))
val epNum = getNumberFromEpsString(element.select("a.title h3").text()) val epText = element.selectFirst("h3")!!.ownText()
episode.episode_number = when { name = "$seasonName: " + epText
(epNum.isNotEmpty()) -> epNum.toFloat() val epNum = epText.filter(Char::isDigit)
else -> 1F // good luck trying to track this xD
} episode_number = "$seasonNum.${epNum.padStart(3, '0')}".toFloatOrNull() ?: 1F
// element.select("td > span.Num").text().toFloat()
// val SeasonNum = element.ownerDocument()!!.select("div.Title span").text()
val seasonName = element.ownerDocument()!!.select("div.media-title h1").text()
episode.name = "$seasonName : " + element.select("a.title h3").text()
episode.setUrlWithoutDomain(element.select("a.title").attr("abs:href"))
return episode
} }
private fun getNumberFromEpsString(epsStr: String): String { override fun episodeFromElement(element: Element) = throw Exception("not used")
return epsStr.filter { it.isDigit() }
}
// Video urls
// ============================ Video Links =============================
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup() val document = response.use { it.asJsoup() }
return videosFromElement(document) val players = document.select(videoListSelector())
return players.parallelMap {
runCatching { getPlayerVideos(it) }.getOrElse { emptyList() }
}.flatten()
} }
override fun videoListSelector() = "li.dooplay_player_option" // ul#playeroptionsul override fun videoListSelector() = "li.dooplay_player_option" // ul#playeroptionsul
private fun videosFromElement(document: Document): List<Video> { private val doodExtractor by lazy { DoodExtractor(client) }
val videoList = mutableListOf<Video>() private val gdrivePlayerExtractor by lazy { GdrivePlayerExtractor(client) }
val elements = document.select(videoListSelector()) private val streamTapeExtractor by lazy { StreamTapeExtractor(client) }
for (element in elements) { private val sharedExtractor by lazy { SharedExtractor(client) }
val location = element.ownerDocument()!!.location() private val uqloadExtractor by lazy { UQLoadExtractor(client) }
val videoHeaders = Headers.headersOf("Referer", location) private val vidBomExtractor by lazy { VidBomExtractor(client) }
val qualityy = element.text() private val mp4uploadExtractor by lazy { Mp4uploadExtractor(client) }
val post = element.attr("data-post") private val okruExtractor by lazy { OkruExtractor(client) }
val num = element.attr("data-nume") private val streamWishExtractor by lazy { StreamWishExtractor(client, headers) }
val type = element.attr("data-type") private val yourUploadExtractor by lazy { YourUploadExtractor(client) }
val pageData = FormBody.Builder()
.add("action", "doo_player_ajax")
.add("nume", num)
.add("post", post)
.add("type", type)
.build()
val ajaxUrl = "https://animerco.com/wp-admin/admin-ajax.php"
val callAjax = client.newCall(POST(ajaxUrl, videoHeaders, pageData)).execute().asJsoup()
val embedUrlT = callAjax.text().substringAfter("embed_url\":\"").substringBefore("\"")
val embedUrl = embedUrlT.replace("\\/", "/")
when { private fun getPlayerVideos(player: Element): List<Video> {
embedUrl.contains("dood") -> { val url = getPlayerUrl(player) ?: return emptyList()
val video = DoodExtractor(client).videoFromUrl(embedUrl) val name = player.selectFirst("span.title")!!.text().lowercase()
if (video != null) { return when {
videoList.add(video) "ok.ru" in url -> okruExtractor.videosFromUrl(url)
"mp4upload" in url -> mp4uploadExtractor.videosFromUrl(url, headers)
"wish" in name -> streamWishExtractor.videosFromUrl(url)
"yourupload" in url -> yourUploadExtractor.videoFromUrl(url, headers)
"dood" in url -> doodExtractor.videoFromUrl(url)?.let(::listOf)
"drive.google" in url -> {
val newUrl = "https://gdriveplayer.to/embed2.php?link=$url"
gdrivePlayerExtractor.videosFromUrl(newUrl, "GdrivePlayer", headers)
} }
"streamtape" in url -> streamTapeExtractor.videoFromUrl(url)?.let(::listOf)
"4shared" in url -> sharedExtractor.videoFromUrl(url)?.let(::listOf)
"uqload" in url -> uqloadExtractor.videoFromUrl(url)?.let(::listOf)
VIDBOM_DOMAINS.any(url::contains) -> vidBomExtractor.videosFromUrl(url)
else -> null
} ?: emptyList()
} }
embedUrl.contains("drive.google")
-> { private fun getPlayerUrl(player: Element): String? {
val embedUrlG = "https://gdriveplayer.to/embed2.php?link=" + embedUrl val body = FormBody.Builder()
val videos = GdrivePlayerExtractor(client).videosFromUrl(embedUrlG, "GdrivePlayer", headers = headers) .add("action", "doo_player_ajax")
videoList.addAll(videos) .add("post", player.attr("data-post"))
.add("nume", player.attr("data-nume"))
.add("type", player.attr("data-type"))
.build()
return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", headers, body))
.execute()
.use { response ->
response.body.string()
.substringAfter("\"embed_url\":\"")
.substringBefore("\",")
.replace("\\", "")
.takeIf(String::isNotBlank)
} }
embedUrl.contains("streamtape") -> {
val video = StreamTapeExtractor(client).videoFromUrl(embedUrl)
if (video != null) {
videoList.add(video)
}
}
embedUrl.contains("4shared") -> {
val qualityy = "4shared"
val video = SharedExtractor(client).videoFromUrl(embedUrl, qualityy)
if (video != null) {
videoList.add(video)
}
}
embedUrl.contains("uqload") -> {
val qualityy = "uqload"
val video = UQLoadExtractor(client).videoFromUrl(embedUrl, qualityy)
if (video != null) {
videoList.add(video)
}
}
embedUrl.contains("vidbom.com") ||
embedUrl.contains("vidbem.com") || embedUrl.contains("vidbm.com") || embedUrl.contains("vedpom.com") ||
embedUrl.contains("vedbom.com") || embedUrl.contains("vedbom.org") || embedUrl.contains("vadbom.com") ||
embedUrl.contains("vidbam.org") || embedUrl.contains("myviid.com") || embedUrl.contains("myviid.net") ||
embedUrl.contains("myvid.com") || embedUrl.contains("vidshare.com") || embedUrl.contains("vedsharr.com") ||
embedUrl.contains("vedshar.com") || embedUrl.contains("vedshare.com") || embedUrl.contains("vadshar.com") || embedUrl.contains("vidshar.org")
-> { // , vidbm, vidbom
val videos = VidBomExtractor(client).videosFromUrl(embedUrl)
videoList.addAll(videos)
}
embedUrl.contains("vidbm") -> { // , vidbm, vidbom
val videos = VidBomExtractor(client).videosFromUrl(embedUrl)
videoList.addAll(videos)
}
embedUrl.contains("vidbom") -> { // , vidbm, vidbom
val videos = VidBomExtractor(client).videosFromUrl(embedUrl)
videoList.addAll(videos)
}
}
}
return videoList
} }
override fun videoFromElement(element: Element) = throw Exception("not used") override fun videoFromElement(element: Element) = throw Exception("not used")
@ -221,101 +223,21 @@ class Animerco : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override fun videoUrlParse(document: Document) = throw Exception("not used") override fun videoUrlParse(document: Document) = throw Exception("not used")
override fun List<Video>.sort(): List<Video> { override fun List<Video>.sort(): List<Video> {
val quality = preferences.getString("preferred_quality", null) val quality = preferences.getString(PREF_QUALITY_KEY, PREF_QUALITY_DEFAULT)!!
if (quality != null) {
val newList = mutableListOf<Video>() return sortedWith(
var preferred = 0 compareBy { it.quality.contains(quality) },
for (video in this) { ).reversed()
if (video.quality.contains(quality)) {
newList.add(preferred, video)
preferred++
} else {
newList.add(video)
}
}
return newList
}
return this
} }
// Search // ============================== Settings ==============================
override fun searchAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(element.select("a.image").attr("href"))
anime.thumbnail_url = element.select("a.image").attr("data-src")
anime.title = element.select("a.image").attr("alt")
return anime
}
override fun searchAnimeNextPageSelector(): String = "a.ti-arrow-left-c"
override fun searchAnimeSelector(): String = "div.media-block"
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = GET("$baseUrl/page/$page/?s=$query")
// Details
override fun animeDetailsParse(document: Document): SAnime {
val anime = SAnime.create()
anime.thumbnail_url = document.select(".poster").attr("data-src")
anime.title = document.select("div.media-title h1").text()
anime.genre = document.select("nav.Nvgnrs a, ul.media-info li:contains(النوع) a").joinToString(", ") { it.text() }
anime.description = document.select("div.media-story p").text()
anime.author = document.select("ul.media-info li:contains(الشبكات) a").joinToString(", ") { it.text() }
anime.artist = document.select("ul.media-info li:contains(الأستوديو) a").joinToString(", ") { it.text() }
// anime.status = parseStatus(document.select("div.row-line:contains(Status)").text().replace("Status: ", ""))
return anime
}
private fun parseStatus(statusString: String): Int {
return when (statusString) {
"Airing" -> SAnime.ONGOING
"Completed" -> SAnime.COMPLETED
else -> SAnime.UNKNOWN
}
}
// Latest
override fun latestUpdatesNextPageSelector(): String = throw Exception("Not used")
override fun latestUpdatesFromElement(element: Element): SAnime = throw Exception("Not used")
override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not used")
override fun latestUpdatesSelector(): String = throw Exception("Not used")
/*// Filter
override fun getFilterList() = AnimeFilterList(
TypeList(typesName),
)
private class TypeList(types: Array<String>) : AnimeFilter.Select<String>("Drame Type", types)
private data class Type(val name: String, val query: String)
private val typesName = getTypeList().map {
it.name
}.toTypedArray()
private fun getTypeList() = listOf(
Type("Select", ""),
Type("Recently Added Sub", ""),
Type("Recently Added Raw", "recently-added-raw"),
Type("Drama Movie", "movies"),
Type("KShow", "kshow"),
Type("Ongoing Series", "ongoing-series")
)*/
// Preferences
override fun setupPreferenceScreen(screen: PreferenceScreen) { override fun setupPreferenceScreen(screen: PreferenceScreen) {
val videoQualityPref = ListPreference(screen.context).apply { ListPreference(screen.context).apply {
key = "preferred_quality" key = PREF_QUALITY_KEY
title = "Preferred quality" title = PREF_QUALITY_TITLE
entries = arrayOf("1080p", "720p", "480p", "360p", "Doodstream", "StreamTape") entries = PREF_QUALITY_ENTRIES
entryValues = arrayOf("1080", "720", "480", "360", "Doodstream", "StreamTape") entryValues = PREF_QUALITY_VALUES
setDefaultValue("1080") setDefaultValue(PREF_QUALITY_DEFAULT)
summary = "%s" summary = "%s"
setOnPreferenceChangeListener { _, newValue -> setOnPreferenceChangeListener { _, newValue ->
@ -324,7 +246,28 @@ class Animerco : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
val entry = entryValues[index] as String val entry = entryValues[index] as String
preferences.edit().putString(key, entry).commit() preferences.edit().putString(key, entry).commit()
} }
}.also(screen::addPreference)
} }
screen.addPreference(videoQualityPref)
// ============================= Utilities ==============================
private inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
runBlocking {
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
}
companion object {
private const val PREF_QUALITY_KEY = "preferred_quality"
private const val PREF_QUALITY_TITLE = "Preferred quality"
private const val PREF_QUALITY_DEFAULT = "1080"
private val PREF_QUALITY_ENTRIES = arrayOf("1080p", "720p", "480p", "360p", "Doodstream", "StreamTape")
private val PREF_QUALITY_VALUES = arrayOf("1080", "720", "480", "360", "Doodstream", "StreamTape")
private val VIDBOM_DOMAINS = listOf(
"vidbom.com", "vidbem.com", "vidbm.com", "vedpom.com",
"vedbom.com", "vedbom.org", "vadbom.com",
"vidbam.org", "myviid.com", "myviid.net",
"myvid.com", "vidshare.com", "vedsharr.com",
"vedshar.com", "vedshare.com", "vadshar.com", "vidshar.org",
)
} }
} }

View File

@ -1,19 +0,0 @@
package eu.kanade.tachiyomi.animeextension.ar.animerco.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
class MpforuploadExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, quality: String): Video? {
val document = client.newCall(GET(url)).execute().asJsoup()
val check = document.select("div.error4shared").text()
val videoUrl = document.select("source").attr("src")
return if (check.contains("This file is not available any more")) {
Video(url, "no 1video", "https")
} else {
Video(url, quality, videoUrl)
}
}
}

View File

@ -6,14 +6,10 @@ import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
class SharedExtractor(private val client: OkHttpClient) { class SharedExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, quality: String): Video? { fun videoFromUrl(url: String, quality: String = "mirror"): Video? {
val document = client.newCall(GET(url)).execute().asJsoup() val document = client.newCall(GET(url)).execute().asJsoup()
val check = document.select("div.error4shared").text() return document.selectFirst("source")?.let {
val videoUrl = document.select("source").attr("src") Video(it.attr("src"), "4Shared: $quality", it.attr("src"))
return if (check.contains("This file is not available any more")) {
Video(url, "no 1video", "https")
} else {
Video(url, quality, videoUrl)
} }
} }
} }

View File

@ -6,14 +6,12 @@ import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
class UQLoadExtractor(private val client: OkHttpClient) { class UQLoadExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, quality: String): Video? { fun videoFromUrl(url: String, quality: String = "uqload"): Video? {
val document = client.newCall(GET(url)).execute().asJsoup() val document = client.newCall(GET(url)).execute().use { it.asJsoup() }
val check = document.selectFirst("script:containsData(sources)")!!.data() val check = document.selectFirst("script:containsData(sources)")?.data()
val videoUrl = check.substringAfter("sources: [\"").substringBefore("\"") ?: return null
return if (check.contains("sources")) { val videoUrl = check.substringAfter("sources: [\"", "").substringBefore("\"", "")
Video(url, quality, videoUrl) if (videoUrl.isBlank()) return null
} else { return Video(videoUrl, quality, videoUrl)
Video(url, "no 1video", "https")
}
} }
} }

View File

@ -1,54 +0,0 @@
package eu.kanade.tachiyomi.animeextension.ar.animerco.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
class VidBomExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String): List<Video> {
val doc = client.newCall(GET(url)).execute().asJsoup()
val script = doc.selectFirst("script:containsData(sources)")!!
val data = script.data().substringAfter("sources: [").substringBefore("],")
val sources = data.split("file:\"").drop(1)
val videoList = mutableListOf<Video>()
for (source in sources) {
val src = source.substringBefore("\"")
val quality = "Vidbom:" + source.substringAfter("label:\"").substringBefore("\"") // .substringAfter("format: '")
val video = Video(src, quality, src)
videoList.add(video)
}
return videoList
/*Log.i("looool", "$js")
val json = JSONObject(js)
Log.i("looool", "$json")
val videoList = mutableListOf<Video>()
val jsonArray = json.getJSONArray("sources")
for (i in 0 until jsonArray.length()) {
val `object` = jsonArray.getJSONObject(i)
val videoUrl = `object`.getString("file")
Log.i("looool", videoUrl)
val quality = "Vidbom:" + `object`.getString("label")
videoList.add(Video(videoUrl, quality, videoUrl))
}
return videoList*/
/*if (jas.contains("sources")) {
val js = script.data()
val json = JSONObject(js)
val videoList = mutableListOf<Video>()
val jsonArray = json.getJSONArray("sources")
for (i in 0 until jsonArray.length()) {
val `object` = jsonArray.getJSONObject(i)
val videoUrl = `object`.getString("file")
Log.i("lol", videoUrl)
val quality = "Vidbom:" + `object`.getString("label")
videoList.add(Video(videoUrl, quality, videoUrl))
}
return videoList
} else {
val videoList = mutableListOf<Video>()
videoList.add(Video(url, "no 2video", null))
return videoList
}*/
}
}