Anchira - Add tag grouping, allow to get the source URL without the keys (#306)
This commit is contained in:
parent
d61cbfc0c1
commit
c311614a2e
|
@ -2,7 +2,7 @@ ext {
|
||||||
extName = 'Anchira'
|
extName = 'Anchira'
|
||||||
pkgNameSuffix = 'en.anchira'
|
pkgNameSuffix = 'en.anchira'
|
||||||
extClass = '.Anchira'
|
extClass = '.Anchira'
|
||||||
extVersionCode = 4
|
extVersionCode = 5
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,9 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
override fun latestUpdatesRequest(page: Int) = GET("$libraryUrl?page=$page", headers)
|
override fun latestUpdatesRequest(page: Int) = GET("$libraryUrl?page=$page", headers)
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||||
|
// Ugly but it works
|
||||||
|
anchiraData.isNotEmpty()
|
||||||
|
|
||||||
val data = json.decodeFromString<LibraryResponse>(response.body.string())
|
val data = json.decodeFromString<LibraryResponse>(response.body.string())
|
||||||
|
|
||||||
return MangasPage(
|
return MangasPage(
|
||||||
|
@ -75,7 +78,7 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
thumbnail_url = "$cdnUrl/${it.id}/${it.key}/m/${it.thumbnailIndex + 1}"
|
thumbnail_url = "$cdnUrl/${it.id}/${it.key}/m/${it.thumbnailIndex + 1}"
|
||||||
artist = it.tags.filter { it.namespace == 1 }.joinToString(", ") { it.name }
|
artist = it.tags.filter { it.namespace == 1 }.joinToString(", ") { it.name }
|
||||||
author = it.tags.filter { it.namespace == 2 }.joinToString(", ") { it.name }
|
author = it.tags.filter { it.namespace == 2 }.joinToString(", ") { it.name }
|
||||||
genre = prepareTags(it.tags)
|
genre = prepareTags(it.tags, preferences.useTagGrouping)
|
||||||
update_strategy = UpdateStrategy.ONLY_FETCH_ONCE
|
update_strategy = UpdateStrategy.ONLY_FETCH_ONCE
|
||||||
status = SManga.COMPLETED
|
status = SManga.COMPLETED
|
||||||
}
|
}
|
||||||
|
@ -165,7 +168,7 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
"$cdnUrl/${data.id}/${data.key}/b/${data.thumbnailIndex + 1}"
|
"$cdnUrl/${data.id}/${data.key}/b/${data.thumbnailIndex + 1}"
|
||||||
artist = data.tags.filter { it.namespace == 1 }.joinToString(", ") { it.name }
|
artist = data.tags.filter { it.namespace == 1 }.joinToString(", ") { it.name }
|
||||||
author = data.tags.filter { it.namespace == 2 }.joinToString(", ") { it.name }
|
author = data.tags.filter { it.namespace == 2 }.joinToString(", ") { it.name }
|
||||||
genre = prepareTags(data.tags)
|
genre = prepareTags(data.tags, preferences.useTagGrouping)
|
||||||
update_strategy = UpdateStrategy.ONLY_FETCH_ONCE
|
update_strategy = UpdateStrategy.ONLY_FETCH_ONCE
|
||||||
status = SManga.COMPLETED
|
status = SManga.COMPLETED
|
||||||
}
|
}
|
||||||
|
@ -173,7 +176,7 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
|
|
||||||
override fun getMangaUrl(manga: SManga) = if (preferences.openSource) {
|
override fun getMangaUrl(manga: SManga) = if (preferences.openSource) {
|
||||||
val id = manga.url.split("/").reversed()[1].toInt()
|
val id = manga.url.split("/").reversed()[1].toInt()
|
||||||
anchiraData.galleries.find { it.id == id }?.url ?: "$baseUrl${manga.url}"
|
anchiraData.find { it.id == id }?.url ?: "$baseUrl${manga.url}"
|
||||||
} else {
|
} else {
|
||||||
"$baseUrl${manga.url}"
|
"$baseUrl${manga.url}"
|
||||||
}
|
}
|
||||||
|
@ -216,16 +219,15 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getImageData(entry: Entry): ImageData {
|
private fun getImageData(entry: Entry): ImageData {
|
||||||
val keys = anchiraData.galleries.find { it.id == entry.id }
|
val keys = anchiraData.find { it.id == entry.id }
|
||||||
|
|
||||||
if (keys != null) {
|
if (keys?.key != null && keys.hash != null) {
|
||||||
return ImageData(keys.id, keys.key, keys.hash, keys.names)
|
return ImageData(keys.id, keys.key, keys.hash, keys.names)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val response =
|
val response =
|
||||||
client.newCall(GET("$libraryUrl/${entry.id}/${entry.key}/data", headers)).execute()
|
client.newCall(GET("$libraryUrl/${entry.id}/${entry.key}/data", headers)).execute()
|
||||||
val body = response.body
|
|
||||||
|
|
||||||
return json.decodeFromString(response.body.string())
|
return json.decodeFromString(response.body.string())
|
||||||
} catch (_: IOException) {
|
} catch (_: IOException) {
|
||||||
|
@ -255,14 +257,21 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
|
|
||||||
val openSourcePref = SwitchPreferenceCompat(screen.context).apply {
|
val openSourcePref = SwitchPreferenceCompat(screen.context).apply {
|
||||||
key = OPEN_SOURCE_PREF
|
key = OPEN_SOURCE_PREF
|
||||||
title = "Open in FAKKU in WebView"
|
title = "Open source website in WebView"
|
||||||
summary =
|
summary = "Enable to open the original source website of the gallery (if available) instead of Anchira."
|
||||||
"Enable to open the search the book in FAKKU when opening the manga or chapter in WebView. If only one result exists, it will open that one."
|
setDefaultValue(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
val useTagGrouping = SwitchPreferenceCompat(screen.context).apply {
|
||||||
|
key = USE_TAG_GROUPING
|
||||||
|
title = "Group tags"
|
||||||
|
summary = "Enable to group tags together by artist, circle, parody, magazine and general tags"
|
||||||
setDefaultValue(false)
|
setDefaultValue(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.addPreference(imageQualityPref)
|
screen.addPreference(imageQualityPref)
|
||||||
screen.addPreference(openSourcePref)
|
screen.addPreference(openSourcePref)
|
||||||
|
screen.addPreference(useTagGrouping)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
override fun getFilterList() = FilterList(
|
||||||
|
@ -294,6 +303,9 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
private val SharedPreferences.openSource
|
private val SharedPreferences.openSource
|
||||||
get() = getBoolean(OPEN_SOURCE_PREF, false)
|
get() = getBoolean(OPEN_SOURCE_PREF, false)
|
||||||
|
|
||||||
|
private val SharedPreferences.useTagGrouping
|
||||||
|
get() = getBoolean(USE_TAG_GROUPING, false)
|
||||||
|
|
||||||
private fun apiInterceptor(chain: Interceptor.Chain): Response {
|
private fun apiInterceptor(chain: Interceptor.Chain): Response {
|
||||||
val request = chain.request()
|
val request = chain.request()
|
||||||
val requestUrl = request.url.toString()
|
val requestUrl = request.url.toString()
|
||||||
|
@ -327,13 +339,14 @@ class Anchira : HttpSource(), ConfigurableSource {
|
||||||
|
|
||||||
private val anchiraData by lazy {
|
private val anchiraData by lazy {
|
||||||
client.newCall(GET(DATA_JSON, headers)).execute()
|
client.newCall(GET(DATA_JSON, headers)).execute()
|
||||||
.use { json.decodeFromStream<AnchiraData>(it.body.byteStream()) }
|
.use { json.decodeFromStream<List<EntryKey>>(it.body.byteStream()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val IMAGE_QUALITY_PREF = "image_quality"
|
private const val IMAGE_QUALITY_PREF = "image_quality"
|
||||||
private const val OPEN_SOURCE_PREF = "use_manga_source"
|
private const val OPEN_SOURCE_PREF = "use_manga_source"
|
||||||
|
private const val USE_TAG_GROUPING = "use_tag_grouping"
|
||||||
private const val DATA_JSON =
|
private const val DATA_JSON =
|
||||||
"https://gist.githubusercontent.com/LetrixZ/2b559cc5829d1c221c701e02ecd81411/raw/site_data.json"
|
"https://gist.githubusercontent.com/LetrixZ/2b559cc5829d1c221c701e02ecd81411/raw/data-v5.json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,14 +48,8 @@ data class ImageData(
|
||||||
@Serializable
|
@Serializable
|
||||||
data class EntryKey(
|
data class EntryKey(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
val key: String,
|
val key: String? = null,
|
||||||
val hash: String,
|
val hash: String? = null,
|
||||||
val url: String?,
|
val url: String? = null,
|
||||||
val names: List<String> = emptyList(),
|
val names: List<String> = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class AnchiraData(
|
|
||||||
val key: String,
|
|
||||||
val galleries: List<EntryKey>,
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,34 +1,28 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.anchira
|
package eu.kanade.tachiyomi.extension.en.anchira
|
||||||
|
|
||||||
import android.util.Base64
|
|
||||||
import kotlinx.serialization.decodeFromString
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import okhttp3.ResponseBody
|
|
||||||
import okio.ByteString.Companion.decodeBase64
|
|
||||||
|
|
||||||
object AnchiraHelper {
|
object AnchiraHelper {
|
||||||
const val KEY = "ZnVja19uaWdnZXJzX2FuZF9mYWdnb3RzLF9hbmRfZGVhdGhfdG9fYWxsX2pld3M="
|
|
||||||
|
|
||||||
val json = Json { ignoreUnknownKeys = true }
|
|
||||||
|
|
||||||
fun getPathFromUrl(url: String) = "${url.split("/").reversed()[1]}/${url.split("/").last()}"
|
fun getPathFromUrl(url: String) = "${url.split("/").reversed()[1]}/${url.split("/").last()}"
|
||||||
|
|
||||||
inline fun <reified T> decodeBytes(body: ResponseBody, key: String = KEY): T {
|
fun prepareTags(tags: List<Tag>, group: Boolean) = tags.map {
|
||||||
val encryptedText = body.string().decodeBase64()!!
|
|
||||||
return json.decodeFromString(
|
|
||||||
XXTEA.decryptToString(
|
|
||||||
encryptedText.toByteArray(),
|
|
||||||
key = Base64.decode(key, Base64.DEFAULT).decodeToString(),
|
|
||||||
)!!,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun prepareTags(tags: List<Tag>) = tags.map {
|
|
||||||
if (it.namespace == null) {
|
if (it.namespace == null) {
|
||||||
it.namespace = 6
|
it.namespace = 6
|
||||||
}
|
}
|
||||||
it
|
it
|
||||||
}.sortedBy { it.namespace }.map {
|
}
|
||||||
return@map it.name.lowercase()
|
.sortedBy { it.namespace }
|
||||||
}.joinToString(", ") { it }
|
.map {
|
||||||
|
val tag = it.name.lowercase()
|
||||||
|
return@map if (group) {
|
||||||
|
when (it.namespace) {
|
||||||
|
1 -> "artist:$tag"
|
||||||
|
2 -> "circle:$tag"
|
||||||
|
3 -> "parody:$tag"
|
||||||
|
4 -> "magazine:$tag"
|
||||||
|
else -> "tag:$tag"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.joinToString(", ") { it }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue