forked from aniyomiorg/aniyomi-extensions
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(src/zh): new extension added: xiaoxintv and Anime1 (#148)
- Loading branch information
Showing
19 changed files
with
1,010 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
plugins { | ||
id("lib-android") | ||
} | ||
|
||
dependencies { | ||
compileOnly(libs.aniyomi.lib) | ||
} |
83 changes: 83 additions & 0 deletions
83
lib/bangumi-scraper/src/main/java/eu/kanade/tachiyomi/lib/bangumiscraper/BangumiDTO.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
@file:UseSerializers(BoxItemSerializer::class) | ||
package eu.kanade.tachiyomi.lib.bangumiscraper | ||
|
||
import kotlinx.serialization.ExperimentalSerializationApi | ||
import kotlinx.serialization.KSerializer | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.Serializer | ||
import kotlinx.serialization.UseSerializers | ||
import kotlinx.serialization.encoding.Decoder | ||
import kotlinx.serialization.json.JsonDecoder | ||
import kotlinx.serialization.json.JsonPrimitive | ||
import kotlinx.serialization.json.contentOrNull | ||
import kotlinx.serialization.json.jsonObject | ||
import kotlinx.serialization.json.jsonPrimitive | ||
|
||
@Serializable | ||
internal data class Images( | ||
val large: String, | ||
val common: String, | ||
val medium: String, | ||
val small: String, | ||
) | ||
|
||
@Serializable | ||
internal data class BoxItem( | ||
val key: String, | ||
val value: String, | ||
) | ||
|
||
@OptIn(ExperimentalSerializationApi::class) | ||
@Serializer(forClass = BoxItem::class) | ||
internal object BoxItemSerializer : KSerializer<BoxItem> { | ||
override fun deserialize(decoder: Decoder): BoxItem { | ||
val item = (decoder as JsonDecoder).decodeJsonElement().jsonObject | ||
val key = item["key"]!!.jsonPrimitive.content | ||
val value = (item["value"] as? JsonPrimitive)?.contentOrNull ?: "" | ||
return BoxItem(key, value) | ||
} | ||
} | ||
|
||
@Serializable | ||
internal data class Subject( | ||
val name: String, | ||
@SerialName("name_cn") | ||
val nameCN: String, | ||
val summary: String, | ||
val images: Images, | ||
@SerialName("meta_tags") | ||
val metaTags: List<String>, | ||
@SerialName("infobox") | ||
val infoBox: List<BoxItem>, | ||
) { | ||
fun findAuthor(): String? { | ||
return findInfo("导演", "原作") | ||
} | ||
|
||
fun findArtist(): String? { | ||
return findInfo("美术监督", "总作画监督", "动画制作") | ||
} | ||
|
||
fun findInfo(vararg keys: String): String? { | ||
keys.forEach { key -> | ||
return infoBox.find { item -> | ||
item.key == key | ||
}?.value ?: return@forEach | ||
} | ||
return null | ||
} | ||
} | ||
|
||
@Serializable | ||
internal data class SearchItem( | ||
val id: Int, | ||
val name: String, | ||
@SerialName("name_cn") | ||
val nameCN: String, | ||
val summary: String, | ||
val images: Images, | ||
) | ||
|
||
@Serializable | ||
internal data class SearchResponse(val results: Int, val list: List<SearchItem>) |
126 changes: 126 additions & 0 deletions
126
lib/bangumi-scraper/src/main/java/eu/kanade/tachiyomi/lib/bangumiscraper/BangumiScraper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package eu.kanade.tachiyomi.lib.bangumiscraper | ||
|
||
import eu.kanade.tachiyomi.animesource.model.SAnime | ||
import eu.kanade.tachiyomi.network.GET | ||
import eu.kanade.tachiyomi.network.awaitSuccess | ||
import eu.kanade.tachiyomi.util.parseAs | ||
import kotlinx.serialization.json.JsonElement | ||
import kotlinx.serialization.json.contentOrNull | ||
import kotlinx.serialization.json.jsonObject | ||
import kotlinx.serialization.json.jsonPrimitive | ||
import okhttp3.HttpUrl | ||
import okhttp3.HttpUrl.Companion.toHttpUrl | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import okhttp3.Response | ||
|
||
enum class BangumiSubjectType(val value: Int) { | ||
BOOK(1), | ||
ANIME(2), | ||
MUSIC(3), | ||
GAME(4), | ||
REAL(6), | ||
} | ||
|
||
enum class BangumiFetchType { | ||
/** | ||
* Give cover and summary info. | ||
*/ | ||
SHORT, | ||
|
||
/** | ||
* Give all require info include genre and author info. | ||
*/ | ||
ALL, | ||
} | ||
|
||
/** | ||
* A helper class to fetch anime details from Bangumi | ||
*/ | ||
object BangumiScraper { | ||
private const val SEARCH_URL = "https://api.bgm.tv/search/subject" | ||
private const val SUBJECTS_URL = "https://api.bgm.tv/v0/subjects" | ||
|
||
/** | ||
* Fetch anime details info from Bangumi | ||
* @param fetchType check [BangumiFetchType] to get detail | ||
* @param subjectType check [BangumiSubjectType] to get detail | ||
* @param requestProducer used to custom request | ||
*/ | ||
suspend fun fetchDetail( | ||
client: OkHttpClient, | ||
keyword: String, | ||
fetchType: BangumiFetchType = BangumiFetchType.SHORT, | ||
subjectType: BangumiSubjectType = BangumiSubjectType.ANIME, | ||
requestProducer: (url: HttpUrl) -> Request = { url -> GET(url) }, | ||
): SAnime { | ||
val httpUrl = SEARCH_URL.toHttpUrl().newBuilder() | ||
.addPathSegment(keyword) | ||
.addQueryParameter( | ||
"responseGroup", | ||
if (fetchType == BangumiFetchType.ALL) { | ||
"small" | ||
} else { | ||
"medium" | ||
}, | ||
) | ||
.addQueryParameter("type", "${subjectType.value}") | ||
.addQueryParameter("start", "0") | ||
.addQueryParameter("max_results", "1") | ||
.build() | ||
val searchResponse = client.newCall(requestProducer(httpUrl)).awaitSuccess() | ||
.checkErrorMessage().parseAs<SearchResponse>() | ||
return if (searchResponse.list.isEmpty()) { | ||
SAnime.create() | ||
} else { | ||
val item = searchResponse.list[0] | ||
if (fetchType == BangumiFetchType.ALL) { | ||
fetchSubject(client, "${item.id}", requestProducer) | ||
} else { | ||
SAnime.create().apply { | ||
thumbnail_url = item.images.large | ||
description = item.summary | ||
} | ||
} | ||
} | ||
} | ||
|
||
private suspend fun fetchSubject( | ||
client: OkHttpClient, | ||
id: String, | ||
requestProducer: (url: HttpUrl) -> Request, | ||
): SAnime { | ||
val httpUrl = SUBJECTS_URL.toHttpUrl().newBuilder().addPathSegment(id).build() | ||
val subject = client.newCall(requestProducer(httpUrl)).awaitSuccess() | ||
.checkErrorMessage().parseAs<Subject>() | ||
return SAnime.create().apply { | ||
thumbnail_url = subject.images.large | ||
description = subject.summary | ||
genre = buildList { | ||
addAll(subject.metaTags) | ||
subject.findInfo("动画制作")?.let { add(it) } | ||
subject.findInfo("放送开始")?.let { add(it) } | ||
}.joinToString() | ||
author = subject.findAuthor() | ||
artist = subject.findArtist() | ||
if (subject.findInfo("播放结束") != null) { | ||
status = SAnime.COMPLETED | ||
} else if (subject.findInfo("放送开始") != null) { | ||
status = SAnime.ONGOING | ||
} | ||
} | ||
} | ||
|
||
private fun Response.checkErrorMessage(): String { | ||
val responseStr = body.string() | ||
val errorMessage = | ||
responseStr.parseAs<JsonElement>().jsonObject["error"]?.jsonPrimitive?.contentOrNull | ||
if (errorMessage != null) { | ||
throw BangumiScraperException(errorMessage) | ||
} | ||
return responseStr | ||
} | ||
} | ||
|
||
|
||
|
3 changes: 3 additions & 0 deletions
3
...i-scraper/src/main/java/eu/kanade/tachiyomi/lib/bangumiscraper/BangumiScraperException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package eu.kanade.tachiyomi.lib.bangumiscraper | ||
|
||
class BangumiScraperException(message: String) : Exception(message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
ext { | ||
extName = 'Anime1.me' | ||
extClass = '.Anime1' | ||
extVersionCode = 3 | ||
} | ||
|
||
apply from: "$rootDir/common.gradle" | ||
|
||
dependencies { | ||
implementation(project(":lib:bangumi-scraper")) | ||
//noinspection UseTomlInstead | ||
implementation "com.github.houbb:opencc4j:1.8.1" | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.