remove 2dgirls.tech and add gogoanime

This commit is contained in:
jmir1
2021-06-16 19:08:53 +02:00
parent 3614863efa
commit 11b38f8b97
11 changed files with 149 additions and 208 deletions

View File

@ -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:92b69d1"
compileOnly "com.github.jmir1:extensions-lib:6467320"
// These are provided by the app itself
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

View File

@ -2,10 +2,10 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = '2dgirls.tech'
pkgNameSuffix = 'en.twodgirlstech'
extClass = '.TwoDGirlsTech'
extVersionCode = 12
extName = 'Gogoanime'
pkgNameSuffix = 'en.gogoanime'
extClass = '.GogoAnime'
extVersionCode = 1
libVersion = '11'
}
dependencies {

View File

@ -0,0 +1,144 @@
package eu.kanade.tachiyomi.animeextension.en.gogoanime
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.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.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
class GogoAnime : ParsedAnimeHttpSource() {
override val name = "Gogoanime"
override val baseUrl = "https://www1.gogoanime.ai"
override val lang = "en"
override val supportsLatest = true
override fun popularAnimeSelector(): String = "div.img a"
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/popular.html?page=$page")
override fun popularAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(element.attr("href"))
anime.thumbnail_url = element.select("img").first().attr("src")
anime.title = element.attr("title")
return anime
}
override fun popularAnimeNextPageSelector(): String = "ul.pagination-list li:last-child:not(.selected)"
override fun episodeListSelector() = "ul#episode_page li a"
override fun episodeListParse(response: Response): List<SEpisode> {
val document = response.asJsoup()
val totalEpisodes = document.select(episodeListSelector()).last().attr("ep_end")
val id = document.select("input#movie_id").attr("value")
return runBlocking { episodesRequest(totalEpisodes, id) }
}
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 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("li.dowloads a").attr("href")
val dlResponse = client.newCall(GET(link))
.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(" "))
val ep = element.selectFirst("div.name").ownText().substringAfter(" ")
episode.episode_number = ep.toFloat()
episode.name = "Episode $ep"
episode.date_upload = System.currentTimeMillis()
return episode
}
override fun episodeLinkSelector() = "div.mirror_link:has(a[download])"
override fun linksFromElement(element: Element): List<Link> {
val links = mutableListOf<Link>()
val linkElements = element.select("a[download]")
for (e in linkElements) {
val quality = e.text().substringAfter("Download (").replace("P - mp4)", "p")
links.add(Link(e.attr("href"), quality))
}
return links
}
override fun searchAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(element.attr("href"))
anime.thumbnail_url = element.select("img").first().attr("src")
anime.title = element.attr("title")
return anime
}
override fun searchAnimeNextPageSelector(): String = "ul.pagination-list li:last-child:not(.selected)"
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 animeDetailsParse(document: Document): SAnime {
val anime = SAnime.create()
anime.title = document.select("div.anime_info_body_bg h1").text()
anime.genre = document.select("p.type:eq(5) a").joinToString("") { it.text() }
anime.description = document.select("p.type:eq(4)").first().ownText()
anime.status = parseStatus(document.select("p.type:eq(7) a").text())
return anime
}
private fun parseStatus(statusString: String): Int {
return when (statusString) {
"Ongoing" -> SAnime.ONGOING
"Completed" -> SAnime.COMPLETED
else -> SAnime.UNKNOWN
}
}
override fun latestUpdatesNextPageSelector(): String = "ul.pagination-list li:last-child:not(.selected)"
override fun latestUpdatesFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(baseUrl + element.attr("href"))
val style = element.select("div.thumbnail-popular").attr("style")
anime.thumbnail_url = style.substringAfter("background: url('").substringBefore("');")
anime.title = element.attr("title")
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 latestUpdatesSelector(): String = "div.added_series_body.popular li a:has(div)"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

View File

@ -1,203 +0,0 @@
package eu.kanade.tachiyomi.animeextension.en.twodgirlstech
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.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Request
import okhttp3.Response
import org.json.JSONArray
import org.json.JSONObject
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import java.io.IOException
import java.net.URLEncoder
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class TwoDGirlsTech : ParsedAnimeHttpSource() {
override val name = "2dgirls.tech"
override val baseUrl = "https://2dgirls.tech"
override val lang = "en"
override val supportsLatest = false
override fun fetchPopularAnime(page: Int): Observable<AnimesPage> {
return Observable.just(runBlocking { get(page) })
}
suspend fun get(page: Int): AnimesPage {
var hasNextPage = true
val request = GET("$baseUrl/api/popular/$page")
val arrayListDetails: ArrayList<SAnime> = ArrayList()
return suspendCoroutine<AnimesPage> { continuation ->
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
throw e
}
override fun onResponse(call: Call, response: Response) {
val strResponse = response.body!!.string()
// creating json object
val json = JSONObject(strResponse)
// creating json array
val jsonArrayInfo: JSONArray = json.getJSONArray("results")
val size: Int = jsonArrayInfo.length()
for (i in 0 until size) {
val anime = SAnime.create()
val jsonObjectDetail: JSONObject = jsonArrayInfo.getJSONObject(i)
anime.title = jsonObjectDetail.getString("title")
anime.thumbnail_url = jsonObjectDetail.getString("image")
anime.setUrlWithoutDomain("/api/detailshtml/" + jsonObjectDetail.getString("id"))
arrayListDetails.add(anime)
}
hasNextPage = (arrayListDetails.isNotEmpty())
continuation.resume(AnimesPage(arrayListDetails, hasNextPage))
}
})
}
}
suspend fun setDetails(anime: SAnime): SAnime {
val request = GET("$baseUrl/api/details/${anime.url.split("/api/detailshtml/").last()}")
return suspendCoroutine<SAnime> { continuation ->
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
throw e
}
override fun onResponse(call: Call, response: Response) {
val strResponse = response.body!!.string()
// creating json object
val json = JSONObject(strResponse)
// creating json array
val jsonArrayInfo: JSONArray = json.getJSONArray("results")
val size: Int = jsonArrayInfo.length()
for (i in 0..size - 1) {
val jsonObjectDetail: JSONObject = jsonArrayInfo.getJSONObject(i)
anime.genre = jsonObjectDetail.getString("genres")
when (jsonObjectDetail.getString("status").replace("\\s".toRegex(), "")) {
"Ongoing" -> anime.status = SAnime.ONGOING
"Completed" -> anime.status = SAnime.COMPLETED
}
anime.description = jsonObjectDetail.getString("summary")
}
continuation.resume(anime)
}
})
}
}
override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage> {
return Observable.just(runBlocking { getSearch(page, query) })
}
suspend fun getSearch(page: Int, query: String): AnimesPage {
var hasNextPage: Boolean
val queryEncoded = withContext(Dispatchers.IO) { URLEncoder.encode(query, "utf-8") }
val request = GET("$baseUrl/api/search/$queryEncoded/$page")
val arrayListDetails: ArrayList<SAnime> = ArrayList()
return suspendCoroutine<AnimesPage> { continuation ->
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
throw e
}
override fun onResponse(call: Call, response: Response) {
val strResponse = response.body!!.string()
// creating json object
val json = JSONObject(strResponse)
// creating json array
val jsonArrayInfo: JSONArray = json.getJSONArray("results")
val size: Int = jsonArrayInfo.length()
for (i in 0..size - 1) {
val anime = SAnime.create()
val jsonObjectDetail: JSONObject = jsonArrayInfo.getJSONObject(i)
anime.title = jsonObjectDetail.getString("title")
anime.thumbnail_url = jsonObjectDetail.getString("image")
anime.setUrlWithoutDomain("/api/detailshtml/" + jsonObjectDetail.getString("id"))
arrayListDetails.add(anime)
}
hasNextPage = json.getBoolean("nextpage")
continuation.resume(AnimesPage(arrayListDetails, hasNextPage))
}
})
}
}
override fun fetchAnimeDetails(anime: SAnime): Observable<SAnime> {
return Observable.just(runBlocking { setDetails(anime) })
}
override fun episodeListSelector() = "div[id^=episode-]"
override fun fetchEpisodeList(anime: SAnime): Observable<List<SEpisode>> {
return super.fetchEpisodeList(anime).flatMap { Observable.just(it.reversed()) }
}
override fun episodeFromElement(element: Element): SEpisode {
val id = element.id().split(":").last()
val episodeNumber = element.id().split("episode-").last().split(":").first()
val episode = SEpisode.create()
episode.episode_number = episodeNumber.toFloat()
episode.name = "Episode $episodeNumber"
episode.url = "/api/watchinghtml/$id/$episodeNumber"
episode.date_upload = System.currentTimeMillis()
return episode
}
override fun episodeLinkSelector() = "body"
override fun linksFromElement(element: Element): List<Link> {
val json = JSONObject(element.text())
val jsonArrayInfo: JSONArray = json.getJSONArray("links")
val size: Int = jsonArrayInfo.length()
val urls = mutableListOf<Link>()
for (i in 0..size - 1) {
val jsonObjectDetail: JSONObject = jsonArrayInfo.getJSONObject(i)
urls.add(Link(jsonObjectDetail.getString("src"), jsonObjectDetail.getString("size")))
}
return urls
}
override fun popularAnimeSelector(): String = throw Exception("Not used")
override fun searchAnimeFromElement(element: Element): SAnime = throw Exception("Not used")
override fun searchAnimeNextPageSelector(): String? = throw Exception("Not used")
override fun searchAnimeSelector(): String = throw Exception("Not used")
override fun popularAnimeRequest(page: Int): Request = throw Exception("Not used")
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = throw Exception("Not used")
override fun popularAnimeNextPageSelector(): String? = throw Exception("Not used")
override fun popularAnimeFromElement(element: Element): SAnime = throw Exception("Not used")
override fun animeDetailsParse(document: Document): SAnime = throw Exception("Not used")
override fun latestUpdatesNextPageSelector(): String? = throw Exception("Not used")
override fun latestUpdatesFromElement(element: Element): SAnime = throw Exception("Not used")
override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not used")
override fun latestUpdatesSelector(): String = throw Exception("Not used")
companion object {
const val baseAltTextUrl = "https://fakeimg.pl/1500x2126/ffffff/000000/?text="
const val baseAltTextPostUrl = "&font_size=42&font=museo"
}
}