forked from recloudstream/cloudstream
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
f7b623ffc7
3 changed files with 130 additions and 16 deletions
|
@ -1139,21 +1139,8 @@ interface LoadResponse {
|
||||||
|
|
||||||
fun getDurationFromString(input: String?): Int? {
|
fun getDurationFromString(input: String?): Int? {
|
||||||
val cleanInput = input?.trim()?.replace(" ", "") ?: return null
|
val cleanInput = input?.trim()?.replace(" ", "") ?: return null
|
||||||
Regex("([0-9]*)h.*?([0-9]*)m").find(cleanInput)?.groupValues?.let { values ->
|
//Use first as sometimes the text passes on the 2 other Regex, but failed to provide accurate return value
|
||||||
if (values.size == 3) {
|
Regex("(\\d+\\shr)|(\\d+\\shour)|(\\d+\\smin)|(\\d+\\ssec)").findAll(input).let { values ->
|
||||||
val hours = values[1].toIntOrNull()
|
|
||||||
val minutes = values[2].toIntOrNull()
|
|
||||||
if (minutes != null && hours != null) {
|
|
||||||
return hours * 60 + minutes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Regex("([0-9]*)m").find(cleanInput)?.groupValues?.let { values ->
|
|
||||||
if (values.size == 2) {
|
|
||||||
return values[1].toIntOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Regex("(\\s\\d+\\shr)|(\\s\\d+\\shour)|(\\s\\d+\\smin)|(\\s\\d+\\ssec)").findAll(input).let { values ->
|
|
||||||
var seconds = 0
|
var seconds = 0
|
||||||
values.forEach {
|
values.forEach {
|
||||||
val time_text = it.value
|
val time_text = it.value
|
||||||
|
@ -1174,6 +1161,23 @@ fun getDurationFromString(input: String?): Int? {
|
||||||
return seconds / 60
|
return seconds / 60
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Regex("([0-9]*)h.*?([0-9]*)m").find(cleanInput)?.groupValues?.let { values ->
|
||||||
|
if (values.size == 3) {
|
||||||
|
val hours = values[1].toIntOrNull()
|
||||||
|
val minutes = values[2].toIntOrNull()
|
||||||
|
if (minutes != null && hours != null) {
|
||||||
|
return hours * 60 + minutes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Regex("([0-9]*)m").find(cleanInput)?.groupValues?.let { values ->
|
||||||
|
if (values.size == 2) {
|
||||||
|
val return_value = values[1].toIntOrNull()
|
||||||
|
if (return_value != null) {
|
||||||
|
return return_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI {
|
||||||
val aniListApi = AniListApi(0)
|
val aniListApi = AniListApi(0)
|
||||||
val openSubtitlesApi = OpenSubtitlesApi(0)
|
val openSubtitlesApi = OpenSubtitlesApi(0)
|
||||||
val indexSubtitlesApi = IndexSubtitleApi()
|
val indexSubtitlesApi = IndexSubtitleApi()
|
||||||
|
val addic7ed = Addic7ed()
|
||||||
|
|
||||||
// used to login via app intent
|
// used to login via app intent
|
||||||
val OAuth2Apis
|
val OAuth2Apis
|
||||||
|
@ -37,7 +38,8 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI {
|
||||||
val subtitleProviders
|
val subtitleProviders
|
||||||
get() = listOf(
|
get() = listOf(
|
||||||
openSubtitlesApi,
|
openSubtitlesApi,
|
||||||
indexSubtitlesApi // they got anti scraping measures in place :(
|
indexSubtitlesApi, // they got anti scraping measures in place :(
|
||||||
|
addic7ed
|
||||||
)
|
)
|
||||||
|
|
||||||
const val appString = "cloudstreamapp"
|
const val appString = "cloudstreamapp"
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
package com.lagradost.cloudstream3.syncproviders.providers
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.TvType
|
||||||
|
import com.lagradost.cloudstream3.app
|
||||||
|
import com.lagradost.cloudstream3.subtitles.AbstractSubApi
|
||||||
|
import com.lagradost.cloudstream3.subtitles.AbstractSubtitleEntities
|
||||||
|
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
||||||
|
|
||||||
|
class Addic7ed : AbstractSubApi {
|
||||||
|
override val name = "Addic7ed"
|
||||||
|
override val idPrefix = "addic7ed"
|
||||||
|
override val requiresLogin = false
|
||||||
|
override val icon: Nothing? = null
|
||||||
|
override val createAccountUrl: Nothing? = null
|
||||||
|
|
||||||
|
override fun loginInfo(): Nothing? = null
|
||||||
|
|
||||||
|
override fun logOut() {}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val host = "https://www.addic7ed.com"
|
||||||
|
const val TAG = "ADDIC7ED"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fixUrl(url: String): String {
|
||||||
|
return if (url.startsWith("/")) host + url
|
||||||
|
else if (!url.startsWith("http")) "$host/$url"
|
||||||
|
else url
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun search(query: AbstractSubtitleEntities.SubtitleSearch): List<AbstractSubtitleEntities.SubtitleEntity> {
|
||||||
|
val lang = query.lang
|
||||||
|
val queryLang = SubtitleHelper.fromTwoLettersToLanguage(lang.toString())
|
||||||
|
val queryText = query.query.trim()
|
||||||
|
val epNum = query.epNumber ?: 0
|
||||||
|
val seasonNum = query.seasonNumber ?: 0
|
||||||
|
val yearNum = query.year ?: 0
|
||||||
|
|
||||||
|
fun cleanResources(
|
||||||
|
results: MutableList<AbstractSubtitleEntities.SubtitleEntity>,
|
||||||
|
name: String,
|
||||||
|
link: String,
|
||||||
|
headers: Map<String, String>,
|
||||||
|
isHearingImpaired: Boolean
|
||||||
|
) {
|
||||||
|
results.add(
|
||||||
|
AbstractSubtitleEntities.SubtitleEntity(
|
||||||
|
idPrefix = idPrefix,
|
||||||
|
name = name,
|
||||||
|
lang = queryLang.toString(),
|
||||||
|
data = link,
|
||||||
|
source = this.name,
|
||||||
|
type = if (seasonNum > 0) TvType.TvSeries else TvType.Movie,
|
||||||
|
epNumber = epNum,
|
||||||
|
seasonNumber = seasonNum,
|
||||||
|
year = yearNum,
|
||||||
|
headers = headers,
|
||||||
|
isHearingImpaired = isHearingImpaired
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val title = queryText.substringBefore("(").trim()
|
||||||
|
val url = "$host/search.php?search=${title}&Submit=Search"
|
||||||
|
val hostDocument = app.get(url).document
|
||||||
|
var searchResult = ""
|
||||||
|
if (!hostDocument.select("span:contains($title)").isNullOrEmpty()) searchResult = url
|
||||||
|
else if (!hostDocument.select("table.tabel")
|
||||||
|
.isNullOrEmpty()
|
||||||
|
) searchResult = hostDocument.select("a:contains($title)").attr("href").toString()
|
||||||
|
else {
|
||||||
|
val show =
|
||||||
|
hostDocument.selectFirst("#sl button")?.attr("onmouseup")?.substringAfter("(")
|
||||||
|
?.substringBefore(",")
|
||||||
|
val doc = app.get(
|
||||||
|
"$host/ajax_loadShow.php?show=$show&season=$seasonNum&langs=&hd=undefined&hi=undefined",
|
||||||
|
referer = "$host/"
|
||||||
|
).document
|
||||||
|
doc.select("#season tr:contains($queryLang)").mapNotNull { node ->
|
||||||
|
if (node.selectFirst("td")?.text()
|
||||||
|
?.toIntOrNull() == seasonNum && node.select("td:eq(1)")
|
||||||
|
.text()
|
||||||
|
.toIntOrNull() == epNum
|
||||||
|
) searchResult = fixUrl(node.select("a").attr("href"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val results = mutableListOf<AbstractSubtitleEntities.SubtitleEntity>()
|
||||||
|
val document = app.get(
|
||||||
|
url = fixUrl(searchResult),
|
||||||
|
).document
|
||||||
|
|
||||||
|
document.select(".tabel95 .tabel95 tr:contains($queryLang)").mapNotNull { node ->
|
||||||
|
val name = if (seasonNum > 0) "${document.select(".titulo").text().replace("Subtitle","").trim()}${
|
||||||
|
node.parent()!!.select(".NewsTitle").text().substringAfter("Version").substringBefore(", Duration")
|
||||||
|
}" else "${document.select(".titulo").text().replace("Subtitle","").trim()}${node.parent()!!.select(".NewsTitle").text().substringAfter("Version").substringBefore(", Duration")}"
|
||||||
|
val link = fixUrl(node.select("a.buttonDownload").attr("href"))
|
||||||
|
val isHearingImpaired =
|
||||||
|
!node.parent()!!.select("tr:last-child [title=\"Hearing Impaired\"]").isNullOrEmpty()
|
||||||
|
cleanResources(results, name, link, mapOf("referer" to "$host/"), isHearingImpaired)
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun load(data: AbstractSubtitleEntities.SubtitleEntity): String {
|
||||||
|
return data.data
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue