Merge pull request #32 from jmir1/lib12
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
// used both in common.gradle and themesources library
|
||||
dependencies {
|
||||
// Lib 1.3, but using specific commit so we don't need to bump up the version
|
||||
compileOnly "com.github.jmir1:extensions-lib:6467320"
|
||||
compileOnly "com.github.jmir1:extensions-lib:632a3e4"
|
||||
|
||||
// These are provided by the app itself
|
||||
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
@ -5,8 +5,8 @@ ext {
|
||||
extName = '4anime.to'
|
||||
pkgNameSuffix = 'en.fouranime'
|
||||
extClass = '.FourAnime'
|
||||
extVersionCode = 11
|
||||
libVersion = '11'
|
||||
extVersionCode = 12
|
||||
libVersion = '12'
|
||||
}
|
||||
dependencies {
|
||||
ext.coroutinesVersion = "1.4.3"
|
||||
|
@ -1,9 +1,9 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.fouranime
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.Link
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
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.network.GET
|
||||
import okhttp3.Request
|
||||
@ -58,12 +58,21 @@ class FourAnime : ParsedAnimeHttpSource() {
|
||||
text.replace("[^\\d]".toRegex(), "").toFloat() + firstLetterAsNumber
|
||||
}
|
||||
}
|
||||
override fun episodeLinkSelector() = "source"
|
||||
|
||||
override fun linksFromElement(element: Element): List<Link> {
|
||||
return mutableListOf(Link(element.attr("src"), "1080p"))
|
||||
override fun videoListSelector() = "source"
|
||||
|
||||
override fun videoFromElement(element: Element): Video {
|
||||
return Video(element.attr("src"), "1080p", null, null)
|
||||
}
|
||||
|
||||
override fun fetchVideoUrl(video: Video): Observable<String> {
|
||||
return Observable.just(video.url)
|
||||
}
|
||||
|
||||
override fun videoUrlSelector() = throw Exception("not used")
|
||||
|
||||
override fun videoUrlFromElement(element: Element) = throw Exception("not used")
|
||||
|
||||
override fun searchAnimeFromElement(element: Element): SAnime {
|
||||
val anime = SAnime.create()
|
||||
anime.setUrlWithoutDomain(element.select("a").attr("href"))
|
||||
|
@ -5,8 +5,8 @@ ext {
|
||||
extName = 'Gogoanime'
|
||||
pkgNameSuffix = 'en.gogoanime'
|
||||
extClass = '.GogoAnime'
|
||||
extVersionCode = 5
|
||||
libVersion = '11'
|
||||
extVersionCode = 6
|
||||
libVersion = '12'
|
||||
}
|
||||
dependencies {
|
||||
ext.coroutinesVersion = "1.4.3"
|
||||
|
@ -1,23 +1,22 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.gogoanime
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.JsonParser
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.Link
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
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.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Headers.Companion.toHeaders
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import rx.Observable
|
||||
import java.lang.Exception
|
||||
|
||||
class GogoAnime : ParsedAnimeHttpSource() {
|
||||
|
||||
@ -29,6 +28,8 @@ class GogoAnime : ParsedAnimeHttpSource() {
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client: OkHttpClient = network.cloudflareClient
|
||||
|
||||
override fun popularAnimeSelector(): String = "div.img a"
|
||||
|
||||
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/popular.html?page=$page")
|
||||
@ -53,30 +54,13 @@ class GogoAnime : ParsedAnimeHttpSource() {
|
||||
}
|
||||
|
||||
private suspend fun episodesRequest(totalEpisodes: String, id: String): List<SEpisode> {
|
||||
val request = GET("https://ajax.gogo-load.com/ajax/load-list-episode?ep_start=0&ep_end=$totalEpisodes&id=$id")
|
||||
val request = GET("https://ajax.gogo-load.com/ajax/load-list-episode?ep_start=0&ep_end=$totalEpisodes&id=$id", headers)
|
||||
val epResponse = client.newCall(request)
|
||||
.await()
|
||||
val document = epResponse.asJsoup()
|
||||
return document.select("a").map { episodeFromElement(it) }
|
||||
}
|
||||
|
||||
override fun fetchEpisodeLink(episode: SEpisode): Observable<List<Link>> {
|
||||
return client.newCall(GET(baseUrl + episode.url))
|
||||
.asObservableSuccess()
|
||||
.map { response ->
|
||||
runBlocking { linkRequest(response) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun linkRequest(response: Response): List<Link> {
|
||||
val elements = response.asJsoup()
|
||||
val link = elements.select("a[data-video*=streamani.net/load.php]").attr("data-video")
|
||||
val dlResponse = client.newCall(GET("https:$link", Headers.headersOf("referer", baseUrl)))
|
||||
.await()
|
||||
val document = dlResponse.asJsoup()
|
||||
return linksFromElement(document.select(episodeLinkSelector()).first())
|
||||
}
|
||||
|
||||
override fun episodeFromElement(element: Element): SEpisode {
|
||||
val episode = SEpisode.create()
|
||||
episode.setUrlWithoutDomain(baseUrl + element.attr("href").substringAfter(" "))
|
||||
@ -87,12 +71,26 @@ class GogoAnime : ParsedAnimeHttpSource() {
|
||||
return episode
|
||||
}
|
||||
|
||||
override fun episodeLinkSelector() = "div.videocontent script"
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val document = response.asJsoup()
|
||||
var videoListUrl = document.selectFirst("a[data-video*=streamani.net/load.php]").attr("data-video")
|
||||
if (!videoListUrl.startsWith("https:")) videoListUrl = "https:$videoListUrl"
|
||||
val newHeaderList = mutableMapOf(Pair("referer", baseUrl))
|
||||
headers.forEach { newHeaderList[it.first] = it.second }
|
||||
val videoListResponse = runBlocking {
|
||||
client.newCall(GET(videoListUrl, newHeaderList.toHeaders()))
|
||||
.await().asJsoup()
|
||||
}
|
||||
return videoListFromElement(videoListResponse.selectFirst(videoListSelector()))
|
||||
}
|
||||
|
||||
override fun linksFromElement(element: Element): List<Link> {
|
||||
val links = mutableListOf<Link>()
|
||||
override fun videoListSelector() = "div.videocontent script"
|
||||
|
||||
override fun videoFromElement(element: Element) = throw Exception("not used")
|
||||
|
||||
private fun videoListFromElement(element: Element): List<Video> {
|
||||
val videos = mutableListOf<Video>()
|
||||
val content = element.data()
|
||||
Log.i("links", content)
|
||||
var hit = content.indexOf("playerInstance.setup(")
|
||||
while (hit >= 0) {
|
||||
val objectString =
|
||||
@ -106,36 +104,37 @@ class GogoAnime : ParsedAnimeHttpSource() {
|
||||
link = link.replace("/videos/hls/$toRemove", "/videos/hls/")
|
||||
}
|
||||
val quality = jsonObject["label"].asString
|
||||
Log.i("links:", "$link - $quality")
|
||||
if (links.isEmpty() || !links.last().url.contains(link.substringAfterLast("/"))) {
|
||||
if (videos.isEmpty() || !videos.last().url.contains(link.substringAfterLast("/"))) {
|
||||
if (link.contains("m3u8")) {
|
||||
val individualLinks = runBlocking { getIndividualLinks(link) }
|
||||
individualLinks.forEach { links.add(it) }
|
||||
individualLinks.forEach { videos.add(it) }
|
||||
} else {
|
||||
links.add(Link(link, quality))
|
||||
videos.add(Video(link, quality, link, null))
|
||||
}
|
||||
}
|
||||
hit = content.indexOf("playerInstance.setup(", hit + 1)
|
||||
}
|
||||
return links
|
||||
return videos
|
||||
}
|
||||
|
||||
private suspend fun getIndividualLinks(link: String): List<Link> {
|
||||
private suspend fun getIndividualLinks(link: String): List<Video> {
|
||||
val response = client.newCall(GET(link)).await().body!!.string()
|
||||
Log.i("links", response)
|
||||
val links = response.split("\n").filter { !it.startsWith("#") && it.isNotEmpty() }.toMutableList()
|
||||
val qualities = response.split("\n").filter { it.startsWith("#EXT-X-STREAM-INF") }.toMutableList()
|
||||
Log.i("links", links.lastIndex.toString() + qualities.lastIndex.toString())
|
||||
val linkList = mutableListOf<Link>()
|
||||
val linkList = mutableListOf<Video>()
|
||||
if (qualities.lastIndex != links.lastIndex) return emptyList()
|
||||
for (i in 0..qualities.lastIndex) {
|
||||
links[i] = link.substringBeforeLast("/") + "/" + links[i]
|
||||
qualities[i] = qualities[i].substringAfter("NAME=").replace("\"", "")
|
||||
linkList.add(Link(links[i], qualities[i]))
|
||||
linkList.add(Video(links[i], qualities[i], links[i], null))
|
||||
}
|
||||
return linkList.reversed()
|
||||
}
|
||||
|
||||
override fun videoUrlFromElement(element: Element): String = throw Exception("not used")
|
||||
|
||||
override fun videoUrlSelector() = throw Exception("not used")
|
||||
|
||||
override fun searchAnimeFromElement(element: Element): SAnime {
|
||||
val anime = SAnime.create()
|
||||
anime.setUrlWithoutDomain(element.attr("href"))
|
||||
@ -148,7 +147,8 @@ class GogoAnime : ParsedAnimeHttpSource() {
|
||||
|
||||
override fun searchAnimeSelector(): String = "div.img a"
|
||||
|
||||
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = GET("$baseUrl/search.html?keyword=$query&page=$page")
|
||||
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request =
|
||||
GET("$baseUrl/search.html?keyword=$query&page=$page", headers)
|
||||
|
||||
override fun animeDetailsParse(document: Document): SAnime {
|
||||
val anime = SAnime.create()
|
||||
@ -178,7 +178,8 @@ class GogoAnime : ParsedAnimeHttpSource() {
|
||||
return anime
|
||||
}
|
||||
|
||||
override fun latestUpdatesRequest(page: Int): Request = GET("https://ajax.gogo-load.com/ajax/page-recent-release-ongoing.html?page=$page&type=1")
|
||||
override fun latestUpdatesRequest(page: Int): Request =
|
||||
GET("https://ajax.gogo-load.com/ajax/page-recent-release-ongoing.html?page=$page&type=1", headers)
|
||||
|
||||
override fun latestUpdatesSelector(): String = "div.added_series_body.popular li a:has(div)"
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ ext {
|
||||
extName = 'hanime.tv'
|
||||
pkgNameSuffix = 'en.hanime'
|
||||
extClass = '.Hanime'
|
||||
extVersionCode = 6
|
||||
libVersion = '11'
|
||||
extVersionCode = 7
|
||||
libVersion = '12'
|
||||
containsNsfw = true
|
||||
}
|
||||
dependencies {
|
||||
|
@ -6,9 +6,9 @@ import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.Link
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
@ -117,16 +117,16 @@ class Hanime : AnimeHttpSource() {
|
||||
return anime
|
||||
}
|
||||
|
||||
override fun episodeLinkParse(response: Response): List<Link> {
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val responseString = response.body!!.string()
|
||||
val jElement: JsonElement = JsonParser.parseString(responseString)
|
||||
val jObject: JsonObject = jElement.asJsonObject
|
||||
val server = jObject.get("videos_manifest").asJsonObject.get("servers").asJsonArray[0].asJsonObject
|
||||
val streams = server.get("streams").asJsonArray
|
||||
val linkList = mutableListOf<Link>()
|
||||
val linkList = mutableListOf<Video>()
|
||||
for (stream in streams) {
|
||||
if (stream.asJsonObject.get("kind").asString != "premium_alert") {
|
||||
linkList.add(Link(stream.asJsonObject.get("url").asString, stream.asJsonObject.get("height").asString + "p"))
|
||||
linkList.add(Video(stream.asJsonObject.get("url").asString, stream.asJsonObject.get("height").asString + "p", stream.asJsonObject.get("url").asString, null))
|
||||
}
|
||||
}
|
||||
return linkList
|
||||
|
@ -5,8 +5,8 @@ ext {
|
||||
extName = 'tenshi.moe'
|
||||
pkgNameSuffix = 'en.tenshimoe'
|
||||
extClass = '.TenshiMoe'
|
||||
extVersionCode = 16
|
||||
libVersion = '11'
|
||||
extVersionCode = 17
|
||||
libVersion = '12'
|
||||
}
|
||||
dependencies {
|
||||
ext.coroutinesVersion = "1.4.3"
|
||||
|
@ -3,22 +3,21 @@ package eu.kanade.tachiyomi.animeextension.en.tenshimoe
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.Log
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.Link
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
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.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Headers.Companion.toHeaders
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import rx.Observable
|
||||
import java.lang.Exception
|
||||
import java.lang.Float.parseFloat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
@ -47,7 +46,7 @@ class TenshiMoe : ParsedAnimeHttpSource() {
|
||||
return anime
|
||||
}
|
||||
|
||||
override fun popularAnimeNextPageSelector(): String? = "ul.pagination li.page-item a[rel=next]"
|
||||
override fun popularAnimeNextPageSelector(): String = "ul.pagination li.page-item a[rel=next]"
|
||||
|
||||
override fun episodeListSelector() = "ul.episode-loop li a"
|
||||
|
||||
@ -88,34 +87,30 @@ class TenshiMoe : ParsedAnimeHttpSource() {
|
||||
return Date(-1L)
|
||||
}
|
||||
|
||||
override fun fetchEpisodeLink(episode: SEpisode): Observable<List<Link>> {
|
||||
return client.newCall(GET(baseUrl + episode.url))
|
||||
.asObservableSuccess()
|
||||
.map { response ->
|
||||
Log.w("tenshi", "linkReq")
|
||||
runBlocking { linkRequest(response) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun linkRequest(response: Response): List<Link> {
|
||||
val elements = response.asJsoup()
|
||||
val link = elements.select("iframe").attr("src")
|
||||
val dlResponse = client.newCall(GET(link, Headers.headersOf("referer", response.request.url.toString()))).await()
|
||||
val document = dlResponse.asJsoup()
|
||||
return linksFromElement(document.select(episodeLinkSelector()).first())
|
||||
}
|
||||
|
||||
override fun episodeLinkSelector() = "video#player"
|
||||
|
||||
override fun linksFromElement(element: Element): List<Link> {
|
||||
val linkList = mutableListOf<Link>()
|
||||
val linkElements = element.select("source")
|
||||
for (link in linkElements) {
|
||||
linkList.add(Link(link.attr("src"), link.attr("title")))
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val document = response.asJsoup()
|
||||
val iframe = document.selectFirst("iframe").attr("src")
|
||||
val referer = response.request.url.encodedPath
|
||||
val newHeaderList = mutableMapOf(Pair("referer", baseUrl + referer))
|
||||
headers.forEach { newHeaderList[it.first] = it.second }
|
||||
val iframeResponse = runBlocking {
|
||||
client.newCall(GET(iframe, newHeaderList.toHeaders()))
|
||||
.await().asJsoup()
|
||||
}
|
||||
return linkList
|
||||
return iframeResponse.select(videoListSelector()).map { videoFromElement(it) }
|
||||
}
|
||||
|
||||
override fun videoListSelector() = "source"
|
||||
|
||||
override fun videoFromElement(element: Element): Video {
|
||||
Log.i("lol", element.attr("src"))
|
||||
return Video(element.attr("src"), element.attr("title"), element.attr("src"), null)
|
||||
}
|
||||
|
||||
override fun videoUrlFromElement(element: Element): String = throw Exception("not used")
|
||||
|
||||
override fun videoUrlSelector() = throw Exception("not used")
|
||||
|
||||
override fun searchAnimeFromElement(element: Element): SAnime {
|
||||
val anime = SAnime.create()
|
||||
anime.setUrlWithoutDomain(element.attr("href") + "?s=srt-d")
|
||||
|
Reference in New Issue
Block a user