Some chinese sources update (#1022)
Close #957 Checklist: - [x] Updated `extVersionCode` value in `build.gradle` for individual extensions - [ ] Updated `overrideVersionCode` or `baseVersionCode` as needed for all multisrc extensions - [x] Referenced all related issues in the PR body (e.g. "Closes #xyz") - [ ] Added the `isNsfw = true` flag in `build.gradle` when appropriate - [x] Have not changed source names - [ ] Have explicitly kept the `id` if a source's name or language were changed - [x] Have tested the modifications by compiling and running the extension through Android Studio - [ ] Have removed `web_hi_res_512.png` when adding a new extension - [ ] Have made sure all the icons are in png format Co-authored-by: AlphaBoom <30779939+AlphaBoom@users.noreply.github.com> Co-authored-by: ZhendongWu <30779939+AlphaBoom@users.noreply.github.com> Reviewed-on: #1022 Co-authored-by: AlphaBoom <alphaboom@noreply.localhost> Co-committed-by: AlphaBoom <alphaboom@noreply.localhost>
This commit is contained in:
parent
f97d742c40
commit
1018982a2e
4 changed files with 50 additions and 29 deletions
|
@ -1,7 +1,7 @@
|
|||
ext {
|
||||
extName = 'Hanime1'
|
||||
extClass = '.Hanime1'
|
||||
extVersionCode = 4
|
||||
extVersionCode = 5
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.animeextension.zh.hanime1
|
|||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
|
@ -16,12 +17,15 @@ import eu.kanade.tachiyomi.network.GET
|
|||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import okhttp3.Cookie
|
||||
|
@ -65,14 +69,32 @@ class Hanime1 : AnimeHttpSource(), ConfigurableAnimeSource {
|
|||
}
|
||||
|
||||
override fun animeDetailsParse(response: Response): SAnime {
|
||||
val jsoup = response.asJsoup()
|
||||
val doc = response.asJsoup()
|
||||
return SAnime.create().apply {
|
||||
genre = jsoup.select(".single-video-tag").not("[data-toggle]").eachText().joinToString()
|
||||
author = jsoup.select("#video-artist-name").text()
|
||||
jsoup.select("script[type=application/ld+json]").first()?.data()?.let {
|
||||
genre = doc.select(".single-video-tag").not("[data-toggle]").eachText().joinToString()
|
||||
author = doc.select("#video-artist-name").text()
|
||||
doc.select("script[type=application/ld+json]").first()?.data()?.let {
|
||||
val info = json.decodeFromString<JsonElement>(it).jsonObject
|
||||
title = info["name"]!!.jsonPrimitive.content
|
||||
description = info["description"]!!.jsonPrimitive.content
|
||||
thumbnail_url = info["thumbnailUrl"]?.jsonArray?.get(0)?.jsonPrimitive?.content
|
||||
}
|
||||
val type = doc.select("a#video-artist-name + a").text().trim()
|
||||
if (type == "裏番" || type == "泡麵番") {
|
||||
// Use the series cover image for bangumi entries instead of the episode image.
|
||||
runBlocking {
|
||||
try {
|
||||
val animesPage =
|
||||
getSearchAnime(
|
||||
1,
|
||||
title,
|
||||
AnimeFilterList(GenreFilter(arrayOf("", type)).apply { state = 1 }),
|
||||
)
|
||||
thumbnail_url = animesPage.animes.first().thumbnail_url
|
||||
} catch (e: Exception) {
|
||||
Log.e(name, "Failed to get bangumi cover image")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +159,7 @@ class Hanime1 : AnimeHttpSource(), ConfigurableAnimeSource {
|
|||
|
||||
override fun searchAnimeParse(response: Response): AnimesPage {
|
||||
val jsoup = response.asJsoup()
|
||||
val nodes = jsoup.select("div.search-doujin-videos.hidden-xs")
|
||||
val nodes = jsoup.select("div.search-doujin-videos.hidden-xs:not(:has(a[target=_blank]))")
|
||||
val list = if (nodes.isNotEmpty()) {
|
||||
nodes.map {
|
||||
SAnime.create().apply {
|
||||
|
@ -216,11 +238,12 @@ class Hanime1 : AnimeHttpSource(), ConfigurableAnimeSource {
|
|||
return chain.proceed(chain.request())
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
private fun updateFilters() {
|
||||
filterUpdateState = FilterUpdateState.UPDATING
|
||||
val exceptionHandler =
|
||||
CoroutineExceptionHandler { _, _ -> filterUpdateState = FilterUpdateState.FAILED }
|
||||
CoroutineScope(Dispatchers.IO + exceptionHandler).launch {
|
||||
GlobalScope.launch(Dispatchers.IO + exceptionHandler) {
|
||||
val jsoup = client.newCall(GET("$baseUrl/search")).awaitSuccess().asJsoup()
|
||||
val genreList = jsoup.select("div.genre-option div.hentai-sort-options").eachText()
|
||||
val sortList =
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
ext {
|
||||
extName = 'Xfani'
|
||||
extClass = '.Xfani'
|
||||
extVersionCode = 5
|
||||
extVersionCode = 6
|
||||
}
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
||||
|
|
|
@ -20,8 +20,9 @@ import eu.kanade.tachiyomi.network.POST
|
|||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
|
@ -53,7 +54,7 @@ enum class FilterUpdateState {
|
|||
|
||||
class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
|
||||
override val baseUrl: String
|
||||
get() = "https://dick.xfani.com"
|
||||
get() = "https://dm.xifanacg.com"
|
||||
override val lang: String
|
||||
get() = "zh"
|
||||
override val name: String
|
||||
|
@ -117,10 +118,16 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
|
|||
}
|
||||
|
||||
override fun animeDetailsParse(response: Response): SAnime {
|
||||
val jsoup = response.asJsoup()
|
||||
val doc = response.asJsoup()
|
||||
return SAnime.create().apply {
|
||||
description = jsoup.select("#height_limit.text").text()
|
||||
title = jsoup.select(".slide-info-title").text()
|
||||
description = doc.select("#height_limit.text").text()
|
||||
title = doc.select(".slide-info-title").text()
|
||||
author = doc.select(".slide-info:contains(导演 :)").text().removePrefix("导演 :")
|
||||
.removeSuffix(",")
|
||||
artist = doc.select(".slide-info:contains(演员 :)").text().removePrefix("演员 :")
|
||||
.removeSuffix(",")
|
||||
genre = doc.select(".slide-info:contains(类型 :)").text().removePrefix("类型 :")
|
||||
.removeSuffix(",").replace(",", ", ")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,19 +241,13 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
|
|||
return vodListToAnimePageList(response)
|
||||
}
|
||||
val jsoup = response.asJsoup()
|
||||
val items = jsoup.select("div.public-list-box.search-box.flex.rel")
|
||||
val items = jsoup.select("div.search-list")
|
||||
val animeList = items.map { item ->
|
||||
SAnime.create().apply {
|
||||
title = item.select(".thumb-txt").text()
|
||||
url = item.select("div.left.public-list-bj a.public-list-exp").attr("href")
|
||||
title = item.select("div.detail-info > a").text()
|
||||
url = item.select("div.detail-info > a").attr("href")
|
||||
thumbnail_url =
|
||||
item.select("div.left.public-list-bj img[data-src]").attr("data-src")
|
||||
author = item.select("div.thumb-actor").text().removeSuffix("/")
|
||||
artist = item.select("div.thumb-director").text().removeSuffix("/")
|
||||
description = item.select(".thumb-blurb").text()
|
||||
genre = item.select("div.thumb-else").text()
|
||||
val statusString = item.select("div.left.public-list-bj .public-list-prb").text()
|
||||
status = STATUS_STR_MAPPING.getOrElse(statusString) { SAnime.ONGOING }
|
||||
item.select("div.detail-pic img[data-src]").attr("data-src")
|
||||
}
|
||||
}
|
||||
val tip = jsoup.select("div.pages div.page-tip").text()
|
||||
|
@ -259,12 +260,13 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
|
|||
return numbers.size == 2 && numbers[0] != numbers[1]
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
private fun updateFilter() {
|
||||
filterState = FilterUpdateState.UPDATING
|
||||
val handler = CoroutineExceptionHandler { _, _ ->
|
||||
filterState = FilterUpdateState.FAILED
|
||||
}
|
||||
CoroutineScope(Dispatchers.IO + handler).launch {
|
||||
GlobalScope.launch(Dispatchers.IO + handler) {
|
||||
val jsoup = client.newCall(GET("$baseUrl/show/1/html")).awaitSuccess().asJsoup()
|
||||
// update class and year filter type
|
||||
val classList = jsoup.select("li[data-type=class]").eachAttr("data-val")
|
||||
|
@ -393,9 +395,5 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
|
|||
const val PREF_KEY_FILTER_YEAR = "PREF_KEY_FILTER_YEAR"
|
||||
|
||||
const val DEFAULT_VIDEO_SOURCE = "0"
|
||||
|
||||
val STATUS_STR_MAPPING = mapOf(
|
||||
"已完结" to SAnime.COMPLETED,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue