package com.lagradost import android.util.Log import com.lagradost.StremioProvider.Companion.encodeUri import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.loadExtractor import org.json.JSONObject import java.net.URLEncoder private const val TRACKER_LIST_URL = "https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt" class StremioProvider : MainAPI() { override var mainUrl = "https://stremio.github.io/stremio-static-addon-example" override var name = "Stremio example" override val supportedTypes = setOf(TvType.Others) override val hasMainPage = true override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse? { val res = tryParseJson(app.get("${mainUrl}/manifest.json").text) ?: return null val lists = mutableListOf() res.catalogs.forEach { catalog -> catalog.toHomePageList(this)?.let { lists.add(it) } } return HomePageResponse( lists, false ) } override suspend fun search(query: String): List? { val res = tryParseJson(app.get("${mainUrl}/manifest.json").text) ?: return null val list = mutableListOf() res.catalogs.forEach { catalog -> list.addAll(catalog.search(query, this)) } return list } override suspend fun load(url: String): LoadResponse? { val res = tryParseJson(url) ?: throw RuntimeException(url) return res.toLoadResponse(this) } override suspend fun loadLinks( data: String, isCasting: Boolean, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { val res = tryParseJson(app.get(data).text) ?: return false res.streams.forEach { stream -> stream.runCallback(subtitleCallback, callback) } return true } private data class Manifest(val catalogs: List) private data class Catalog( var name: String?, val id: String, val type: String?, val types: MutableList = mutableListOf() ) { init { if (type != null) types.add(type) } suspend fun search(query: String, provider: StremioProvider): List { val entries = mutableListOf() types.forEach { type -> val res = tryParseJson(app.get("${provider.mainUrl}/catalog/${type.encodeUri()}/${id.encodeUri()}/search=${query.encodeUri()}.json").text) ?: return@forEach res.metas.forEach { entry -> entries.add(entry.toSearchResponse(provider)) } } return entries } suspend fun toHomePageList(provider: StremioProvider): HomePageList? { val entries = mutableListOf() types.forEach { type -> val res = tryParseJson(app.get("${provider.mainUrl}/catalog/${type.encodeUri()}/${id.encodeUri()}.json").text) ?: return@forEach res.metas.forEach { entry -> entries.add(entry.toSearchResponse(provider)) } } return HomePageList( name ?: id, entries ) } } private data class CatalogResponse(val metas: List) private data class CatalogEntry( val name: String, val id: String, val poster: String?, val description: String?, val type: String?, val videos: List