diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt index defd6f698f..ced827eecb 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt @@ -5,6 +5,7 @@ import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.ExtractorLinkType import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.newExtractorLink @@ -20,27 +21,45 @@ open class Gofile : ExtractorApi() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ) { - val id = Regex("/(?:\\?c=|d/)([\\da-zA-Z-]+)").find(url)?.groupValues?.get(1) - val token = app.get("$mainApi/createAccount").parsedSafe()?.data?.get("token") - val websiteToken = app.get("$mainUrl/dist/js/alljs.js").text.let { - Regex("fetchData.wt\\s*=\\s*\"([^\"]+)").find(it)?.groupValues?.get(1) - } - app.get("$mainApi/getContent?contentId=$id&token=$token&wt=$websiteToken") - .parsedSafe()?.data?.contents?.forEach { - callback.invoke( - newExtractorLink( - this.name, - this.name, - it.value["link"] ?: return, - ) { - this.quality = getQuality(it.value["name"]) - this.headers = mapOf( - "Cookie" to "accountToken=$token" - ) - } - ) - } + val id = Regex("/(?:\\?c=|d/)([\\da-zA-Z-]+)").find(url)?.groupValues?.get(1) ?: return + + val token = app.post( + "$mainApi/accounts", + ).parsedSafe()?.data?.token ?: return + + val globalRes = app.get("$mainUrl/dist/js/config.js").text + val wt = Regex("""appdata\.wt\s*=\s*[\"']([^\"']+)[\"']""").find(globalRes)?.groupValues?.get(1) ?: return + + val headers = mapOf( + "Authorization" to "Bearer $token", + "X-Website-Token" to wt + ) + + val parsedResponse = app.get( + "$mainApi/contents/$id?contentFilter=&page=1&pageSize=1000&sortField=name&sortDirection=1", + headers = headers + ).parsedSafe() + + val childrenMap = parsedResponse?.data?.children ?: return + + for ((_, file) in childrenMap) { + if (file.link.isNullOrEmpty() || file.type != "file") continue + val fileName = file.name ?: "" + val size = file.size ?: 0L + val formattedSize = formatBytes(size) + callback.invoke( + newExtractorLink( + "Gofile", + "[Gofile] $fileName [$formattedSize]", + file.link, + ExtractorLinkType.VIDEO + ) { + this.quality = getQuality(fileName) + this.headers = mapOf("Cookie" to "accountToken=$token") + } + ) + } } private fun getQuality(str: String?): Int { @@ -48,16 +67,33 @@ open class Gofile : ExtractorApi() { ?: Qualities.Unknown.value } - data class Account( - @JsonProperty("data") val data: HashMap? = null, + private fun formatBytes(bytes: Long): String { + return when { + bytes < 1024L * 1024 * 1024 -> "%.2f MB".format(bytes.toDouble() / (1024 * 1024)) + else -> "%.2f GB".format(bytes.toDouble() / (1024 * 1024 * 1024)) + } + } + + data class AccountResponse( + @JsonProperty("data") val data: AccountData? = null ) - data class Data( - @JsonProperty("contents") val contents: HashMap>? = null, + data class AccountData( + @JsonProperty("token") val token: String? = null ) - data class Source( - @JsonProperty("data") val data: Data? = null, + data class GofileResponse( + @JsonProperty("data") val data: GofileData? = null ) + data class GofileData( + @JsonProperty("children") val children: Map? = null + ) + + data class GofileFile( + @JsonProperty("type") val type: String? = null, + @JsonProperty("name") val name: String? = null, + @JsonProperty("link") val link: String? = null, + @JsonProperty("size") val size: Long? = 0L + ) }