Migrating 3 sources to kotlinx.serialization (#8463)
* HentaiHand: Migration to kotlinx.serialization * SimplyHentai: Migration to kotlinx.serialization * Kangaryu: Migration to kotlinx.serialization
This commit is contained in:
parent
5a0d513b94
commit
6470dd5245
|
@ -1,11 +1,12 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlinx-serialization'
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
extName = 'HentaiHand'
|
extName = 'HentaiHand'
|
||||||
pkgNameSuffix = 'all.hentaihand'
|
pkgNameSuffix = 'all.hentaihand'
|
||||||
extClass = '.HentaiHandFactory'
|
extClass = '.HentaiHandFactory'
|
||||||
extVersionCode = 3
|
extVersionCode = 4
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
containsNsfw = true
|
containsNsfw = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
package eu.kanade.tachiyomi.extension.all.hentaihand
|
package eu.kanade.tachiyomi.extension.all.hentaihand
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.nullObj
|
|
||||||
import com.github.salomonbrys.kotson.nullString
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.annotations.Nsfw
|
import eu.kanade.tachiyomi.annotations.Nsfw
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
|
@ -24,20 +16,28 @@ import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
|
import kotlinx.serialization.json.int
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
import kotlinx.serialization.json.put
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.json.JSONException
|
|
||||||
import org.json.JSONObject
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.schedulers.Schedulers
|
import rx.schedulers.Schedulers
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
@Nsfw
|
@Nsfw
|
||||||
abstract class HentaiHand(
|
abstract class HentaiHand(
|
||||||
|
@ -50,29 +50,37 @@ abstract class HentaiHand(
|
||||||
override val name: String = "HentaiHand$extraName"
|
override val name: String = "HentaiHand$extraName"
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
private val gson = Gson()
|
|
||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
||||||
.addInterceptor { authIntercept(it) }
|
.addInterceptor { authIntercept(it) }
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private fun parseGenericResponse(response: Response): MangasPage {
|
private val json: Json by injectLazy()
|
||||||
val data = gson.fromJson<JsonObject>(response.body!!.string())
|
|
||||||
return MangasPage(
|
private fun slugToUrl(json: JsonObject) = json["slug"]!!.jsonPrimitive.content.prependIndent("/en/comic/")
|
||||||
data.getAsJsonArray("data").map {
|
|
||||||
SManga.create().apply {
|
private fun jsonArrayToString(arrayKey: String, obj: JsonObject): String? {
|
||||||
url = "/en/comic/${it["slug"].asString}"
|
val array = obj[arrayKey]!!.jsonArray
|
||||||
title = it["title"].asString
|
if (array.isEmpty()) return null
|
||||||
thumbnail_url = it["thumb_url"].asString
|
return array.joinToString(", ") {
|
||||||
}
|
it.jsonObject["name"]!!.jsonPrimitive.content
|
||||||
},
|
}
|
||||||
!data["next_page_url"].isJsonNull
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Popular
|
// Popular
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage = parseGenericResponse(response)
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
|
val jsonResponse = json.parseToJsonElement(response.body!!.string())
|
||||||
|
val mangaList = jsonResponse.jsonObject["data"]!!.jsonArray.map {
|
||||||
|
val obj = it.jsonObject
|
||||||
|
SManga.create().apply {
|
||||||
|
url = slugToUrl(obj)
|
||||||
|
title = obj["title"]!!.jsonPrimitive.content
|
||||||
|
thumbnail_url = obj["thumb_url"]!!.jsonPrimitive.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val hasNextPage = jsonResponse.jsonObject["next_page_url"]!!.jsonPrimitive.content.isNotEmpty()
|
||||||
|
return MangasPage(mangaList, hasNextPage)
|
||||||
|
}
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
val url = "$baseUrl/api/comics?page=$page&sort=popularity&order=desc&duration=all"
|
val url = "$baseUrl/api/comics?page=$page&sort=popularity&order=desc&duration=all"
|
||||||
|
@ -81,7 +89,7 @@ abstract class HentaiHand(
|
||||||
|
|
||||||
// Latest
|
// Latest
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage = parseGenericResponse(response)
|
override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response)
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
val url = "$baseUrl/api/comics?page=$page&sort=uploaded_at&order=desc&duration=week"
|
val url = "$baseUrl/api/comics?page=$page&sort=uploaded_at&order=desc&duration=week"
|
||||||
|
@ -90,17 +98,20 @@ abstract class HentaiHand(
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage = parseGenericResponse(response)
|
override fun searchMangaParse(response: Response): MangasPage = popularMangaParse(response)
|
||||||
|
|
||||||
private fun lookupFilterId(query: String, uri: String): Int? {
|
private fun lookupFilterId(query: String, uri: String): Int? {
|
||||||
// filter query needs to be resolved to an ID
|
// filter query needs to be resolved to an ID
|
||||||
return client.newCall(GET("$baseUrl/api/$uri?q=$query"))
|
return client.newCall(GET("$baseUrl/api/$uri?q=$query"))
|
||||||
.asObservableSuccess()
|
.asObservableSuccess()
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.map {
|
.map { response ->
|
||||||
val data = gson.fromJson<JsonObject>(it.body!!.string())
|
// Returns the first matched id, or null if there are no results
|
||||||
// only the first tag will be used
|
val idList = json.parseToJsonElement(response.body!!.string()).jsonObject["data"]!!.jsonArray.map {
|
||||||
data.getAsJsonArray("data").firstOrNull()?.let { t -> t["id"].asInt }
|
it.jsonObject["id"]!!.jsonPrimitive.content
|
||||||
|
}
|
||||||
|
if (idList.isEmpty()) return@map null
|
||||||
|
else idList.first().toInt()
|
||||||
}.toBlocking().first()
|
}.toBlocking().first()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,12 +149,6 @@ abstract class HentaiHand(
|
||||||
|
|
||||||
// Details
|
// Details
|
||||||
|
|
||||||
private fun tagArrayToString(array: JsonArray, key: String = "name"): String? {
|
|
||||||
if (array.size() == 0)
|
|
||||||
return null
|
|
||||||
return array.joinToString { it[key].asString }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mangaDetailsApiRequest(manga: SManga): Request {
|
private fun mangaDetailsApiRequest(manga: SManga): Request {
|
||||||
val slug = manga.url.removePrefix("/en/comic/")
|
val slug = manga.url.removePrefix("/en/comic/")
|
||||||
return GET("$baseUrl/api/comics/$slug")
|
return GET("$baseUrl/api/comics/$slug")
|
||||||
|
@ -156,28 +161,26 @@ abstract class HentaiHand(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val data = gson.fromJson<JsonObject>(response.body!!.string())
|
val obj = json.parseToJsonElement(response.body!!.string()).jsonObject
|
||||||
return SManga.create().apply {
|
return SManga.create().apply {
|
||||||
|
url = slugToUrl(obj)
|
||||||
artist = tagArrayToString(data.getAsJsonArray("artists"))
|
title = obj["title"]!!.jsonPrimitive.content
|
||||||
author = tagArrayToString(data.getAsJsonArray("authors")) ?: artist
|
thumbnail_url = obj["thumb_url"]!!.jsonPrimitive.content
|
||||||
|
artist = jsonArrayToString("artists", obj)
|
||||||
genre = listOf("tags", "relationships").map {
|
author = jsonArrayToString("authors", obj) ?: artist
|
||||||
data.getAsJsonArray(it).map { t -> t["name"].asString }
|
genre = listOfNotNull(jsonArrayToString("tags", obj), jsonArrayToString("relationships", obj)).joinToString(", ")
|
||||||
}.flatten().distinct().joinToString()
|
|
||||||
|
|
||||||
status = SManga.COMPLETED
|
status = SManga.COMPLETED
|
||||||
|
|
||||||
description = listOf(
|
description = listOf(
|
||||||
Pair("Alternative Title", data["alternative_title"].nullString),
|
Pair("Alternative Title", obj["alternative_title"]!!.jsonPrimitive.content),
|
||||||
Pair("Groups", tagArrayToString(data.getAsJsonArray("groups"))),
|
Pair("Groups", jsonArrayToString("groups", obj)),
|
||||||
Pair("Description", data["description"].nullString),
|
Pair("Description", obj["description"]!!.jsonPrimitive.content),
|
||||||
Pair("Pages", data["pages"].asInt.toString()),
|
Pair("Pages", obj["pages"]!!.jsonPrimitive.content),
|
||||||
Pair("Category", data["category"].nullObj?.get("name")?.asString),
|
Pair("Category", obj["category"]!!.jsonObject["name"]!!.jsonPrimitive.content),
|
||||||
Pair("Language", data["language"].nullObj?.get("name")?.asString),
|
Pair("Language", obj["language"]!!.jsonObject["name"]!!.jsonPrimitive.content),
|
||||||
Pair("Parodies", tagArrayToString(data.getAsJsonArray("parodies"))),
|
Pair("Parodies", jsonArrayToString("parodies", obj)),
|
||||||
Pair("Characters", tagArrayToString(data.getAsJsonArray("characters")))
|
Pair("Characters", jsonArrayToString("characters", obj))
|
||||||
).filter { !it.second.isNullOrEmpty() }.joinToString("\n\n") { "${it.first}:\n${it.second}" }
|
).filter { !it.second.isNullOrEmpty() }.joinToString("\n\n") { "${it.first}: ${it.second}" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,12 +189,12 @@ abstract class HentaiHand(
|
||||||
override fun chapterListRequest(manga: SManga): Request = mangaDetailsApiRequest(manga)
|
override fun chapterListRequest(manga: SManga): Request = mangaDetailsApiRequest(manga)
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
val data = gson.fromJson<JsonObject>(response.body!!.string())
|
val obj = json.parseToJsonElement(response.body!!.string()).jsonObject
|
||||||
return listOf(
|
return listOf(
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
url = "/en/comic/${data["slug"].asString}/reader/1"
|
url = "/en/comic/${obj["slug"]!!.jsonPrimitive.content}/reader/1"
|
||||||
name = "Chapter"
|
name = "Chapter"
|
||||||
date_upload = DATE_FORMAT.parse(data["uploaded_at"].asString)?.time ?: 0
|
date_upload = DATE_FORMAT.parse(obj["uploaded_at"]!!.jsonPrimitive.content)?.time ?: 0
|
||||||
chapter_number = 1f
|
chapter_number = 1f
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -204,12 +207,13 @@ abstract class HentaiHand(
|
||||||
return GET("$baseUrl/api/comics/$slug/images")
|
return GET("$baseUrl/api/comics/$slug/images")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> =
|
||||||
val data = gson.fromJson<JsonObject>(response.body!!.string())
|
json.parseToJsonElement(response.body!!.string()).jsonObject["images"]!!.jsonArray.map {
|
||||||
return data.getAsJsonArray("images").mapIndexed { i, it ->
|
val imgObj = it.jsonObject
|
||||||
Page(i, "/en/comic/${data["comic"]["slug"].asString}/reader/${it["page"].asInt}", it["source_url"].asString)
|
val index = imgObj["page"]!!.jsonPrimitive.int
|
||||||
|
val imgUrl = imgObj["source_url"]!!.jsonPrimitive.content
|
||||||
|
Page(index, "", imgUrl)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
|
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
|
@ -231,12 +235,12 @@ abstract class HentaiHand(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun login(chain: Interceptor.Chain, username: String, password: String): String {
|
private fun login(chain: Interceptor.Chain, username: String, password: String): String {
|
||||||
val jsonObject = JSONObject().apply {
|
val jsonObject = buildJsonObject {
|
||||||
this.put("username", username)
|
put("username", username)
|
||||||
this.put("password", password)
|
put("password", password)
|
||||||
this.put("remember_me", true)
|
put("remember_me", true)
|
||||||
}
|
}
|
||||||
val body = RequestBody.create(MEDIA_TYPE, jsonObject.toString())
|
val body = jsonObject.toString().toRequestBody(MEDIA_TYPE)
|
||||||
val response = chain.proceed(POST("$baseUrl/api/login", headers, body))
|
val response = chain.proceed(POST("$baseUrl/api/login", headers, body))
|
||||||
if (response.code == 401) {
|
if (response.code == 401) {
|
||||||
throw Exception("Failed to login, check if username and password are correct")
|
throw Exception("Failed to login, check if username and password are correct")
|
||||||
|
@ -245,10 +249,9 @@ abstract class HentaiHand(
|
||||||
if (response.body == null)
|
if (response.body == null)
|
||||||
throw Exception("Login response body is empty")
|
throw Exception("Login response body is empty")
|
||||||
try {
|
try {
|
||||||
return JSONObject(response.body!!.string())
|
// Returns access token as a string, unless unparseable
|
||||||
.getJSONObject("auth")
|
return json.parseToJsonElement(response.body!!.string()).jsonObject["auth"]!!.jsonObject["access-token"]!!.jsonPrimitive.content
|
||||||
.getString("access_token")
|
} catch (e: IllegalArgumentException) {
|
||||||
} catch (e: JSONException) {
|
|
||||||
throw Exception("Cannot parse login response body")
|
throw Exception("Cannot parse login response body")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,8 +360,7 @@ abstract class HentaiHand(
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@SuppressLint("SimpleDateFormat")
|
private val DATE_FORMAT = SimpleDateFormat("yyyy-dd-MM", Locale.US)
|
||||||
private val DATE_FORMAT = SimpleDateFormat("yyyy-dd-MM")
|
|
||||||
private val MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
|
private val MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
|
||||||
private const val USERNAME_TITLE = "Username"
|
private const val USERNAME_TITLE = "Username"
|
||||||
private const val USERNAME_DEFAULT = ""
|
private const val USERNAME_DEFAULT = ""
|
||||||
|
|
|
@ -50,7 +50,7 @@ class HentaiHandFactory : SourceFactory {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class HentaiHandOther : HentaiHand("other", extraName = " (Unfiltered)")
|
class HentaiHandOther : HentaiHand("all", extraName = " (Unfiltered)")
|
||||||
class HentaiHandEn : HentaiHand("en", 1)
|
class HentaiHandEn : HentaiHand("en", 1)
|
||||||
class HentaiHandZh : HentaiHand("zh", 2)
|
class HentaiHandZh : HentaiHand("zh", 2)
|
||||||
class HentaiHandJa : HentaiHand("ja", 3)
|
class HentaiHandJa : HentaiHand("ja", 3)
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlinx-serialization'
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
extName = 'Simply Hentai'
|
extName = 'Simply Hentai'
|
||||||
pkgNameSuffix = 'all.simplyhentai'
|
pkgNameSuffix = 'all.simplyhentai'
|
||||||
extClass = '.SimplyHentaiFactory'
|
extClass = '.SimplyHentaiFactory'
|
||||||
extVersionCode = 3
|
extVersionCode = 4
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
containsNsfw = true
|
containsNsfw = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.extension.all.simplyhentai
|
package eu.kanade.tachiyomi.extension.all.simplyhentai
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import com.github.salomonbrys.kotson.forEach
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.string
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
@ -15,12 +9,16 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
|
||||||
abstract class SimplyHentai(
|
abstract class SimplyHentai(
|
||||||
|
@ -36,7 +34,7 @@ abstract class SimplyHentai(
|
||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient
|
override val client: OkHttpClient = network.cloudflareClient
|
||||||
|
|
||||||
private val gson = Gson()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
// Popular
|
// Popular
|
||||||
|
|
||||||
|
@ -158,8 +156,13 @@ abstract class SimplyHentai(
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val pages = mutableListOf<Page>()
|
val pages = mutableListOf<Page>()
|
||||||
|
|
||||||
gson.fromJson<JsonObject>(response.body!!.string()).forEach { _, jsonElement ->
|
json.parseToJsonElement(response.body!!.string()).jsonObject.forEach {
|
||||||
pages.add(Page(pages.size, "", jsonElement["sizes"]["full"].string))
|
pages.add(
|
||||||
|
Page(
|
||||||
|
pages.size, "",
|
||||||
|
it.value.jsonObject["sizes"]!!.jsonObject["full"]!!.jsonPrimitive.content
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages
|
return pages
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlinx-serialization'
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
extName = 'Kangaryu'
|
extName = 'Kangaryu'
|
||||||
pkgNameSuffix = 'fr.kangaryu'
|
pkgNameSuffix = 'fr.kangaryu'
|
||||||
extClass = '.Kangaryu'
|
extClass = '.Kangaryu'
|
||||||
extVersionCode = 2
|
extVersionCode = 3
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.extension.fr.kangaryu
|
package eu.kanade.tachiyomi.extension.fr.kangaryu
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.array
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.string
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
|
@ -13,11 +7,16 @@ import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
@ -87,14 +86,15 @@ class Kangaryu : ParsedHttpSource() {
|
||||||
return GET("$baseUrl/search?query=$query", headers)
|
return GET("$baseUrl/search?query=$query", headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val gson by lazy { Gson() }
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
val mangas = gson.fromJson<JsonObject>(response.body!!.string())["suggestions"].array.map { json ->
|
val mangas = json.parseToJsonElement(response.body!!.string()).jsonObject["suggestions"]!!.jsonArray.map {
|
||||||
|
val data = it.jsonObject["data"]!!.jsonPrimitive.content
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
url = "/manga/${json["data"].string}"
|
url = "/manga/$data"
|
||||||
title = json["value"].string
|
title = it.jsonObject["value"]!!.jsonPrimitive.content
|
||||||
thumbnail_url = "https://kangaryu-team.fr/uploads/manga/${json["data"].string}/cover/cover_250x350.jpg"
|
thumbnail_url = "https://kangaryu-team.fr/uploads/manga/$data/cover/cover_250x350.jpg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MangasPage(mangas, false)
|
return MangasPage(mangas, false)
|
||||||
|
|
Loading…
Reference in New Issue