Replace usages of Gson (#10080)
This commit is contained in:
parent
1f6027dd67
commit
fa6be0f1c9
|
@ -123,25 +123,26 @@ dependencies {
|
||||||
|
|
||||||
#### Additional dependencies
|
#### Additional dependencies
|
||||||
|
|
||||||
You may find yourself needing additional functionality and wanting to add more dependencies to your `build.gradle` file. Since extensions are run within the main Tachiyomi app, you can make use of [its dependencies](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle).
|
You may find yourself needing additional functionality and wanting to add more dependencies to your `build.gradle` file. Since extensions are run within the main Tachiyomi app, you can make use of [its dependencies](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts).
|
||||||
|
|
||||||
For example, an extension that needs Gson could add the following:
|
For example, an extension that needs coroutines, it could add the following:
|
||||||
|
|
||||||
```gradle
|
```gradle
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'com.google.code.gson:gson:2.8.2'
|
compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
|
||||||
|
compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
(Note that Gson, and several other dependencies, are already exposed to all extensions via `common.gradle`.)
|
(Note that several dependencies are already exposed to all extensions via `common-dependencies.gradle`.)
|
||||||
|
|
||||||
Notice that we're using `compileOnly` instead of `implementation`, since the app already contains it. You could use `implementation` instead for a new dependency, or you prefer not to rely on whatever the main app has at the expense of app size.
|
Notice that we're using `compileOnly` instead of `implementation`, since the app already contains it. You could use `implementation` instead for a new dependency, or you prefer not to rely on whatever the main app has at the expense of app size.
|
||||||
|
|
||||||
Note that using `compileOnly` restricts you to versions that must be compatible with those used in [Tachiyomi v0.8.5+](https://github.com/tachiyomiorg/tachiyomi/blob/82141cec6e612885fef4fa70092e29e99d60adbb/app/build.gradle#L104) for proper backwards compatibility.
|
Note that using `compileOnly` restricts you to versions that must be compatible with those used in [Tachiyomi v0.10.12+](https://github.com/tachiyomiorg/tachiyomi/blob/v0.10.12/app/build.gradle.kts) for proper backwards compatibility.
|
||||||
|
|
||||||
### Extension main class
|
### Extension main class
|
||||||
|
|
||||||
The class which is refrenced and defined by `extClass` in `build.gradle`. This class should implement either `SourceFactory` or extend one of the `Source` implementations: `HttpSource` or `ParsedHttpSource`.
|
The class which is referenced and defined by `extClass` in `build.gradle`. This class should implement either `SourceFactory` or extend one of the `Source` implementations: `HttpSource` or `ParsedHttpSource`.
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
| ----- | ----------- |
|
| ----- | ----------- |
|
||||||
|
|
|
@ -5,13 +5,6 @@ import android.content.SharedPreferences
|
||||||
import androidx.preference.CheckBoxPreference
|
import androidx.preference.CheckBoxPreference
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import com.github.salomonbrys.kotson.addProperty
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.set
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
|
@ -22,6 +15,20 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
|
import kotlinx.serialization.json.boolean
|
||||||
|
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.long
|
||||||
|
import kotlinx.serialization.json.put
|
||||||
|
import kotlinx.serialization.json.putJsonArray
|
||||||
|
import kotlinx.serialization.json.putJsonObject
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
@ -29,6 +36,7 @@ import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
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.util.Calendar
|
import java.util.Calendar
|
||||||
|
|
||||||
abstract class Luscious(
|
abstract class Luscious(
|
||||||
|
@ -44,7 +52,7 @@ abstract class Luscious(
|
||||||
|
|
||||||
private val apiBaseUrl: String = "$baseUrl/graphql/nobatch/"
|
private val apiBaseUrl: String = "$baseUrl/graphql/nobatch/"
|
||||||
|
|
||||||
private val gson = Gson()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient
|
override val client: OkHttpClient = network.cloudflareClient
|
||||||
|
|
||||||
|
@ -86,90 +94,91 @@ abstract class Luscious(
|
||||||
val contentTypeFilter = filters.findInstance<ContentTypeSelectFilter>()!!
|
val contentTypeFilter = filters.findInstance<ContentTypeSelectFilter>()!!
|
||||||
val albumSizeFilter = filters.findInstance<AlbumSizeSelectFilter>()!!
|
val albumSizeFilter = filters.findInstance<AlbumSizeSelectFilter>()!!
|
||||||
val restrictGenresFilter = filters.findInstance<RestrictGenresSelectFilter>()!!
|
val restrictGenresFilter = filters.findInstance<RestrictGenresSelectFilter>()!!
|
||||||
return JsonObject().apply {
|
return buildJsonObject {
|
||||||
add(
|
putJsonObject("input") {
|
||||||
"input",
|
put("display", sortByFilter.selected)
|
||||||
JsonObject().apply {
|
put("page", page)
|
||||||
addProperty("display", sortByFilter.selected)
|
putJsonArray("filters") {
|
||||||
addProperty("page", page)
|
if (contentTypeFilter.selected != FILTER_VALUE_IGNORE)
|
||||||
add(
|
add(contentTypeFilter.toJsonObject("content_id"))
|
||||||
"filters",
|
|
||||||
JsonArray().apply {
|
|
||||||
|
|
||||||
if (contentTypeFilter.selected != FILTER_VALUE_IGNORE)
|
if (albumTypeFilter.selected != FILTER_VALUE_IGNORE)
|
||||||
add(contentTypeFilter.toJsonObject("content_id"))
|
add(albumTypeFilter.toJsonObject("album_type"))
|
||||||
|
|
||||||
if (albumTypeFilter.selected != FILTER_VALUE_IGNORE)
|
if (selectionFilter.selected != FILTER_VALUE_IGNORE)
|
||||||
add(albumTypeFilter.toJsonObject("album_type"))
|
add(selectionFilter.toJsonObject("selection"))
|
||||||
|
|
||||||
if (selectionFilter.selected != FILTER_VALUE_IGNORE)
|
if (albumSizeFilter.selected != FILTER_VALUE_IGNORE)
|
||||||
add(selectionFilter.toJsonObject("selection"))
|
add(albumSizeFilter.toJsonObject("picture_count_rank"))
|
||||||
|
|
||||||
if (albumSizeFilter.selected != FILTER_VALUE_IGNORE)
|
if (restrictGenresFilter.selected != FILTER_VALUE_IGNORE)
|
||||||
add(albumSizeFilter.toJsonObject("picture_count_rank"))
|
add(restrictGenresFilter.toJsonObject("restrict_genres"))
|
||||||
|
|
||||||
if (restrictGenresFilter.selected != FILTER_VALUE_IGNORE)
|
with(interestsFilter) {
|
||||||
add(restrictGenresFilter.toJsonObject("restrict_genres"))
|
if (this.selected.isEmpty()) {
|
||||||
|
throw Exception("Please select an Interest")
|
||||||
with(interestsFilter) {
|
|
||||||
if (this.selected.isEmpty()) {
|
|
||||||
throw Exception("Please select an Interest")
|
|
||||||
}
|
|
||||||
add(this.toJsonObject("audience_ids"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lusLang != FILTER_VALUE_IGNORE) {
|
|
||||||
add(
|
|
||||||
languagesFilter.toJsonObject("language_ids").apply {
|
|
||||||
set("value", "+$lusLang${get("value").asString}")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tagsFilter.state.isNotEmpty()) {
|
|
||||||
val tags = "+${tagsFilter.state.toLowerCase()}".replace(" ", "_").replace("_,", "+").replace(",_", "+").replace(",", "+").replace("+-", "-").replace("-_", "-").trim()
|
|
||||||
add(
|
|
||||||
JsonObject().apply {
|
|
||||||
addProperty("name", "tagged")
|
|
||||||
addProperty("value", tags)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (creatorFilter.state.isNotEmpty()) {
|
|
||||||
add(
|
|
||||||
JsonObject().apply {
|
|
||||||
addProperty("name", "created_by_id")
|
|
||||||
addProperty("value", creatorFilter.state)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (favoriteFilter.state.isNotEmpty()) {
|
|
||||||
add(
|
|
||||||
JsonObject().apply {
|
|
||||||
addProperty("name", "favorite_by_user_id")
|
|
||||||
addProperty("value", favoriteFilter.state)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (genreFilter.anyNotIgnored()) {
|
|
||||||
add(genreFilter.toJsonObject("genre_ids"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query != "") {
|
|
||||||
add(
|
|
||||||
JsonObject().apply {
|
|
||||||
addProperty("name", "search_query")
|
|
||||||
addProperty("value", query)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
add(this.toJsonObject("audience_ids"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lusLang != FILTER_VALUE_IGNORE) {
|
||||||
|
val languageIds = languagesFilter.toJsonObject("language_ids")
|
||||||
|
add(
|
||||||
|
JsonObject(
|
||||||
|
languageIds.toMutableMap().apply {
|
||||||
|
put(
|
||||||
|
"value",
|
||||||
|
JsonPrimitive ("+$lusLang${languageIds["value"]!!.jsonPrimitive.content}")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tagsFilter.state.isNotEmpty()) {
|
||||||
|
val tags = "+${tagsFilter.state.toLowerCase()}".replace(" ", "_")
|
||||||
|
.replace("_,", "+").replace(",_", "+").replace(",", "+")
|
||||||
|
.replace("+-", "-").replace("-_", "-").trim()
|
||||||
|
add(
|
||||||
|
buildJsonObject {
|
||||||
|
put("name", "tagged")
|
||||||
|
put("value", tags)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creatorFilter.state.isNotEmpty()) {
|
||||||
|
add(
|
||||||
|
buildJsonObject {
|
||||||
|
put("name", "created_by_id")
|
||||||
|
put("value", creatorFilter.state)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (favoriteFilter.state.isNotEmpty()) {
|
||||||
|
add(
|
||||||
|
buildJsonObject {
|
||||||
|
put("name", "favorite_by_user_id")
|
||||||
|
put("value", favoriteFilter.state)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genreFilter.anyNotIgnored()) {
|
||||||
|
add(genreFilter.toJsonObject("genre_ids"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query != "") {
|
||||||
|
add(
|
||||||
|
buildJsonObject {
|
||||||
|
put("name", "search_query")
|
||||||
|
put("value", query)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,24 +193,24 @@ abstract class Luscious(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseAlbumListResponse(response: Response): MangasPage {
|
private fun parseAlbumListResponse(response: Response): MangasPage {
|
||||||
val data = gson.fromJson<JsonObject>(response.body!!.string())
|
val data = json.decodeFromString<JsonObject>(response.body!!.string())
|
||||||
with(data["data"]["album"]["list"]) {
|
with(data["data"]!!.jsonObject["album"]!!.jsonObject["list"]) {
|
||||||
return MangasPage(
|
return MangasPage(
|
||||||
this["items"].asJsonArray.map {
|
this!!.jsonObject["items"]!!.jsonArray.map {
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
url = it["url"].asString
|
url = it.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
title = it["title"].asString
|
title = it.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
thumbnail_url = it["cover"]["url"].asString
|
thumbnail_url = it.jsonObject["cover"]!!.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
this["info"]["has_next_page"].asBoolean
|
this.jsonObject["info"]!!.jsonObject["has_next_page"]!!.jsonPrimitive.boolean
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildAlbumInfoRequestInput(id: String): JsonObject {
|
private fun buildAlbumInfoRequestInput(id: String): JsonObject {
|
||||||
return JsonObject().apply {
|
return buildJsonObject {
|
||||||
addProperty("id", id)
|
put("id", id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,34 +255,34 @@ abstract class Luscious(
|
||||||
var nextPage = true
|
var nextPage = true
|
||||||
var page = 2
|
var page = 2
|
||||||
val id = response.request.url.queryParameter("variables").toString()
|
val id = response.request.url.queryParameter("variables").toString()
|
||||||
.let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray }
|
.let { json.decodeFromString<JsonObject>(it)["input"]!!.jsonObject["filters"]!!.jsonArray }
|
||||||
.let { it.first { f -> f["name"].asString == "album_id" } }
|
.let { it.first { f -> f.jsonObject["name"]!!.jsonPrimitive.content == "album_id" } }
|
||||||
.let { it["value"].asString }
|
.let { it.jsonObject["value"]!!.jsonPrimitive.content }
|
||||||
|
|
||||||
var data = gson.fromJson<JsonObject>(response.body!!.string())
|
var data = json.decodeFromString<JsonObject>(response.body!!.string())
|
||||||
.let { it["data"]["picture"]["list"].asJsonObject }
|
.let { it.jsonObject["data"]!!.jsonObject["picture"]!!.jsonObject["list"]!!.jsonObject }
|
||||||
|
|
||||||
while (nextPage) {
|
while (nextPage) {
|
||||||
nextPage = data["info"]["has_next_page"].asBoolean
|
nextPage = data["info"]!!.jsonObject["has_next_page"]!!.jsonPrimitive.boolean
|
||||||
data["items"].asJsonArray.map {
|
data["items"]!!.jsonArray.map {
|
||||||
val chapter = SChapter.create()
|
val chapter = SChapter.create()
|
||||||
val url = when (getResolutionPref()) {
|
val url = when (getResolutionPref()) {
|
||||||
"-1" -> it["url_to_original"].asString
|
"-1" -> it.jsonObject["url_to_original"]!!.jsonPrimitive.content
|
||||||
else -> it["thumbnails"][getResolutionPref()?.toInt()!!]["url"].asString
|
else -> it.jsonObject["thumbnails"]!!.jsonObject[getResolutionPref()?.toInt()!!]!!.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
when {
|
when {
|
||||||
url.startsWith("//") -> chapter.url = "https:$url"
|
url.startsWith("//") -> chapter.url = "https:$url"
|
||||||
else -> chapter.url = url
|
else -> chapter.url = url
|
||||||
}
|
}
|
||||||
chapter.chapter_number = it["position"].asInt.toFloat()
|
chapter.chapter_number = it.jsonObject["position"]!!.jsonPrimitive.int.toFloat()
|
||||||
chapter.name = chapter.chapter_number.toInt().toString() + " - " + it["title"].asString
|
chapter.name = chapter.chapter_number.toInt().toString() + " - " + it.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
chapter.date_upload = "${it["created"].asLong}000".toLong()
|
chapter.date_upload = "${it.jsonObject["created"]!!.jsonPrimitive.long}000".toLong()
|
||||||
chapters.add(chapter)
|
chapters.add(chapter)
|
||||||
}
|
}
|
||||||
if (nextPage) {
|
if (nextPage) {
|
||||||
val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page))).execute()
|
val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page))).execute()
|
||||||
data = gson.fromJson<JsonObject>(newPage.body!!.string())
|
data = json.decodeFromString<JsonObject>(newPage.body!!.string())
|
||||||
.let { it["data"]["picture"]["list"].asJsonObject }
|
.let { it["data"]!!.jsonObject["picture"]!!.jsonObject["list"]!!.jsonObject }
|
||||||
}
|
}
|
||||||
page++
|
page++
|
||||||
}
|
}
|
||||||
|
@ -288,25 +297,17 @@ abstract class Luscious(
|
||||||
// Pages
|
// Pages
|
||||||
|
|
||||||
private fun buildAlbumPicturesRequestInput(id: String, page: Int): JsonObject {
|
private fun buildAlbumPicturesRequestInput(id: String, page: Int): JsonObject {
|
||||||
return JsonObject().apply {
|
return buildJsonObject {
|
||||||
addProperty(
|
putJsonObject("input") {
|
||||||
"input",
|
putJsonArray("filters") {
|
||||||
JsonObject().apply {
|
add(buildJsonObject {
|
||||||
addProperty(
|
put("name", "album_id")
|
||||||
"filters",
|
put("value", id)
|
||||||
JsonArray().apply {
|
})
|
||||||
add(
|
|
||||||
JsonObject().apply {
|
|
||||||
addProperty("name", "album_id")
|
|
||||||
addProperty("value", id)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
addProperty("display", getSortPref())
|
|
||||||
addProperty("page", page)
|
|
||||||
}
|
}
|
||||||
)
|
put("display", getSortPref())
|
||||||
|
put("page", page)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,20 +325,20 @@ abstract class Luscious(
|
||||||
var nextPage = true
|
var nextPage = true
|
||||||
var page = 2
|
var page = 2
|
||||||
val id = response.request.url.queryParameter("variables").toString()
|
val id = response.request.url.queryParameter("variables").toString()
|
||||||
.let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray }
|
.let { json.decodeFromString<JsonObject>(it)["input"]!!.jsonObject["filters"]!!.jsonArray }
|
||||||
.let { it.first { f -> f["name"].asString == "album_id" } }
|
.let { it.first { f -> f.jsonObject["name"]!!.jsonPrimitive.content == "album_id" } }
|
||||||
.let { it["value"].asString }
|
.let { it.jsonObject["value"]!!.jsonPrimitive.content }
|
||||||
|
|
||||||
var data = gson.fromJson<JsonObject>(response.body!!.string())
|
var data = json.decodeFromString<JsonObject>(response.body!!.string())
|
||||||
.let { it["data"]["picture"]["list"].asJsonObject }
|
.let { it["data"]!!.jsonObject["picture"]!!.jsonObject["list"]!!.jsonObject }
|
||||||
|
|
||||||
while (nextPage) {
|
while (nextPage) {
|
||||||
nextPage = data["info"]["has_next_page"].asBoolean
|
nextPage = data["info"]!!.jsonObject["has_next_page"]!!.jsonPrimitive.boolean
|
||||||
data["items"].asJsonArray.map {
|
data["items"]!!.jsonArray.map {
|
||||||
val index = it["position"].asInt
|
val index = it.jsonObject["position"]!!.jsonPrimitive.int
|
||||||
val url = when (getResolutionPref()) {
|
val url = when (getResolutionPref()) {
|
||||||
"-1" -> it["url_to_original"].asString
|
"-1" -> it.jsonObject["url_to_original"]!!.jsonPrimitive.content
|
||||||
else -> it["thumbnails"][getResolutionPref()?.toInt()!!]["url"].asString
|
else -> it.jsonObject["thumbnails"]!!.jsonObject[getResolutionPref()?.toInt()!!]!!.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
when {
|
when {
|
||||||
url.startsWith("//") -> pages.add(Page(index, "https:$url", "https:$url"))
|
url.startsWith("//") -> pages.add(Page(index, "https:$url", "https:$url"))
|
||||||
|
@ -346,8 +347,8 @@ abstract class Luscious(
|
||||||
}
|
}
|
||||||
if (nextPage) {
|
if (nextPage) {
|
||||||
val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page))).execute()
|
val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page))).execute()
|
||||||
data = gson.fromJson<JsonObject>(newPage.body!!.string())
|
data = json.decodeFromString<JsonObject>(newPage.body!!.string())
|
||||||
.let { it["data"]["picture"]["list"].asJsonObject }
|
.let { it["data"]!!.jsonObject["picture"]!!.jsonObject["list"]!!.jsonObject }
|
||||||
}
|
}
|
||||||
page++
|
page++
|
||||||
}
|
}
|
||||||
|
@ -381,12 +382,12 @@ abstract class Luscious(
|
||||||
return client.newCall(GET(page.url, headers))
|
return client.newCall(GET(page.url, headers))
|
||||||
.asObservableSuccess()
|
.asObservableSuccess()
|
||||||
.map {
|
.map {
|
||||||
val data = gson.fromJson<JsonObject>(it.body!!.string()).let { data ->
|
val data = json.decodeFromString<JsonObject>(it.body!!.string()).let { data ->
|
||||||
data["data"]["picture"]["list"].asJsonObject
|
data["data"]!!.jsonObject["picture"]!!.jsonObject["list"]!!.jsonObject
|
||||||
}
|
}
|
||||||
when (getResolutionPref()) {
|
when (getResolutionPref()) {
|
||||||
"-1" -> data["items"].asJsonArray[page.index % 50].asJsonObject["url_to_original"].asString
|
"-1" -> data["items"]!!.jsonArray[page.index % 50].jsonObject["url_to_original"]!!.jsonPrimitive.content
|
||||||
else -> data["items"].asJsonArray[page.index % 50].asJsonObject["thumbnails"][getResolutionPref()?.toInt()!!]["url"].asString
|
else -> data["items"]!!.jsonArray[page.index % 50].jsonObject["thumbnails"]!!.jsonObject[getResolutionPref()?.toInt()!!]!!.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,32 +406,32 @@ abstract class Luscious(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun detailsParse(response: Response): SManga {
|
private fun detailsParse(response: Response): SManga {
|
||||||
val data = gson.fromJson<JsonObject>(response.body!!.string())
|
val data = json.decodeFromString<JsonObject>(response.body!!.string())
|
||||||
with(data["data"]["album"]["get"]) {
|
with(data["data"]!!.jsonObject["album"]!!.jsonObject["get"]!!.jsonObject) {
|
||||||
val manga = SManga.create()
|
val manga = SManga.create()
|
||||||
manga.url = this["url"].asString
|
manga.url = this["url"]!!.jsonPrimitive.content
|
||||||
manga.title = this["title"].asString
|
manga.title = this["title"]!!.jsonPrimitive.content
|
||||||
manga.thumbnail_url = this["cover"]["url"].asString
|
manga.thumbnail_url = this["cover"]!!.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
manga.status = 0
|
manga.status = 0
|
||||||
manga.description = "${this["description"].asString}\n\nPictures: ${this["number_of_pictures"].asString}\nAnimated Pictures: ${this["number_of_animated_pictures"].asString}"
|
manga.description = "${this["description"]!!.jsonPrimitive.content}\n\nPictures: ${this["number_of_pictures"]!!.jsonPrimitive.content}\nAnimated Pictures: ${this["number_of_animated_pictures"]!!.jsonPrimitive.content}"
|
||||||
var genreList = this["language"]["title"].asString
|
var genreList = this["language"]!!.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
for ((i, _) in this["labels"].asJsonArray.withIndex()) {
|
for ((i, _) in this["labels"]!!.jsonArray.withIndex()) {
|
||||||
genreList = "$genreList, ${this["labels"][i].asString}"
|
genreList = "$genreList, ${this["labels"]!!.jsonArray[i].jsonPrimitive.content}"
|
||||||
}
|
}
|
||||||
for ((i, _) in this["genres"].asJsonArray.withIndex()) {
|
for ((i, _) in this["genres"]!!.jsonArray.withIndex()) {
|
||||||
genreList = "$genreList, ${this["genres"][i]["title"].asString}"
|
genreList = "$genreList, ${this["genres"]!!.jsonArray[i].jsonObject["title"]!!.jsonPrimitive.content}"
|
||||||
}
|
}
|
||||||
for ((i, _) in this["audiences"].asJsonArray.withIndex()) {
|
for ((i, _) in this["audiences"]!!.jsonArray.withIndex()) {
|
||||||
genreList = "$genreList, ${this["audiences"][i]["title"].asString}"
|
genreList = "$genreList, ${this["audiences"]!!.jsonArray[i].jsonObject["title"]!!.jsonPrimitive.content}"
|
||||||
}
|
}
|
||||||
for ((i, _) in this["tags"].asJsonArray.withIndex()) {
|
for ((i, _) in this["tags"]!!.jsonArray.withIndex()) {
|
||||||
genreList = "$genreList, ${this["tags"][i]["text"].asString}"
|
genreList = "$genreList, ${this["tags"]!!.jsonArray[i].jsonObject["text"]!!.jsonPrimitive.content}"
|
||||||
if (this["tags"][i]["text"].asString.contains("Artist:")) {
|
if (this["tags"]!!.jsonArray[i].jsonObject["text"]!!.jsonPrimitive.content.contains("Artist:")) {
|
||||||
manga.artist = this["tags"][i]["text"].asString.substringAfter(":").trim()
|
manga.artist = this["tags"]!!.jsonArray[i].jsonObject["text"]!!.jsonPrimitive.content.substringAfter(":").trim()
|
||||||
manga.author = manga.artist
|
manga.author = manga.artist
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
genreList = "$genreList, ${this["content"]["title"].asString}"
|
genreList = "$genreList, ${this["content"]!!.jsonObject["title"]!!.jsonPrimitive.content}"
|
||||||
manga.genre = genreList
|
manga.genre = genreList
|
||||||
|
|
||||||
return manga
|
return manga
|
||||||
|
@ -483,9 +484,9 @@ abstract class Luscious(
|
||||||
|
|
||||||
private fun Filter<*>.toJsonObject(key: String): JsonObject {
|
private fun Filter<*>.toJsonObject(key: String): JsonObject {
|
||||||
val value = this.toString()
|
val value = this.toString()
|
||||||
return JsonObject().apply {
|
return buildJsonObject {
|
||||||
addProperty("name", key)
|
put("name", key)
|
||||||
addProperty("value", value)
|
put("value", value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,6 @@ package eu.kanade.tachiyomi.multisrc.mmrcms
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.github.salomonbrys.kotson.array
|
|
||||||
import com.github.salomonbrys.kotson.bool
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.string
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import com.google.gson.JsonParser
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
|
@ -19,11 +12,20 @@ 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 eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.boolean
|
||||||
|
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.Element
|
import org.jsoup.nodes.Element
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -33,7 +35,7 @@ abstract class MMRCMS(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val baseUrl: String,
|
override val baseUrl: String,
|
||||||
override val lang: String,
|
override val lang: String,
|
||||||
private val sourceInfo: String = "",
|
sourceInfo: String = "",
|
||||||
) : HttpSource() {
|
) : HttpSource() {
|
||||||
open val jsonData = if (sourceInfo == "") {
|
open val jsonData = if (sourceInfo == "") {
|
||||||
SourceData.giveMetaData(baseUrl)
|
SourceData.giveMetaData(baseUrl)
|
||||||
|
@ -72,14 +74,15 @@ abstract class MMRCMS(
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
open val jsonObject = JsonParser.parseString(jsonData) as JsonObject
|
private val json: Json by injectLazy()
|
||||||
override val supportsLatest = jsonObject["supports_latest"].bool
|
val jsonObject = json.decodeFromString<JsonObject>(jsonData)
|
||||||
open val itemUrl = jsonObject["item_url"].string
|
override val supportsLatest = jsonObject["supports_latest"]!!.jsonPrimitive.boolean
|
||||||
open val categoryMappings = mapToPairs(jsonObject["categories"].array)
|
open val itemUrl = jsonObject["item_url"]!!.jsonPrimitive.content
|
||||||
open var tagMappings = if (jsonObject["tags"].isJsonArray) {
|
open val categoryMappings = mapToPairs(jsonObject["categories"]!!.jsonArray)
|
||||||
mapToPairs(jsonObject["tags"].asJsonArray)
|
open var tagMappings = if (jsonObject["tags"] is JsonArray) {
|
||||||
|
mapToPairs(jsonObject["tags"]!!.jsonArray)
|
||||||
} else {
|
} else {
|
||||||
emptyList<Pair<String, String>>()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,7 +98,7 @@ abstract class MMRCMS(
|
||||||
open fun mapToPairs(array: JsonArray): List<Pair<String, String>> = array.map {
|
open fun mapToPairs(array: JsonArray): List<Pair<String, String>> = array.map {
|
||||||
it as JsonObject
|
it as JsonObject
|
||||||
|
|
||||||
it["id"].string to it["name"].string
|
it["id"]!!.jsonPrimitive.content to it["name"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
|
|
||||||
private val itemUrlPath = Uri.parse(itemUrl).pathSegments.firstOrNull()
|
private val itemUrlPath = Uri.parse(itemUrl).pathSegments.firstOrNull()
|
||||||
|
@ -153,16 +156,16 @@ abstract class MMRCMS(
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
return if (listOf("query", "q").any { it in response.request.url.queryParameterNames }) {
|
return if (listOf("query", "q").any { it in response.request.url.queryParameterNames }) {
|
||||||
// If a search query was specified, use search instead!
|
// If a search query was specified, use search instead!
|
||||||
val jsonArray = JsonParser.parseString(response.body!!.string()).let {
|
val jsonArray = json.decodeFromString<JsonObject>(response.body!!.string()).let {
|
||||||
it["suggestions"].array
|
it["suggestions"]!!.jsonArray
|
||||||
}
|
}
|
||||||
MangasPage(
|
MangasPage(
|
||||||
jsonArray
|
jsonArray
|
||||||
.map {
|
.map {
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
val segment = it["data"].string
|
val segment = it.jsonObject["data"]!!.jsonPrimitive.content
|
||||||
url = getUrlWithoutBaseUrl(itemUrl + segment)
|
url = getUrlWithoutBaseUrl(itemUrl + segment)
|
||||||
title = it["value"].string
|
title = it.jsonObject["value"]!!.jsonPrimitive.content
|
||||||
|
|
||||||
// Guess thumbnails
|
// Guess thumbnails
|
||||||
// thumbnail_url = "$baseUrl/uploads/manga/$segment/cover/cover_250x350.jpg"
|
// thumbnail_url = "$baseUrl/uploads/manga/$segment/cover/cover_250x350.jpg"
|
||||||
|
|
|
@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
@ -73,7 +73,7 @@ abstract class ToomicsGlobal(
|
||||||
.add("Content-Type", "application/x-www-form-urlencoded")
|
.add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val rbody = RequestBody.create(null, "toonData=$query&offset=0&limit=20")
|
val rbody = "toonData=$query&offset=0&limit=20".toRequestBody(null)
|
||||||
|
|
||||||
return POST("$baseUrl/$siteLang/webtoon/ajax_search", newHeaders, rbody)
|
return POST("$baseUrl/$siteLang/webtoon/ajax_search", newHeaders, rbody)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'GMANGA'
|
extName = 'GMANGA'
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.extension.ar.gmanga
|
package eu.kanade.tachiyomi.extension.ar.gmanga
|
||||||
|
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.nullString
|
|
||||||
import com.github.salomonbrys.kotson.toJsonArray
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.extension.ar.gmanga.GmangaPreferences.Companion.PREF_CHAPTER_LISTING
|
import eu.kanade.tachiyomi.extension.ar.gmanga.GmangaPreferences.Companion.PREF_CHAPTER_LISTING
|
||||||
import eu.kanade.tachiyomi.extension.ar.gmanga.GmangaPreferences.Companion.PREF_CHAPTER_LISTING_SHOW_POPULAR
|
import eu.kanade.tachiyomi.extension.ar.gmanga.GmangaPreferences.Companion.PREF_CHAPTER_LISTING_SHOW_POPULAR
|
||||||
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
||||||
|
@ -21,12 +14,24 @@ 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 eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.contentOrNull
|
||||||
|
import kotlinx.serialization.json.float
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
import kotlinx.serialization.json.long
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
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
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class Gmanga : ConfigurableSource, HttpSource() {
|
class Gmanga : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
|
@ -40,7 +45,7 @@ class Gmanga : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
override val supportsLatest: Boolean = true
|
override val supportsLatest: Boolean = true
|
||||||
|
|
||||||
private val gson = Gson()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
private val preferences = GmangaPreferences(id)
|
private val preferences = GmangaPreferences(id)
|
||||||
|
|
||||||
|
@ -67,18 +72,18 @@ class Gmanga : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
val chapters: List<JsonArray> = buildList {
|
val chapters: List<JsonArray> = buildList {
|
||||||
val allChapters: ArrayList<JsonArray> = ArrayList()
|
val allChapters: ArrayList<JsonArray> = ArrayList()
|
||||||
data["rows"][0]["rows"].asJsonArray.forEach { release ->
|
data["rows"]!!.jsonArray[0].jsonObject["rows"]!!.jsonArray.forEach { release ->
|
||||||
val chapter = data["rows"][2]["rows"].asJsonArray.filter { it[0] == release[4] }.toJsonArray()
|
val chapter = data["rows"]!!.jsonArray[2].jsonObject["rows"]!!.jsonArray.filter { it.jsonArray[0] == release.jsonArray[4] }
|
||||||
chapter.asJsonArray.forEach { release.asJsonArray.addAll(it.asJsonArray) }
|
allChapters.addAll(chapter.map { it.jsonArray })
|
||||||
val team = data["rows"][1]["rows"].asJsonArray.filter { it[0] == release[5] }.toJsonArray()
|
val team = data["rows"]!!.jsonArray[1].jsonObject["rows"]!!.jsonArray.filter { it.jsonArray[0] == release.jsonArray[5] }
|
||||||
team.asJsonArray.forEach { release.asJsonArray.addAll(it.asJsonArray) }
|
allChapters.addAll(team.map { it.jsonArray })
|
||||||
allChapters.add(release.asJsonArray)
|
allChapters.add(release.jsonArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (preferences.getString(PREF_CHAPTER_LISTING)) {
|
when (preferences.getString(PREF_CHAPTER_LISTING)) {
|
||||||
PREF_CHAPTER_LISTING_SHOW_POPULAR -> addAll(
|
PREF_CHAPTER_LISTING_SHOW_POPULAR -> addAll(
|
||||||
allChapters.groupBy { it.asJsonArray[4].asFloat }
|
allChapters.groupBy { it.jsonArray[4].jsonPrimitive.float }
|
||||||
.map { (_: Float, versions: List<JsonArray>) -> versions.maxByOrNull { it[5].asLong }!! }
|
.map { (_: Float, versions: List<JsonArray>) -> versions.maxByOrNull { it[5].jsonPrimitive.float }!! }
|
||||||
)
|
)
|
||||||
else -> addAll(allChapters)
|
else -> addAll(allChapters)
|
||||||
}
|
}
|
||||||
|
@ -86,14 +91,14 @@ class Gmanga : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
return chapters.map {
|
return chapters.map {
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
chapter_number = it[8].asFloat
|
chapter_number = it[8].jsonPrimitive.float
|
||||||
|
|
||||||
val chapterName = it[10].asString.let { if (it.trim() != "") " - $it" else "" }
|
val chapterName = it[10].jsonPrimitive.content.let { if (it.trim() != "") " - $it" else "" }
|
||||||
|
|
||||||
url = "/r/${it[0]}"
|
url = "/r/${it[0]}"
|
||||||
name = "${chapter_number.let { if (it % 1 > 0) it else it.toInt() }}$chapterName"
|
name = "${chapter_number.let { if (it % 1 > 0) it else it.toInt() }}$chapterName"
|
||||||
date_upload = it[2].asLong * 1000
|
date_upload = it[2].jsonPrimitive.long * 1000
|
||||||
scanlator = it[13].asString
|
scanlator = it[13].jsonPrimitive.content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,16 +106,16 @@ class Gmanga : ConfigurableSource, HttpSource() {
|
||||||
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
|
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||||
val data = gson.fromJson<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html())
|
val data = json.decodeFromString<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html())
|
||||||
return MangasPage(
|
return MangasPage(
|
||||||
data["mangaDataAction"]["newMangas"].asJsonArray.map {
|
data["mangaDataAction"]!!.jsonObject["newMangas"]!!.jsonArray.map {
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
url = "/mangas/${it["id"].asString}"
|
url = "/mangas/${it.jsonObject["id"]!!.jsonPrimitive.content}"
|
||||||
title = it["title"].asString
|
title = it.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
|
|
||||||
thumbnail_url = it["cover"].nullString?.let { coverFileName ->
|
thumbnail_url = it.jsonObject["cover"]!!.jsonPrimitive.contentOrNull?.let { coverFileName ->
|
||||||
val thumbnail = "medium_${coverFileName.substringBeforeLast(".")}.webp"
|
val thumbnail = "medium_${coverFileName.substringBeforeLast(".")}.webp"
|
||||||
"https://media.$domain/uploads/manga/cover/${it["id"].asString}/$thumbnail"
|
"https://media.$domain/uploads/manga/cover/${it.jsonObject["id"]!!.jsonPrimitive.content}/$thumbnail"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -123,27 +128,27 @@ class Gmanga : ConfigurableSource, HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val data = gson.fromJson<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html())
|
val data = json.decodeFromString<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html())
|
||||||
val mangaData = data["mangaDataAction"]["mangaData"].asJsonObject
|
val mangaData = data["mangaDataAction"]!!.jsonObject["mangaData"]!!.jsonObject
|
||||||
return SManga.create().apply {
|
return SManga.create().apply {
|
||||||
description = mangaData["summary"].nullString ?: ""
|
description = mangaData["summary"]!!.jsonPrimitive.contentOrNull ?: ""
|
||||||
artist = mangaData["artists"].asJsonArray.joinToString(", ") { it.asJsonObject["name"].asString }
|
artist = mangaData["artists"]!!.jsonArray.joinToString(", ") { it.jsonObject["name"]!!.jsonPrimitive.content }
|
||||||
author = mangaData["authors"].asJsonArray.joinToString(", ") { it.asJsonObject["name"].asString }
|
author = mangaData["authors"]!!.jsonArray.joinToString(", ") { it.jsonObject["name"]!!.jsonPrimitive.content }
|
||||||
genre = mangaData["categories"].asJsonArray.joinToString(", ") { it.asJsonObject["name"].asString }
|
genre = mangaData["categories"]!!.jsonArray.joinToString(", ") { it.jsonObject["name"]!!.jsonPrimitive.content }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val url = response.request.url.toString()
|
val url = response.request.url.toString()
|
||||||
val data = gson.fromJson<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html())
|
val data = json.decodeFromString<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html())
|
||||||
val releaseData = data["readerDataAction"]["readerData"]["release"].asJsonObject
|
val releaseData = data["readerDataAction"]!!.jsonObject["readerData"]!!.jsonObject["release"]!!.jsonObject
|
||||||
|
|
||||||
val hasWebP = releaseData["webp_pages"].asJsonArray.size() > 0
|
val hasWebP = releaseData["webp_pages"]!!.jsonArray.size > 0
|
||||||
return releaseData[if (hasWebP) "webp_pages" else "pages"].asJsonArray.map { it.asString }.mapIndexed { index, pageUri ->
|
return releaseData[if (hasWebP) "webp_pages" else "pages"]!!.jsonArray.map { it.jsonPrimitive.content }.mapIndexed { index, pageUri ->
|
||||||
Page(
|
Page(
|
||||||
index,
|
index,
|
||||||
"$url#page_$index",
|
"$url#page_$index",
|
||||||
"https://media.$domain/uploads/releases/${releaseData["storage_key"].asString}/hq${if (hasWebP) "_webp" else ""}/$pageUri"
|
"https://media.$domain/uploads/releases/${releaseData["storage_key"]!!.jsonPrimitive.content}/hq${if (hasWebP) "_webp" else ""}/$pageUri"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,29 +159,29 @@ class Gmanga : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
val data = decryptResponse(response)
|
val data = decryptResponse(response)
|
||||||
val mangas = data["mangas"].asJsonArray
|
val mangas = data["mangas"]!!.jsonArray
|
||||||
return MangasPage(
|
return MangasPage(
|
||||||
mangas.asJsonArray.map {
|
mangas.jsonArray.map {
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
url = "/mangas/${it["id"].asString}"
|
url = "/mangas/${it.jsonObject["id"]!!.jsonPrimitive.content}"
|
||||||
title = it["title"].asString
|
title = it.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
val thumbnail = "medium_${it["cover"].asString.substringBeforeLast(".")}.webp"
|
val thumbnail = "medium_${it.jsonObject["cover"]!!.jsonPrimitive.content.substringBeforeLast(".")}.webp"
|
||||||
thumbnail_url = "https://media.$domain/uploads/manga/cover/${it["id"].asString}/$thumbnail"
|
thumbnail_url = "https://media.$domain/uploads/manga/cover/${it.jsonObject["id"]!!.jsonPrimitive.content}/$thumbnail"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mangas.size() == 50
|
mangas.size == 50
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decryptResponse(response: Response): JsonObject {
|
private fun decryptResponse(response: Response): JsonObject {
|
||||||
val encryptedData = gson.fromJson<JsonObject>(response.body!!.string())["data"].asString
|
val encryptedData = json.decodeFromString<JsonObject>(response.body!!.string())["data"]!!.jsonPrimitive.content
|
||||||
val decryptedData = decrypt(encryptedData)
|
val decryptedData = decrypt(encryptedData)
|
||||||
return gson.fromJson(decryptedData)
|
return json.decodeFromString(decryptedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
return GmangaFilters.buildSearchPayload(page, query, if (filters.isEmpty()) getFilterList() else filters).let {
|
return GmangaFilters.buildSearchPayload(page, query, if (filters.isEmpty()) getFilterList() else filters).let {
|
||||||
val body = RequestBody.create(MEDIA_TYPE, it.toString())
|
val body = it.toString().toRequestBody(MEDIA_TYPE)
|
||||||
POST("$baseUrl/api/mangas/search", headers, body)
|
POST("$baseUrl/api/mangas/search", headers, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package eu.kanade.tachiyomi.extension.ar.gmanga
|
package eu.kanade.tachiyomi.extension.ar.gmanga
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import com.github.salomonbrys.kotson.addAll
|
|
||||||
import com.github.salomonbrys.kotson.addProperty
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonNull
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
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
|
||||||
import java.lang.Exception
|
import kotlinx.serialization.json.JsonNull
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.JsonObjectBuilder
|
||||||
|
import kotlinx.serialization.json.add
|
||||||
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
|
import kotlinx.serialization.json.put
|
||||||
|
import kotlinx.serialization.json.putJsonArray
|
||||||
|
import kotlinx.serialization.json.putJsonObject
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
|
||||||
|
@ -35,139 +37,90 @@ class GmangaFilters() {
|
||||||
val dateRangeFilter = filters.findInstance<DateRangeFilter>()!!
|
val dateRangeFilter = filters.findInstance<DateRangeFilter>()!!
|
||||||
val categoryFilter = filters.findInstance<CategoryFilter>()!!
|
val categoryFilter = filters.findInstance<CategoryFilter>()!!
|
||||||
|
|
||||||
return JsonObject().apply {
|
return buildJsonObject {
|
||||||
|
|
||||||
oneShotFilter.state.first().let {
|
oneShotFilter.state.first().let {
|
||||||
when {
|
when {
|
||||||
it.isIncluded() -> addProperty("oneshot", true)
|
it.isIncluded() -> put("oneshot", true)
|
||||||
it.isExcluded() -> addProperty("oneshot", false)
|
it.isExcluded() -> put("oneshot", false)
|
||||||
else -> addProperty("oneshot", JsonNull.INSTANCE)
|
else -> put("oneshot", JsonNull)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addProperty("title", query)
|
put("title", query)
|
||||||
addProperty("page", page)
|
put("page", page)
|
||||||
addProperty(
|
putJsonObject("manga_types") {
|
||||||
"manga_types",
|
putJsonArray("include") {
|
||||||
JsonObject().apply {
|
mangaTypeFilter.state.filter { it.isIncluded() }.map { it.id }.forEach { add(it) }
|
||||||
|
|
||||||
addProperty(
|
|
||||||
"include",
|
|
||||||
JsonArray().apply {
|
|
||||||
addAll(mangaTypeFilter.state.filter { it.isIncluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
addProperty(
|
|
||||||
"exclude",
|
|
||||||
JsonArray().apply {
|
|
||||||
addAll(mangaTypeFilter.state.filter { it.isExcluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
addProperty(
|
|
||||||
"story_status",
|
|
||||||
JsonObject().apply {
|
|
||||||
|
|
||||||
addProperty(
|
putJsonArray("exclude") {
|
||||||
"include",
|
mangaTypeFilter.state.filter { it.isExcluded() }.map { it.id }.forEach { add(it) }
|
||||||
JsonArray().apply {
|
|
||||||
addAll(storyStatusFilter.state.filter { it.isIncluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
addProperty(
|
|
||||||
"exclude",
|
|
||||||
JsonArray().apply {
|
|
||||||
addAll(storyStatusFilter.state.filter { it.isExcluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
addProperty(
|
putJsonObject("story_status") {
|
||||||
"translation_status",
|
putJsonArray("include") {
|
||||||
JsonObject().apply {
|
storyStatusFilter.state.filter { it.isIncluded() }.map { it.id }.forEach { add(it) }
|
||||||
|
|
||||||
addProperty(
|
|
||||||
"include",
|
|
||||||
JsonArray().apply {
|
|
||||||
addAll(translationStatusFilter.state.filter { it.isIncluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
addProperty(
|
|
||||||
"exclude",
|
|
||||||
JsonArray().apply {
|
|
||||||
addAll(translationStatusFilter.state.filter { it.isExcluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
addProperty(
|
|
||||||
"categories",
|
|
||||||
JsonObject().apply {
|
|
||||||
|
|
||||||
addProperty(
|
putJsonArray("exclude") {
|
||||||
"include",
|
storyStatusFilter.state.filter { it.isExcluded() }.map { it.id }.forEach { add(it) }
|
||||||
JsonArray().apply {
|
|
||||||
add(JsonNull.INSTANCE) // always included, maybe to avoid shifting index in the backend
|
|
||||||
addAll(categoryFilter.state.filter { it.isIncluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
addProperty(
|
|
||||||
"exclude",
|
|
||||||
JsonArray().apply {
|
|
||||||
addAll(categoryFilter.state.filter { it.isExcluded() }.map { it.id })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
addProperty(
|
putJsonObject("translation_status") {
|
||||||
"chapters",
|
putJsonArray("include") {
|
||||||
JsonObject().apply {
|
translationStatusFilter.state.filter { it.isIncluded() }.map { it.id }.forEach { add(it) }
|
||||||
|
|
||||||
addPropertyFromValidatingTextFilter(
|
|
||||||
chapterCountFilter.state.first {
|
|
||||||
it.id == FILTER_ID_MIN_CHAPTER_COUNT
|
|
||||||
},
|
|
||||||
"min",
|
|
||||||
ERROR_INVALID_MIN_CHAPTER_COUNT,
|
|
||||||
""
|
|
||||||
)
|
|
||||||
|
|
||||||
addPropertyFromValidatingTextFilter(
|
|
||||||
chapterCountFilter.state.first {
|
|
||||||
it.id == FILTER_ID_MAX_CHAPTER_COUNT
|
|
||||||
},
|
|
||||||
"max",
|
|
||||||
ERROR_INVALID_MAX_CHAPTER_COUNT,
|
|
||||||
""
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
addProperty(
|
|
||||||
"dates",
|
|
||||||
JsonObject().apply {
|
|
||||||
|
|
||||||
addPropertyFromValidatingTextFilter(
|
putJsonArray("exclude") {
|
||||||
dateRangeFilter.state.first {
|
translationStatusFilter.state.filter { it.isExcluded() }.map { it.id }.forEach { add(it) }
|
||||||
it.id == FILTER_ID_START_DATE
|
|
||||||
},
|
|
||||||
"start",
|
|
||||||
ERROR_INVALID_START_DATE
|
|
||||||
)
|
|
||||||
|
|
||||||
addPropertyFromValidatingTextFilter(
|
|
||||||
dateRangeFilter.state.first {
|
|
||||||
it.id == FILTER_ID_END_DATE
|
|
||||||
},
|
|
||||||
"end",
|
|
||||||
ERROR_INVALID_END_DATE
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
putJsonObject("categories") {
|
||||||
|
putJsonArray("include") {
|
||||||
|
add(JsonNull) // always included, maybe to avoid shifting index in the backend
|
||||||
|
categoryFilter.state.filter { it.isIncluded() }.map { it.id }.forEach { add(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
putJsonArray("exclude") {
|
||||||
|
categoryFilter.state.filter { it.isExcluded() }.map { it.id }.forEach { add(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putJsonObject("chapters") {
|
||||||
|
putFromValidatingTextFilter(
|
||||||
|
chapterCountFilter.state.first {
|
||||||
|
it.id == FILTER_ID_MIN_CHAPTER_COUNT
|
||||||
|
},
|
||||||
|
"min",
|
||||||
|
ERROR_INVALID_MIN_CHAPTER_COUNT,
|
||||||
|
""
|
||||||
|
)
|
||||||
|
|
||||||
|
putFromValidatingTextFilter(
|
||||||
|
chapterCountFilter.state.first {
|
||||||
|
it.id == FILTER_ID_MAX_CHAPTER_COUNT
|
||||||
|
},
|
||||||
|
"max",
|
||||||
|
ERROR_INVALID_MAX_CHAPTER_COUNT,
|
||||||
|
""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
putJsonObject("dates") {
|
||||||
|
putFromValidatingTextFilter(
|
||||||
|
dateRangeFilter.state.first {
|
||||||
|
it.id == FILTER_ID_START_DATE
|
||||||
|
},
|
||||||
|
"start",
|
||||||
|
ERROR_INVALID_START_DATE
|
||||||
|
)
|
||||||
|
|
||||||
|
putFromValidatingTextFilter(
|
||||||
|
dateRangeFilter.state.first {
|
||||||
|
it.id == FILTER_ID_END_DATE
|
||||||
|
},
|
||||||
|
"end",
|
||||||
|
ERROR_INVALID_END_DATE
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +251,7 @@ class GmangaFilters() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JsonObject.addPropertyFromValidatingTextFilter(
|
private fun JsonObjectBuilder.putFromValidatingTextFilter(
|
||||||
filter: ValidatingTextFilter,
|
filter: ValidatingTextFilter,
|
||||||
property: String,
|
property: String,
|
||||||
invalidErrorMessage: String,
|
invalidErrorMessage: String,
|
||||||
|
@ -307,9 +260,9 @@ class GmangaFilters() {
|
||||||
filter.let {
|
filter.let {
|
||||||
when {
|
when {
|
||||||
it.state == "" -> if (default == null) {
|
it.state == "" -> if (default == null) {
|
||||||
addProperty(property, JsonNull.INSTANCE)
|
put(property, JsonNull)
|
||||||
} else addProperty(property, default)
|
} else put(property, default)
|
||||||
it.isValid() -> addProperty(property, it.state)
|
it.isValid() -> put(property, it.state)
|
||||||
else -> throw Exception(invalidErrorMessage)
|
else -> throw Exception(invalidErrorMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'Manga Tube'
|
extName = 'Manga Tube'
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.extension.de.mangatube
|
package eu.kanade.tachiyomi.extension.de.mangatube
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
|
@ -14,14 +9,22 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
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.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -45,7 +48,7 @@ class MangaTube : ParsedHttpSource() {
|
||||||
|
|
||||||
private val xhrHeaders: Headers = headersBuilder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build()
|
private val xhrHeaders: Headers = headersBuilder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build()
|
||||||
|
|
||||||
private val gson by lazy { Gson() }
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
// Popular
|
// Popular
|
||||||
|
|
||||||
|
@ -59,21 +62,21 @@ class MangaTube : ParsedHttpSource() {
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
val rbodyContent = "action=load_series_list_entries¶meter%5Bpage%5D=$page¶meter%5Bletter%5D=¶meter%5Bsortby%5D=popularity¶meter%5Border%5D=asc"
|
val rbodyContent = "action=load_series_list_entries¶meter%5Bpage%5D=$page¶meter%5Bletter%5D=¶meter%5Bsortby%5D=popularity¶meter%5Border%5D=asc"
|
||||||
return POST("$baseUrl/ajax", xhrHeaders, RequestBody.create(null, rbodyContent))
|
return POST("$baseUrl/ajax", xhrHeaders, rbodyContent.toRequestBody(null))
|
||||||
}
|
}
|
||||||
|
|
||||||
// popular uses "success" as a key, search uses "suggestions"
|
// popular uses "success" as a key, search uses "suggestions"
|
||||||
// for future reference: if adding filters, advanced search might use a different key
|
// for future reference: if adding filters, advanced search might use a different key
|
||||||
private fun parseMangaFromJson(response: Response, hasNextPage: Boolean): MangasPage {
|
private fun parseMangaFromJson(response: Response, hasNextPage: Boolean): MangasPage {
|
||||||
var titleKey = "manga_title"
|
var titleKey = "manga_title"
|
||||||
val mangas = gson.fromJson<JsonObject>(response.body!!.string())
|
val mangas = json.decodeFromString<JsonObject>(response.body!!.string())
|
||||||
.let { it["success"] ?: it["suggestions"].also { titleKey = "value" } }
|
.let { it["success"] ?: it["suggestions"].also { titleKey = "value" } }!!
|
||||||
.asJsonArray
|
.jsonArray
|
||||||
.map { json ->
|
.map { json ->
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
title = json[titleKey].asString
|
title = json.jsonObject[titleKey]!!.jsonPrimitive.content
|
||||||
url = "/series/${json["manga_slug"].asString}"
|
url = "/series/${json.jsonObject["manga_slug"]!!.jsonPrimitive.content}"
|
||||||
thumbnail_url = json["covers"][0]["img_name"].asString
|
thumbnail_url = json.jsonObject["covers"]!!.jsonArray[0].jsonObject["img_name"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MangasPage(mangas, hasNextPage)
|
return MangasPage(mangas, hasNextPage)
|
||||||
|
@ -109,7 +112,7 @@ class MangaTube : ParsedHttpSource() {
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val rbodyContent = "action=search_query¶meter%5Bquery%5D=$query"
|
val rbodyContent = "action=search_query¶meter%5Bquery%5D=$query"
|
||||||
return POST("$baseUrl/ajax", xhrHeaders, RequestBody.create(null, rbodyContent))
|
return POST("$baseUrl/ajax", xhrHeaders, rbodyContent.toRequestBody(null))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
|
@ -173,8 +176,8 @@ class MangaTube : ParsedHttpSource() {
|
||||||
val jsonArray = Regex("""pages: (\[.*]),""").find(script)?.groupValues?.get(1)
|
val jsonArray = Regex("""pages: (\[.*]),""").find(script)?.groupValues?.get(1)
|
||||||
?: throw Exception("Couldn't find JSON array")
|
?: throw Exception("Couldn't find JSON array")
|
||||||
|
|
||||||
return gson.fromJson<JsonArray>(jsonArray).mapIndexed { i, json ->
|
return json.decodeFromString<JsonArray>(jsonArray).mapIndexed { i, json ->
|
||||||
Page(i, "", imagePath + json.asJsonObject["file_name"].asString)
|
Page(i, "", imagePath + json.jsonObject["file_name"]!!.jsonPrimitive.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'Mangahub'
|
extName = 'Mangahub'
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.mangahub
|
package eu.kanade.tachiyomi.extension.en.mangahub
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.keys
|
|
||||||
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.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
|
@ -14,12 +8,18 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
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.net.URL
|
import java.net.URL
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -156,21 +156,26 @@ class Mangahub : ParsedHttpSource() {
|
||||||
|
|
||||||
val slug = chapter.url.substringAfter("chapter/").substringBefore("/")
|
val slug = chapter.url.substringAfter("chapter/").substringBefore("/")
|
||||||
val number = chapter.url.substringAfter("chapter-").removeSuffix("/")
|
val number = chapter.url.substringAfter("chapter-").removeSuffix("/")
|
||||||
val body = RequestBody.create(null, "{\"query\":\"{chapter(x:m01,slug:\\\"$slug\\\",number:$number){id,title,mangaID,number,slug,date,pages,noAd,manga{id,title,slug,mainSlug,author,isWebtoon,isYaoi,isPorn,isSoftPorn,unauthFile,isLicensed}}}\"}")
|
val body =
|
||||||
|
"{\"query\":\"{chapter(x:m01,slug:\\\"$slug\\\",number:$number){id,title,mangaID,number,slug,date,pages,noAd,manga{id,title,slug,mainSlug,author,isWebtoon,isYaoi,isPorn,isSoftPorn,unauthFile,isLicensed}}}\"}".toRequestBody(
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
return POST("https://api.mghubcdn.com/graphql", jsonHeaders, body)
|
return POST("https://api.mghubcdn.com/graphql", jsonHeaders, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val gson = Gson()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val cdn = "https://img.mghubcdn.com/file/imghub"
|
val cdn = "https://img.mghubcdn.com/file/imghub"
|
||||||
|
|
||||||
return gson.fromJson<JsonObject>(response.body!!.string())["data"]["chapter"]["pages"].string
|
return json.decodeFromString<JsonObject>(response.body!!.string())["data"]!!
|
||||||
|
.jsonObject["chapter"]!!
|
||||||
|
.jsonObject["pages"]!!.jsonPrimitive.content
|
||||||
.removeSurrounding("\"").replace("\\", "")
|
.removeSurrounding("\"").replace("\\", "")
|
||||||
.let { cleaned ->
|
.let { cleaned ->
|
||||||
val jsonObject = gson.fromJson<JsonObject>(cleaned)
|
val jsonObject = json.decodeFromString<JsonObject>(cleaned)
|
||||||
jsonObject.keys().map { key -> jsonObject[key].string }
|
jsonObject.keys.map { key -> jsonObject[key]!!.jsonPrimitive.content }
|
||||||
}
|
}
|
||||||
.mapIndexed { i, tail -> Page(i, "", "$cdn/$tail") }
|
.mapIndexed { i, tail -> Page(i, "", "$cdn/$tail") }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'MangaRock.es'
|
extName = 'MangaRock.es'
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.mangarockes
|
package eu.kanade.tachiyomi.extension.en.mangarockes
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
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
|
||||||
|
@ -10,6 +7,11 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
@ -18,6 +20,7 @@ import okhttp3.Response
|
||||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||||
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.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -160,13 +163,13 @@ class MangaRockEs : ParsedHttpSource() {
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
|
|
||||||
private val gson by lazy { Gson() }
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val responseString = response.body!!.string()
|
val responseString = response.body!!.string()
|
||||||
return Regex("""mangaData = (\[.*]);""", RegexOption.IGNORE_CASE).find(responseString)?.groupValues?.get(1)?.let { array ->
|
return Regex("""mangaData = (\[.*]);""", RegexOption.IGNORE_CASE).find(responseString)?.groupValues?.get(1)?.let { array ->
|
||||||
gson.fromJson<JsonArray>(array)
|
json.decodeFromString<JsonArray>(array)
|
||||||
.mapIndexed { i, jsonElement -> Page(i, "", jsonElement.asJsonObject["url"].asString) }
|
.mapIndexed { i, jsonElement -> Page(i, "", jsonElement.jsonObject["url"]!!.jsonPrimitive.content) }
|
||||||
}
|
}
|
||||||
?: Regex("""getManga\(\d+, '(http.*)',""").findAll(responseString).toList()
|
?: Regex("""getManga\(\d+, '(http.*)',""").findAll(responseString).toList()
|
||||||
.mapIndexed { i, mr -> Page(i, "", mr.groupValues[1]) }
|
.mapIndexed { i, mr -> Page(i, "", mr.groupValues[1]) }
|
||||||
|
|
|
@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
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
|
||||||
|
@ -69,7 +69,7 @@ class ManhuaManga : ParsedHttpSource() {
|
||||||
protected fun getXhrChapters(mangaId: String): Document {
|
protected fun getXhrChapters(mangaId: String): Document {
|
||||||
val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8")
|
val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8")
|
||||||
.build()
|
.build()
|
||||||
val body = RequestBody.create(null, "action=tw_ajax&type=list_chap&id=$mangaId")
|
val body = "action=tw_ajax&type=list_chap&id=$mangaId".toRequestBody(null)
|
||||||
return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).execute().asJsoup()
|
return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).execute().asJsoup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
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
|
||||||
|
@ -69,7 +69,7 @@ class ManhwaManga : ParsedHttpSource() {
|
||||||
protected fun getXhrChapters(mangaId: String): Document {
|
protected fun getXhrChapters(mangaId: String): Document {
|
||||||
val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8")
|
val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8")
|
||||||
.build()
|
.build()
|
||||||
val body = RequestBody.create(null, "action=tw_ajax&type=list_chap&id=$mangaId")
|
val body = "action=tw_ajax&type=list_chap&id=$mangaId".toRequestBody(null)
|
||||||
return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).execute().asJsoup()
|
return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).execute().asJsoup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'ReadManhwa'
|
extName = 'ReadManhwa'
|
||||||
|
|
|
@ -2,14 +2,6 @@ package eu.kanade.tachiyomi.extension.en.readmanhwa
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.int
|
|
||||||
import com.github.salomonbrys.kotson.nullString
|
|
||||||
import com.github.salomonbrys.kotson.string
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
|
@ -20,6 +12,15 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.contentOrNull
|
||||||
|
import kotlinx.serialization.json.int
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
@ -28,6 +29,7 @@ import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
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.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -54,20 +56,20 @@ class ReadManhwa : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient
|
override val client: OkHttpClient = network.cloudflareClient
|
||||||
|
|
||||||
private val gson = Gson()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
private fun parseMangaFromJson(response: Response): MangasPage {
|
private fun parseMangaFromJson(response: Response): MangasPage {
|
||||||
val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
|
val jsonObject = json.decodeFromString<JsonObject>(response.body!!.string())
|
||||||
|
|
||||||
val mangas = jsonObject["data"].asJsonArray.map { json ->
|
val mangas = jsonObject["data"]!!.jsonArray.map { json ->
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
title = json["title"].string
|
title = json.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
thumbnail_url = json["image_url"].string
|
thumbnail_url = json.jsonObject["image_url"]!!.jsonPrimitive.content
|
||||||
url = json["slug"].string
|
url = json.jsonObject["slug"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MangasPage(mangas, jsonObject["current_page"].int < jsonObject["last_page"].int)
|
return MangasPage(mangas, jsonObject["current_page"]!!.jsonPrimitive.int < jsonObject["last_page"]!!.jsonPrimitive.int)
|
||||||
}
|
}
|
||||||
private fun getMangaUrl(url: String): String {
|
private fun getMangaUrl(url: String): String {
|
||||||
return url.toHttpUrlOrNull()!!.newBuilder()
|
return url.toHttpUrlOrNull()!!.newBuilder()
|
||||||
|
@ -159,15 +161,15 @@ class ReadManhwa : ConfigurableSource, HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
|
val jsonObject = json.decodeFromString<JsonObject>(response.body!!.string())
|
||||||
|
|
||||||
return SManga.create().apply {
|
return SManga.create().apply {
|
||||||
description = jsonObject["description"].nullString
|
description = jsonObject["description"]!!.jsonPrimitive.contentOrNull
|
||||||
status = jsonObject["status"].nullString.toStatus()
|
status = jsonObject["status"]!!.jsonPrimitive.contentOrNull.toStatus()
|
||||||
thumbnail_url = jsonObject["image_url"].nullString
|
thumbnail_url = jsonObject["image_url"]!!.jsonPrimitive.contentOrNull
|
||||||
genre = try { jsonObject["tags"].asJsonArray.joinToString { it["name"].string } } catch (_: Exception) { null }
|
genre = try { jsonObject["tags"]!!.jsonArray.joinToString { it.jsonObject["name"]!!.jsonPrimitive.content } } catch (_: Exception) { null }
|
||||||
artist = try { jsonObject["artists"].asJsonArray.joinToString { it["name"].string } } catch (_: Exception) { null }
|
artist = try { jsonObject["artists"]!!.jsonArray.joinToString { it.jsonObject["name"]!!.jsonPrimitive.content } } catch (_: Exception) { null }
|
||||||
author = try { jsonObject["authors"].asJsonArray.joinToString { it["name"].string } } catch (_: Exception) { null }
|
author = try { jsonObject["authors"]!!.jsonArray.joinToString { it.jsonObject["name"]!!.jsonPrimitive.content } } catch (_: Exception) { null }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,11 +195,11 @@ class ReadManhwa : ConfigurableSource, HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun chapterListParse(response: Response, titleSlug: String): List<SChapter> {
|
private fun chapterListParse(response: Response, titleSlug: String): List<SChapter> {
|
||||||
return gson.fromJson<JsonArray>(response.body!!.string()).map { json ->
|
return json.decodeFromString<JsonArray>(response.body!!.string()).map { json ->
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
name = json["name"].string
|
name = json.jsonObject["name"]!!.jsonPrimitive.content
|
||||||
url = "$titleSlug/${json["slug"].string}"
|
url = "$titleSlug/${json.jsonObject["slug"]!!.jsonPrimitive.content}"
|
||||||
date_upload = json["added_at"].string.let { dateString ->
|
date_upload = json.jsonObject["added_at"]!!.jsonPrimitive.content.let { dateString ->
|
||||||
if (dateString.contains("ago")) {
|
if (dateString.contains("ago")) {
|
||||||
val trimmedDate = dateString.substringBefore(" ago").removeSuffix("s").split(" ")
|
val trimmedDate = dateString.substringBefore(" ago").removeSuffix("s").split(" ")
|
||||||
val calendar = Calendar.getInstance()
|
val calendar = Calendar.getInstance()
|
||||||
|
@ -225,8 +227,8 @@ class ReadManhwa : ConfigurableSource, HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
return gson.fromJson<JsonObject>(response.body!!.string())["images"].asJsonArray.mapIndexed { i, json ->
|
return json.decodeFromString<JsonObject>(response.body!!.string())["images"]!!.jsonArray.mapIndexed { i, json ->
|
||||||
Page(i, "", json["source_url"].string)
|
Page(i, "", json.jsonObject["source_url"]!!.jsonPrimitive.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ 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 okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
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
|
||||||
|
@ -131,7 +131,7 @@ class DoujinYang : ParsedHttpSource() {
|
||||||
return POST(
|
return POST(
|
||||||
baseUrl + chapter.url,
|
baseUrl + chapter.url,
|
||||||
headersBuilder().add("Content-Type", "application/x-www-form-urlencoded").build(),
|
headersBuilder().add("Content-Type", "application/x-www-form-urlencoded").build(),
|
||||||
RequestBody.create(null, "info")
|
"info".toRequestBody(null)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.extension.es.kumanga
|
package eu.kanade.tachiyomi.extension.es.kumanga
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import com.github.salomonbrys.kotson.jsonObject
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'ComX'
|
extName = 'ComX'
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.extension.ru.comx
|
package eu.kanade.tachiyomi.extension.ru.comx
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.nullArray
|
|
||||||
import com.github.salomonbrys.kotson.obj
|
|
||||||
import com.google.gson.JsonParser
|
|
||||||
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
|
@ -15,6 +11,12 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
|
@ -23,12 +25,16 @@ 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.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class ComX : ParsedHttpSource() {
|
class ComX : ParsedHttpSource() {
|
||||||
|
|
||||||
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override val name = "Com-x"
|
override val name = "Com-x"
|
||||||
|
|
||||||
override val baseUrl = "https://com-x.life"
|
override val baseUrl = "https://com-x.life"
|
||||||
|
@ -186,13 +192,13 @@ class ComX : ParsedHttpSource() {
|
||||||
.substringBefore("</script>")
|
.substringBefore("</script>")
|
||||||
.substringBeforeLast(";")
|
.substringBeforeLast(";")
|
||||||
|
|
||||||
val data = JsonParser.parseString(dataStr).obj
|
val data = json.decodeFromString<JsonObject>(dataStr)
|
||||||
val chaptersList = data["chapters"].nullArray
|
val chaptersList = data["chapters"]?.jsonArray
|
||||||
val chapters: List<SChapter>? = chaptersList?.map {
|
val chapters: List<SChapter>? = chaptersList?.map {
|
||||||
val chapter = SChapter.create()
|
val chapter = SChapter.create()
|
||||||
chapter.name = it["title"].asString
|
chapter.name = it.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
chapter.date_upload = parseDate(it["date"].asString)
|
chapter.date_upload = parseDate(it.jsonObject["date"]!!.jsonPrimitive.content)
|
||||||
chapter.setUrlWithoutDomain("/readcomix/" + data["news_id"] + "/" + it["id"] + ".html")
|
chapter.setUrlWithoutDomain("/readcomix/" + data["news_id"] + "/" + it.jsonObject["id"]!!.jsonPrimitive.content + ".html")
|
||||||
chapter
|
chapter
|
||||||
}
|
}
|
||||||
return chapters ?: emptyList()
|
return chapters ?: emptyList()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'MangaLib'
|
extName = 'MangaLib'
|
||||||
|
|
|
@ -5,18 +5,6 @@ import android.content.SharedPreferences
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import com.github.salomonbrys.kotson.array
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.int
|
|
||||||
import com.github.salomonbrys.kotson.nullArray
|
|
||||||
import com.github.salomonbrys.kotson.nullInt
|
|
||||||
import com.github.salomonbrys.kotson.nullString
|
|
||||||
import com.github.salomonbrys.kotson.obj
|
|
||||||
import com.github.salomonbrys.kotson.string
|
|
||||||
import com.github.salomonbrys.kotson.toMap
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonElement
|
|
||||||
import com.google.gson.JsonParser
|
|
||||||
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
|
@ -30,6 +18,17 @@ 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 eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.contentOrNull
|
||||||
|
import kotlinx.serialization.json.int
|
||||||
|
import kotlinx.serialization.json.intOrNull
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
@ -39,12 +38,15 @@ import org.jsoup.nodes.Element
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
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
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class LibManga : ConfigurableSource, HttpSource() {
|
class LibManga : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
private val preferences: SharedPreferences by lazy {
|
private val preferences: SharedPreferences by lazy {
|
||||||
Injekt.get<Application>().getSharedPreferences("source_${id}_2", 0x0000)
|
Injekt.get<Application>().getSharedPreferences("source_${id}_2", 0x0000)
|
||||||
}
|
}
|
||||||
|
@ -72,8 +74,6 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
add("Referer", baseUrl)
|
add("Referer", baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val jsonParser = JsonParser()
|
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers)
|
override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers)
|
||||||
|
|
||||||
private val latestUpdatesSelector = "div.updates__item"
|
private val latestUpdatesSelector = "div.updates__item"
|
||||||
|
@ -135,21 +135,21 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
val resBody = response.body!!.string()
|
val resBody = response.body!!.string()
|
||||||
val result = jsonParser.parse(resBody).obj
|
val result = json.decodeFromString<JsonObject>(resBody)
|
||||||
val items = result["items"]
|
val items = result["items"]!!.jsonObject
|
||||||
val popularMangas = items["data"].nullArray?.map { popularMangaFromElement(it) }
|
val popularMangas = items["data"]?.jsonArray?.map { popularMangaFromElement(it) }
|
||||||
|
|
||||||
if (popularMangas != null) {
|
if (popularMangas != null) {
|
||||||
val hasNextPage = items["next_page_url"].nullString != null
|
val hasNextPage = items["next_page_url"]?.jsonPrimitive?.contentOrNull != null
|
||||||
return MangasPage(popularMangas, hasNextPage)
|
return MangasPage(popularMangas, hasNextPage)
|
||||||
}
|
}
|
||||||
return MangasPage(emptyList(), false)
|
return MangasPage(emptyList(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun popularMangaFromElement(el: JsonElement) = SManga.create().apply {
|
private fun popularMangaFromElement(el: JsonElement) = SManga.create().apply {
|
||||||
val slug = el["slug"].string
|
val slug = el.jsonObject["slug"]!!.jsonPrimitive.content
|
||||||
val cover = el["cover"].string
|
val cover = el.jsonObject["cover"]!!.jsonPrimitive.content
|
||||||
title = if (titleLanguage.equals("rus")) el["rus_name"].string else el["name"].string
|
title = if (titleLanguage.equals("rus")) el.jsonObject["rus_name"]!!.jsonPrimitive.content else el.jsonObject["name"]!!.jsonPrimitive.content
|
||||||
thumbnail_url = "$COVER_URL/uploads/cover/$slug/cover/${cover}_250x350.jpg"
|
thumbnail_url = "$COVER_URL/uploads/cover/$slug/cover/${cover}_250x350.jpg"
|
||||||
url = "/$slug"
|
url = "/$slug"
|
||||||
}
|
}
|
||||||
|
@ -232,17 +232,17 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
.substringBefore("window._SITE_COLOR_")
|
.substringBefore("window._SITE_COLOR_")
|
||||||
.substringBeforeLast(";")
|
.substringBeforeLast(";")
|
||||||
|
|
||||||
val data = jsonParser.parse(dataStr).obj
|
val data = json.decodeFromString<JsonObject>(dataStr)
|
||||||
val chaptersList = data["chapters"]["list"].nullArray
|
val chaptersList = data["chapters"]!!.jsonObject["list"]?.jsonArray
|
||||||
val slug = data["manga"]["slug"].string
|
val slug = data["manga"]!!.jsonObject["slug"]!!.jsonPrimitive.content
|
||||||
val branches = data["chapters"]["branches"].array.reversed()
|
val branches = data["chapters"]!!.jsonObject["branches"]!!.jsonArray.reversed()
|
||||||
val sortingList = preferences.getString(SORTING_PREF, "ms_mixing")
|
val sortingList = preferences.getString(SORTING_PREF, "ms_mixing")
|
||||||
|
|
||||||
val chapters: List<SChapter>? = if (branches.isNotEmpty() && !sortingList.equals("ms_mixing")) {
|
val chapters: List<SChapter>? = if (branches.isNotEmpty() && !sortingList.equals("ms_mixing")) {
|
||||||
sortChaptersByTranslator(sortingList, chaptersList, slug, branches)
|
sortChaptersByTranslator(sortingList, chaptersList, slug, branches)
|
||||||
} else {
|
} else {
|
||||||
chaptersList
|
chaptersList
|
||||||
?.filter { it["status"].nullInt != 2 }
|
?.filter { it.jsonObject["status"]?.jsonPrimitive?.intOrNull != 2 }
|
||||||
?.map { chapterFromElement(it, sortingList, slug) }
|
?.map { chapterFromElement(it, sortingList, slug) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,9 +256,9 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
"ms_combining" -> {
|
"ms_combining" -> {
|
||||||
val tempChaptersList = mutableListOf<SChapter>()
|
val tempChaptersList = mutableListOf<SChapter>()
|
||||||
for (currentBranch in branches.withIndex()) {
|
for (currentBranch in branches.withIndex()) {
|
||||||
val teamId = branches[currentBranch.index]["id"].int
|
val teamId = branches[currentBranch.index].jsonObject["id"]!!.jsonPrimitive.int
|
||||||
chapters = chaptersList
|
chapters = chaptersList
|
||||||
?.filter { it["branch_id"].nullInt == teamId && it["status"].nullInt != 2 }
|
?.filter { it.jsonObject["branch_id"]?.jsonPrimitive?.intOrNull == teamId && it.jsonObject["status"]?.jsonPrimitive?.intOrNull != 2 }
|
||||||
?.map { chapterFromElement(it, sortingList, slug, teamId, branches) }
|
?.map { chapterFromElement(it, sortingList, slug, teamId, branches) }
|
||||||
chapters?.let { tempChaptersList.addAll(it) }
|
chapters?.let { tempChaptersList.addAll(it) }
|
||||||
}
|
}
|
||||||
|
@ -267,26 +267,26 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
"ms_largest" -> {
|
"ms_largest" -> {
|
||||||
val sizesChaptersLists = mutableListOf<Int>()
|
val sizesChaptersLists = mutableListOf<Int>()
|
||||||
for (currentBranch in branches.withIndex()) {
|
for (currentBranch in branches.withIndex()) {
|
||||||
val teamId = branches[currentBranch.index]["id"].int
|
val teamId = branches[currentBranch.index].jsonObject["id"]!!.jsonPrimitive.int
|
||||||
val chapterSize = chaptersList
|
val chapterSize = chaptersList
|
||||||
?.filter { it["branch_id"].nullInt == teamId }!!.size
|
?.filter { it.jsonObject["branch_id"]?.jsonPrimitive?.intOrNull == teamId }!!.size
|
||||||
sizesChaptersLists.add(chapterSize)
|
sizesChaptersLists.add(chapterSize)
|
||||||
}
|
}
|
||||||
val max = sizesChaptersLists.indexOfFirst { it == sizesChaptersLists.maxOrNull() ?: 0 }
|
val max = sizesChaptersLists.indexOfFirst { it == sizesChaptersLists.maxOrNull() ?: 0 }
|
||||||
val teamId = branches[max]["id"].int
|
val teamId = branches[max].jsonObject["id"]!!.jsonPrimitive.int
|
||||||
|
|
||||||
chapters = chaptersList
|
chapters = chaptersList
|
||||||
?.filter { it["branch_id"].nullInt == teamId && it["status"].nullInt != 2 }
|
?.filter { it.jsonObject["branch_id"]?.jsonPrimitive?.intOrNull == teamId && it.jsonObject["status"]?.jsonPrimitive?.intOrNull != 2 }
|
||||||
?.map { chapterFromElement(it, sortingList, slug, teamId, branches) }
|
?.map { chapterFromElement(it, sortingList, slug, teamId, branches) }
|
||||||
}
|
}
|
||||||
"ms_active" -> {
|
"ms_active" -> {
|
||||||
for (currentBranch in branches.withIndex()) {
|
for (currentBranch in branches.withIndex()) {
|
||||||
val teams = branches[currentBranch.index]["teams"].array
|
val teams = branches[currentBranch.index].jsonObject["teams"]!!.jsonArray
|
||||||
for (currentTeam in teams.withIndex()) {
|
for (currentTeam in teams.withIndex()) {
|
||||||
if (teams[currentTeam.index]["is_active"].int == 1) {
|
if (teams[currentTeam.index].jsonObject["is_active"]!!.jsonPrimitive.int == 1) {
|
||||||
val teamId = branches[currentBranch.index]["id"].int
|
val teamId = branches[currentBranch.index].jsonObject["id"]!!.jsonPrimitive.int
|
||||||
chapters = chaptersList
|
chapters = chaptersList
|
||||||
?.filter { it["branch_id"].nullInt == teamId && it["status"].nullInt != 2 }
|
?.filter { it.jsonObject["branch_id"]?.jsonPrimitive?.intOrNull == teamId && it.jsonObject["status"]?.jsonPrimitive?.intOrNull != 2 }
|
||||||
?.map { chapterFromElement(it, sortingList, slug, teamId, branches) }
|
?.map { chapterFromElement(it, sortingList, slug, teamId, branches) }
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -303,23 +303,23 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
(chapterItem: JsonElement, sortingList: String?, slug: String, teamIdParam: Int? = null, branches: List<JsonElement>? = null): SChapter {
|
(chapterItem: JsonElement, sortingList: String?, slug: String, teamIdParam: Int? = null, branches: List<JsonElement>? = null): SChapter {
|
||||||
val chapter = SChapter.create()
|
val chapter = SChapter.create()
|
||||||
|
|
||||||
val volume = chapterItem["chapter_volume"].int
|
val volume = chapterItem.jsonObject["chapter_volume"]!!.jsonPrimitive.int
|
||||||
val number = chapterItem["chapter_number"].string
|
val number = chapterItem.jsonObject["chapter_number"]!!.jsonPrimitive.content
|
||||||
val teamId = if (teamIdParam != null) "?bid=$teamIdParam" else ""
|
val teamId = if (teamIdParam != null) "?bid=$teamIdParam" else ""
|
||||||
|
|
||||||
val url = "$baseUrl/$slug/v$volume/c$number$teamId"
|
val url = "$baseUrl/$slug/v$volume/c$number$teamId"
|
||||||
|
|
||||||
chapter.setUrlWithoutDomain(url)
|
chapter.setUrlWithoutDomain(url)
|
||||||
|
|
||||||
val nameChapter = chapterItem["chapter_name"].nullString
|
val nameChapter = chapterItem.jsonObject["chapter_name"]?.jsonPrimitive?.contentOrNull
|
||||||
val fullNameChapter = "Том $volume. Глава $number"
|
val fullNameChapter = "Том $volume. Глава $number"
|
||||||
|
|
||||||
if (!sortingList.equals("ms_mixing")) {
|
if (!sortingList.equals("ms_mixing")) {
|
||||||
chapter.scanlator = branches?.let { getScanlatorTeamName(it, chapterItem) } ?: chapterItem["username"].string
|
chapter.scanlator = branches?.let { getScanlatorTeamName(it, chapterItem) } ?: chapterItem.jsonObject["username"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
chapter.name = if (nameChapter.isNullOrBlank()) fullNameChapter else "$fullNameChapter - $nameChapter"
|
chapter.name = if (nameChapter.isNullOrBlank()) fullNameChapter else "$fullNameChapter - $nameChapter"
|
||||||
chapter.date_upload = SimpleDateFormat("yyyy-MM-dd", Locale.US)
|
chapter.date_upload = SimpleDateFormat("yyyy-MM-dd", Locale.US)
|
||||||
.parse(chapterItem["chapter_created_at"].string.substringBefore(" "))?.time ?: 0L
|
.parse(chapterItem.jsonObject["chapter_created_at"]!!.jsonPrimitive.content.substringBefore(" "))?.time ?: 0L
|
||||||
|
|
||||||
return chapter
|
return chapter
|
||||||
}
|
}
|
||||||
|
@ -327,15 +327,15 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
private fun getScanlatorTeamName(branches: List<JsonElement>, chapterItem: JsonElement): String? {
|
private fun getScanlatorTeamName(branches: List<JsonElement>, chapterItem: JsonElement): String? {
|
||||||
var scanlatorData: String? = null
|
var scanlatorData: String? = null
|
||||||
for (currentBranch in branches.withIndex()) {
|
for (currentBranch in branches.withIndex()) {
|
||||||
val branch = branches[currentBranch.index]
|
val branch = branches[currentBranch.index].jsonObject
|
||||||
val teams = branch["teams"].array
|
val teams = branch["teams"]!!.jsonArray
|
||||||
if (chapterItem["branch_id"].int == branch["id"].int) {
|
if (chapterItem.jsonObject["branch_id"]!!.jsonPrimitive.int == branch["id"]!!.jsonPrimitive.int) {
|
||||||
for (currentTeam in teams.withIndex()) {
|
for (currentTeam in teams.withIndex()) {
|
||||||
val team = teams[currentTeam.index]
|
val team = teams[currentTeam.index].jsonObject
|
||||||
val scanlatorId = chapterItem["chapter_scanlator_id"].int
|
val scanlatorId = chapterItem.jsonObject["chapter_scanlator_id"]!!.jsonPrimitive.int
|
||||||
scanlatorData = if ((scanlatorId == team["id"].int) ||
|
scanlatorData = if ((scanlatorId == team.jsonObject["id"]!!.jsonPrimitive.int) ||
|
||||||
(scanlatorId == 0 && team["is_active"].int == 1)
|
(scanlatorId == 0 && team["is_active"]!!.jsonPrimitive.int == 1)
|
||||||
) team["name"].string else branch["teams"][0]["name"].string
|
) team["name"]!!.jsonPrimitive.content else branch["teams"]!!.jsonArray[0].jsonObject["name"]!!.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,11 +371,11 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
.split(";")
|
.split(";")
|
||||||
.first()
|
.first()
|
||||||
|
|
||||||
val chapInfoJson = jsonParser.parse(chapInfo).obj
|
val chapInfoJson = json.decodeFromString<JsonObject>(chapInfo)
|
||||||
val servers = chapInfoJson["servers"].asJsonObject.toMap()
|
val servers = chapInfoJson["servers"]!!.jsonObject.toMap()
|
||||||
val defaultServer: String = chapInfoJson["img"]["server"].string
|
val defaultServer: String = chapInfoJson["img"]!!.jsonObject["server"]!!.jsonPrimitive.content
|
||||||
val autoServer = setOf("secondary", "fourth", defaultServer, "compress")
|
val autoServer = setOf("secondary", "fourth", defaultServer, "compress")
|
||||||
val imgUrl: String = chapInfoJson["img"]["url"].string
|
val imgUrl: String = chapInfoJson["img"]!!.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
|
|
||||||
val serverToUse = when (this.server) {
|
val serverToUse = when (this.server) {
|
||||||
null -> autoServer
|
null -> autoServer
|
||||||
|
@ -392,15 +392,15 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
.removePrefix("window.__pg = ")
|
.removePrefix("window.__pg = ")
|
||||||
.removeSuffix(";")
|
.removeSuffix(";")
|
||||||
|
|
||||||
val pagesJson = jsonParser.parse(pagesArr).array
|
val pagesJson = json.decodeFromString<JsonArray>(pagesArr)
|
||||||
val pages = mutableListOf<Page>()
|
val pages = mutableListOf<Page>()
|
||||||
|
|
||||||
pagesJson.forEach { page ->
|
pagesJson.forEach { page ->
|
||||||
val keys = servers.keys.filter { serverToUse.indexOf(it) >= 0 }.sortedBy { serverToUse.indexOf(it) }
|
val keys = servers.keys.filter { serverToUse.indexOf(it) >= 0 }.sortedBy { serverToUse.indexOf(it) }
|
||||||
val serversUrls = keys.map {
|
val serversUrls = keys.map {
|
||||||
servers[it]?.string + imgUrl + page["u"].string
|
servers[it]?.jsonPrimitive?.contentOrNull + imgUrl + page.jsonObject["u"]!!.jsonPrimitive.content
|
||||||
}.joinToString(separator = ",,") { it }
|
}.joinToString(separator = ",,") { it }
|
||||||
pages.add(Page(page["p"].int, serversUrls))
|
pages.add(Page(page.jsonObject["p"]!!.jsonPrimitive.int, serversUrls))
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages
|
return pages
|
||||||
|
@ -523,7 +523,7 @@ class LibManga : ConfigurableSource, HttpSource() {
|
||||||
)
|
)
|
||||||
.execute().body!!.string()
|
.execute().body!!.string()
|
||||||
|
|
||||||
val jsonList = jsonParser.parse(popup).array
|
val jsonList = json.decodeFromString<JsonArray>(popup)
|
||||||
jsonList.forEach {
|
jsonList.forEach {
|
||||||
mangas.add(popularMangaFromElement(it))
|
mangas.add(popularMangaFromElement(it))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'Mangaonlinebiz'
|
extName = 'Mangaonlinebiz'
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.extension.ru.mangaonlinebiz
|
package eu.kanade.tachiyomi.extension.ru.mangaonlinebiz
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.float
|
|
||||||
import com.github.salomonbrys.kotson.forEach
|
|
||||||
import com.github.salomonbrys.kotson.string
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import com.google.gson.JsonParser
|
|
||||||
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
|
||||||
|
@ -13,15 +8,27 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.float
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
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
|
||||||
|
|
||||||
class MangaOnlineBiz : ParsedHttpSource() {
|
class MangaOnlineBiz : ParsedHttpSource() {
|
||||||
|
|
||||||
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override val name = "MangaOnlineBiz"
|
override val name = "MangaOnlineBiz"
|
||||||
|
|
||||||
override val baseUrl = "https://manga-online.biz"
|
override val baseUrl = "https://manga-online.biz"
|
||||||
|
@ -68,15 +75,14 @@ class MangaOnlineBiz : ParsedHttpSource() {
|
||||||
return popularMangaParse(response)
|
return popularMangaParse(response)
|
||||||
}
|
}
|
||||||
val jsonData = response.body!!.string()
|
val jsonData = response.body!!.string()
|
||||||
val json = JsonParser().parse(jsonData).asJsonObject
|
val results = json.decodeFromString<JsonObject>(jsonData)["results"]!!.jsonArray
|
||||||
val results = json.getAsJsonArray("results")
|
|
||||||
val mangas = mutableListOf<SManga>()
|
val mangas = mutableListOf<SManga>()
|
||||||
results.forEach {
|
results.forEach {
|
||||||
val element = it.asJsonObject
|
val element = it.jsonObject
|
||||||
val manga = SManga.create()
|
val manga = SManga.create()
|
||||||
manga.setUrlWithoutDomain(element.get("url").string)
|
manga.setUrlWithoutDomain(element["url"]!!.jsonPrimitive.content)
|
||||||
manga.title = element.get("title").string.split("/").first()
|
manga.title = element["title"]!!.jsonPrimitive.content.split("/").first()
|
||||||
val image = element.get("image").string
|
val image = element["image"]!!.jsonPrimitive.content
|
||||||
if (image.startsWith("http")) {
|
if (image.startsWith("http")) {
|
||||||
manga.thumbnail_url = image
|
manga.thumbnail_url = image
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,10 +136,9 @@ class MangaOnlineBiz : ParsedHttpSource() {
|
||||||
|
|
||||||
val jsonData = html.split("App.Collection.MangaChapter(").last().split("]);").first() + "]"
|
val jsonData = html.split("App.Collection.MangaChapter(").last().split("]);").first() + "]"
|
||||||
val mangaName = html.split("mangaName: '").last().split("' });").first()
|
val mangaName = html.split("mangaName: '").last().split("' });").first()
|
||||||
val json = JsonParser().parse(jsonData).asJsonArray
|
|
||||||
val chapterList = mutableListOf<SChapter>()
|
val chapterList = mutableListOf<SChapter>()
|
||||||
json.forEach {
|
json.decodeFromString<JsonArray>(jsonData).forEach {
|
||||||
chapterList.add(chapterFromElement(mangaName, it.asJsonObject))
|
chapterList.add(chapterFromElement(mangaName, it.jsonObject))
|
||||||
}
|
}
|
||||||
return chapterList
|
return chapterList
|
||||||
}
|
}
|
||||||
|
@ -142,22 +147,22 @@ class MangaOnlineBiz : ParsedHttpSource() {
|
||||||
|
|
||||||
private fun chapterFromElement(mangaName: String, element: JsonObject): SChapter {
|
private fun chapterFromElement(mangaName: String, element: JsonObject): SChapter {
|
||||||
val chapter = SChapter.create()
|
val chapter = SChapter.create()
|
||||||
chapter.setUrlWithoutDomain("/$mangaName/${element.get("volume").string}/${element.get("number").string})/1")
|
chapter.setUrlWithoutDomain("/$mangaName/${element["volume"]!!.jsonPrimitive.content}/${element["number"]!!.jsonPrimitive.content})/1")
|
||||||
chapter.name = "Том ${element.get("volume").string} - Глава ${element.get("number").string} ${element.get("title").string}"
|
chapter.name = "Том ${element["volume"]!!.jsonPrimitive.content} - Глава ${element["number"]!!.jsonPrimitive.content} ${element["title"]!!.jsonPrimitive.content}"
|
||||||
chapter.chapter_number = element.get("number").float
|
chapter.chapter_number = element["number"]!!.jsonPrimitive.float
|
||||||
chapter.date_upload = SimpleDateFormat("yyyy-MM-dd", Locale.US).parse(element.get("date").string)?.time ?: 0L
|
chapter.date_upload = SimpleDateFormat("yyyy-MM-dd", Locale.US).parse(element["date"]!!.jsonPrimitive.content)?.time ?: 0L
|
||||||
return chapter
|
return chapter
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val html = response.body!!.string()
|
val html = response.body!!.string()
|
||||||
val jsonData = html.split("new App.Router.Chapter(").last().split("});").first() + "}"
|
val jsonData = html.split("new App.Router.Chapter(").last().split("});").first() + "}"
|
||||||
val json = JsonParser().parse(jsonData).asJsonObject
|
val jsonObj = json.decodeFromString<JsonObject>(jsonData)
|
||||||
val cdnUrl = json.get("srcBaseUrl").string
|
val cdnUrl = jsonObj["srcBaseUrl"]!!.jsonPrimitive.content
|
||||||
val pages = json.get("pages").asJsonObject
|
val pages = jsonObj["pages"]!!.jsonObject
|
||||||
val resPages = mutableListOf<Page>()
|
val resPages = mutableListOf<Page>()
|
||||||
pages.forEach { page, jsonElement ->
|
pages.entries.forEach { (page, jsonElement) ->
|
||||||
resPages.add(Page(page.toInt(), imageUrl = "$cdnUrl/${jsonElement.asJsonObject.get("src").string}"))
|
resPages.add(Page(page.toInt(), imageUrl = "$cdnUrl/${jsonElement.jsonObject["src"]!!.jsonPrimitive.content}"))
|
||||||
}
|
}
|
||||||
return resPages
|
return resPages
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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 = 'Risens Team'
|
extName = 'Risens Team'
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.extension.ru.risensteam
|
package eu.kanade.tachiyomi.extension.ru.risensteam
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import com.github.salomonbrys.kotson.int
|
|
||||||
import com.github.salomonbrys.kotson.nullString
|
|
||||||
import com.github.salomonbrys.kotson.string
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonElement
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
|
@ -18,11 +9,22 @@ 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.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.contentOrNull
|
||||||
|
import kotlinx.serialization.json.int
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -39,7 +41,7 @@ class RisensTeam : HttpSource() {
|
||||||
|
|
||||||
override val versionId: Int = 2
|
override val versionId: Int = 2
|
||||||
|
|
||||||
private val gson by lazy { Gson() }
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
// Popular (source only returns manga sorted by latest)
|
// Popular (source only returns manga sorted by latest)
|
||||||
|
|
||||||
|
@ -49,16 +51,16 @@ class RisensTeam : HttpSource() {
|
||||||
|
|
||||||
private fun mangaFromJson(json: JsonElement): SManga {
|
private fun mangaFromJson(json: JsonElement): SManga {
|
||||||
return SManga.create().apply {
|
return SManga.create().apply {
|
||||||
url = "${json["id"].int}/${json["furl"].string}"
|
url = "${json.jsonObject["id"]!!.jsonPrimitive.int}/${json.jsonObject["furl"]!!.jsonPrimitive.content}"
|
||||||
title = json["title"].string
|
title = json.jsonObject["title"]!!.jsonPrimitive.content
|
||||||
thumbnail_url = baseUrl + json["poster"].string
|
thumbnail_url = baseUrl + json.jsonObject["poster"]!!.jsonPrimitive.content
|
||||||
description = json["description"].nullString
|
description = json.jsonObject["description"]!!.jsonPrimitive.contentOrNull
|
||||||
status = try { if (json["active"].int == 1) SManga.ONGOING else SManga.UNKNOWN } catch (_: Exception) { SManga.UNKNOWN }
|
status = try { if (json.jsonObject["active"]!!.jsonPrimitive.int == 1) SManga.ONGOING else SManga.UNKNOWN } catch (_: Exception) { SManga.UNKNOWN }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
val mangas = gson.fromJson<JsonArray>(response.body!!.string())
|
val mangas = json.decodeFromString<JsonArray>(response.body!!.string())
|
||||||
.map { json -> mangaFromJson(json) }
|
.map { json -> mangaFromJson(json) }
|
||||||
|
|
||||||
return MangasPage(mangas, false)
|
return MangasPage(mangas, false)
|
||||||
|
@ -98,7 +100,7 @@ class RisensTeam : HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
return mangaFromJson(gson.fromJson<JsonObject>(response.body!!.string()))
|
return mangaFromJson(json.decodeFromString<JsonObject>(response.body!!.string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chapters
|
// Chapters
|
||||||
|
@ -106,11 +108,11 @@ class RisensTeam : HttpSource() {
|
||||||
override fun chapterListRequest(manga: SManga): Request = apiMangaDetailsRequest(manga)
|
override fun chapterListRequest(manga: SManga): Request = apiMangaDetailsRequest(manga)
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
return gson.fromJson<JsonObject>(response.body!!.string())["entities"].asJsonArray.map { json ->
|
return json.decodeFromString<JsonObject>(response.body!!.string())["entities"]!!.jsonArray.map { json ->
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
url = json["id"].int.toString()
|
url = json.jsonObject["id"]!!.jsonPrimitive.int.toString()
|
||||||
name = listOfNotNull(json["label"].nullString, json["name"].nullString).joinToString(" - ")
|
name = listOfNotNull(json.jsonObject["label"]!!.jsonPrimitive.contentOrNull, json.jsonObject["name"]!!.jsonPrimitive.contentOrNull).joinToString(" - ")
|
||||||
date_upload = json["updated_at"].toDate()
|
date_upload = json.jsonObject["updated_at"]!!.toDate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +122,7 @@ class RisensTeam : HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JsonElement.toDate(): Long {
|
private fun JsonElement.toDate(): Long {
|
||||||
val date = this.nullString ?: return 0
|
val date = this.jsonPrimitive.contentOrNull ?: return 0
|
||||||
return try {
|
return try {
|
||||||
simpleDateFormat.parse(date)?.time ?: 0
|
simpleDateFormat.parse(date)?.time ?: 0
|
||||||
} catch (e: ParseException) {
|
} catch (e: ParseException) {
|
||||||
|
@ -135,8 +137,8 @@ class RisensTeam : HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
return gson.fromJson<JsonArray>(response.body!!.string())
|
return json.decodeFromString<JsonArray>(response.body!!.string())
|
||||||
.mapIndexed { i, json -> Page(i, "", json.string) }
|
.mapIndexed { i, json -> Page(i, "", json.jsonPrimitive.content) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
|
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
package eu.kanade.tachiyomi.extension.th.nekopost.model
|
package eu.kanade.tachiyomi.extension.th.nekopost.model
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class RawProjectChapter(
|
data class RawProjectChapter(
|
||||||
@SerializedName("cu_displayname")
|
@SerialName("cu_displayname")
|
||||||
val cuDisplayname: String,
|
val cuDisplayname: String,
|
||||||
@SerializedName("nc_chapter_id")
|
@SerialName("nc_chapter_id")
|
||||||
val ncChapterId: String,
|
val ncChapterId: String,
|
||||||
@SerializedName("nc_chapter_name")
|
@SerialName("nc_chapter_name")
|
||||||
val ncChapterName: String,
|
val ncChapterName: String,
|
||||||
@SerializedName("nc_chapter_no")
|
@SerialName("nc_chapter_no")
|
||||||
val ncChapterNo: String,
|
val ncChapterNo: String,
|
||||||
@SerializedName("nc_created_date")
|
@SerialName("nc_created_date")
|
||||||
val ncCreatedDate: String,
|
val ncCreatedDate: String,
|
||||||
@SerializedName("nc_data_file")
|
@SerialName("nc_data_file")
|
||||||
val ncDataFile: String,
|
val ncDataFile: String,
|
||||||
@SerializedName("nc_owner_id")
|
@SerialName("nc_owner_id")
|
||||||
val ncOwnerId: String,
|
val ncOwnerId: String,
|
||||||
@SerializedName("nc_provider")
|
@SerialName("nc_provider")
|
||||||
val ncProvider: String
|
val ncProvider: String
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
package eu.kanade.tachiyomi.extension.th.nekopost.model
|
package eu.kanade.tachiyomi.extension.th.nekopost.model
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class RawProjectInfoData(
|
data class RawProjectInfoData(
|
||||||
@SerializedName("artist_name")
|
@SerialName("artist_name")
|
||||||
val artistName: String,
|
val artistName: String,
|
||||||
@SerializedName("author_name")
|
@SerialName("author_name")
|
||||||
val authorName: String,
|
val authorName: String,
|
||||||
@SerializedName("np_comment")
|
@SerialName("np_comment")
|
||||||
val npComment: String,
|
val npComment: String,
|
||||||
@SerializedName("np_created_date")
|
@SerialName("np_created_date")
|
||||||
val npCreatedDate: String,
|
val npCreatedDate: String,
|
||||||
@SerializedName("np_flag_mature")
|
@SerialName("np_flag_mature")
|
||||||
val npFlagMature: String,
|
val npFlagMature: String,
|
||||||
@SerializedName("np_info")
|
@SerialName("np_info")
|
||||||
val npInfo: String,
|
val npInfo: String,
|
||||||
@SerializedName("np_licenced_by")
|
@SerialName("np_licenced_by")
|
||||||
val npLicencedBy: String,
|
val npLicencedBy: String,
|
||||||
@SerializedName("np_name")
|
@SerialName("np_name")
|
||||||
val npName: String,
|
val npName: String,
|
||||||
@SerializedName("np_name_link")
|
@SerialName("np_name_link")
|
||||||
val npNameLink: String,
|
val npNameLink: String,
|
||||||
@SerializedName("np_project_id")
|
@SerialName("np_project_id")
|
||||||
val npProjectId: String,
|
val npProjectId: String,
|
||||||
@SerializedName("np_status")
|
@SerialName("np_status")
|
||||||
val npStatus: String,
|
val npStatus: String,
|
||||||
@SerializedName("np_type")
|
@SerialName("np_type")
|
||||||
val npType: String,
|
val npType: String,
|
||||||
@SerializedName("np_updated_date")
|
@SerialName("np_updated_date")
|
||||||
val npUpdatedDate: String,
|
val npUpdatedDate: String,
|
||||||
@SerializedName("np_view")
|
@SerialName("np_view")
|
||||||
val npView: String,
|
val npView: String,
|
||||||
@SerializedName("np_web")
|
@SerialName("np_web")
|
||||||
val npWeb: String
|
val npWeb: String
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue