package com.hexated import android.util.Log import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import org.json.JSONObject import java.net.URI private const val TRACKER_LIST_URL = "https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt" class StremioC : MainAPI() { override var mainUrl = "https://stremio.github.io/stremio-static-addon-example" override var name = "StremioC" override val supportedTypes = setOf(TvType.Others) override val hasMainPage = true private val cinemataUrl = "https://v3-cinemeta.strem.io" override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse? { mainUrl = mainUrl.fixSourceUrl() val res = tryParseJson(app.get("${mainUrl}/manifest.json").text) ?: return null val lists = mutableListOf() res.catalogs.forEach { catalog -> catalog.toHomePageList(this)?.let { if(it.list.isNotEmpty()) lists.add(it) } } return HomePageResponse( lists, false ) } override suspend fun search(query: String): List? { mainUrl = mainUrl.fixSourceUrl() 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 = parseJson(url) mainUrl = if((res.type == "movie" || res.type == "series") && isImdborTmdb(res.id)) cinemataUrl else mainUrl val json = app.get("${mainUrl}/meta/${res.type}/${res.id}.json") .parsedSafe()?.meta ?: throw RuntimeException(url) return json.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(this, subtitleCallback, callback) } return true } // check if id is imdb/tmdb cause stremio addons like torrentio works base on imdbId private fun isImdborTmdb(url: String?): Boolean { return imdbUrlToIdNullable(url) != null || url?.startsWith("tmdb:") == 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: StremioC): List { val entries = mutableListOf() types.forEach { type -> val json = app.get("${provider.mainUrl}/catalog/${type}/${id}/search=${query}.json").text val res = tryParseJson(json) ?: return@forEach res.metas?.forEach { entry -> entries.add(entry.toSearchResponse(provider)) } } return entries } suspend fun toHomePageList(provider: StremioC): HomePageList? { val entries = mutableListOf() types.forEach { type -> val json = app.get("${provider.mainUrl}/catalog/${type}/${id}.json").text val res = tryParseJson(json) ?: return@forEach res.metas?.forEach { entry -> entries.add(entry.toSearchResponse(provider)) } } return HomePageList( "$type - ${name ?: id}", entries ) } } private data class CatalogResponse(val metas: List?, val meta: CatalogEntry?) private data class CatalogEntry( val name: String, val id: String, val poster: String?, val background: String?, val description: String?, val imdbRating: String?, val type: String?, val videos: List