diff --git a/src/de/streamcloud/build.gradle b/src/de/streamcloud/build.gradle index e4bce67e2..65152ed26 100644 --- a/src/de/streamcloud/build.gradle +++ b/src/de/streamcloud/build.gradle @@ -1,17 +1,20 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlinx-serialization' +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) +} ext { extName = 'StreamCloud' pkgNameSuffix = 'de.streamcloud' extClass = '.StreamCloud' - extVersionCode = 5 + extVersionCode = 6 libVersion = '13' } dependencies { implementation(project(':lib-dood-extractor')) + implementation(project(':lib-streamtape-extractor')) + implementation(project(':lib-mixdrop-extractor')) } apply from: "$rootDir/common.gradle" diff --git a/src/de/streamcloud/src/eu/kanade/tachiyomi/animeextension/de/streamcloud/StreamCloud.kt b/src/de/streamcloud/src/eu/kanade/tachiyomi/animeextension/de/streamcloud/StreamCloud.kt index d2aa199e3..5e6294919 100644 --- a/src/de/streamcloud/src/eu/kanade/tachiyomi/animeextension/de/streamcloud/StreamCloud.kt +++ b/src/de/streamcloud/src/eu/kanade/tachiyomi/animeextension/de/streamcloud/StreamCloud.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.animeextension.de.streamcloud import android.app.Application -import android.content.SharedPreferences import androidx.preference.ListPreference import androidx.preference.MultiSelectListPreference import androidx.preference.PreferenceScreen @@ -12,11 +11,10 @@ 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.lib.doodextractor.DoodExtractor +import eu.kanade.tachiyomi.lib.mixdropextractor.MixDropExtractor +import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.util.asJsoup -import okhttp3.Headers -import okhttp3.OkHttpClient -import okhttp3.Request import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -28,140 +26,125 @@ class StreamCloud : ConfigurableAnimeSource, ParsedAnimeHttpSource() { override val name = "StreamCloud" - override val baseUrl = "https://streamcloud.cam" + override val baseUrl = "https://streamcloud.movie" override val lang = "de" override val supportsLatest = false - override val client: OkHttpClient = network.cloudflareClient + override val client = network.cloudflareClient - private val preferences: SharedPreferences by lazy { + private val preferences by lazy { Injekt.get().getSharedPreferences("source_$id", 0x0000) } - override fun popularAnimeSelector(): String = "#dle-content div.item" + // ============================== Popular =============================== + override fun popularAnimeRequest(page: Int) = GET("$baseUrl/beliebte-filme/") - override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/beliebte-filme/") + override fun popularAnimeSelector() = "div#dle-content > div.item > div.thumb > a" - override fun popularAnimeFromElement(element: Element): SAnime { - val anime = SAnime.create() - anime.setUrlWithoutDomain(element.select("div.thumb a").attr("href")) - anime.thumbnail_url = baseUrl + element.select("div.thumb a img").attr("src") - anime.title = element.select("div.thumb a img").attr("alt") - return anime + override fun popularAnimeFromElement(element: Element) = SAnime.create().apply { + setUrlWithoutDomain(element.attr("href")) + element.selectFirst("img")!!.run { + thumbnail_url = absUrl("src") + title = attr("alt") + } } - override fun popularAnimeNextPageSelector(): String? = null + override fun popularAnimeNextPageSelector() = null - // episodes + // =============================== Latest =============================== + override fun latestUpdatesNextPageSelector() = throw Exception("Not used") + + override fun latestUpdatesFromElement(element: Element) = throw Exception("Not used") + + override fun latestUpdatesRequest(page: Int) = throw Exception("Not used") + + override fun latestUpdatesSelector() = throw Exception("Not used") + + // =============================== Search =============================== + override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList) = + GET("$baseUrl/index.php?do=search&subaction=search&search_start=$page&full_search=0&story=$query") + + override fun searchAnimeSelector() = popularAnimeSelector() + + override fun searchAnimeFromElement(element: Element) = popularAnimeFromElement(element) + + override fun searchAnimeNextPageSelector() = "#nextlink" + + // =========================== Anime Details ============================ + override fun animeDetailsParse(document: Document) = SAnime.create().apply { + title = document.selectFirst("#title span.title")!!.text() + status = SAnime.COMPLETED + with(document.selectFirst("div#longInfo")!!) { + thumbnail_url = selectFirst("img")?.absUrl("src") + genre = selectFirst("span.masha_index10")?.let { + it.text().split("/").joinToString() + } + description = select("#storyline > span > p").eachText().joinToString("\n") + author = selectFirst("strong:contains(Regie:) + div > a")?.text() + } + } + + // ============================== Episodes ============================== + override fun episodeListParse(response: Response): List { + val document = response.use { it.asJsoup() } + val episode = SEpisode.create().apply { + name = document.selectFirst("#title span.title")!!.text() + episode_number = 1F + setUrlWithoutDomain(document.location()) + } + return listOf(episode) + } override fun episodeListSelector() = throw Exception("not used") - override fun episodeListParse(response: Response): List { - val document = response.asJsoup() - val episodeList = mutableListOf() - val episode = SEpisode.create() - episode.name = document.select("#title span.title").text() - episode.episode_number = 1F - episode.setUrlWithoutDomain(document.select("meta[property=\"og:url\"]").attr("content")) - episodeList.add(episode) - return episodeList.reversed() - } - - override fun episodeListRequest(anime: SAnime): Request { - return GET(baseUrl + anime.url, headers = Headers.headersOf("if-modified-since", "")) - } - override fun episodeFromElement(element: Element): SEpisode = throw Exception("not used") - // Video Extractor - - override fun videoListRequest(episode: SEpisode): Request { - return GET(baseUrl + episode.url, headers = Headers.headersOf("if-modified-since", "")) - } + // ============================ Video Links ============================= + private val streamtapeExtractor by lazy { StreamTapeExtractor(client) } + private val doodExtractor by lazy { DoodExtractor(client) } + private val mixdropExtractor by lazy { MixDropExtractor(client) } override fun videoListParse(response: Response): List