Add Assorted Scans to MangAdventure (#7450)
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 39 KiB |
|
@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.multisrc.mangadventure.MangAdventure
|
|||
class ArcRelight : MangAdventure(
|
||||
"Arc-Relight",
|
||||
"https://arc-relight.com",
|
||||
listOf(
|
||||
categories = listOf(
|
||||
"4-Koma",
|
||||
"Chaos;Head",
|
||||
"Collection",
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="eu.kanade.tachiyomi.extension">
|
||||
<application>
|
||||
<activity android:name="eu.kanade.tachiyomi.multisrc.mangadventure.MangAdventureActivity"
|
||||
android:theme="@android:style/Theme.NoDisplay"
|
||||
android:excludeFromRecents="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<data android:host="assortedscans.com"
|
||||
android:pathPattern="/reader/..*"
|
||||
android:scheme="https"/>
|
||||
<data android:host="www.assortedscans.com"
|
||||
android:pathPattern="/reader/..*"
|
||||
android:scheme="https"/>
|
||||
<data android:host="helveticascans.com"
|
||||
android:pathPattern="/reader/..*"
|
||||
android:scheme="https"/>
|
||||
<data android:host="www.helveticascans.com"
|
||||
android:pathPattern="/reader/..*"
|
||||
android:scheme="https"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 34 KiB |
|
@ -34,13 +34,12 @@ import java.util.Locale
|
|||
abstract class MangAdventure(
|
||||
override val name: String,
|
||||
override val baseUrl: String,
|
||||
override val lang: String = "en",
|
||||
val categories: List<String> = DEFAULT_CATEGORIES
|
||||
) : HttpSource() {
|
||||
|
||||
override val versionId = 1
|
||||
|
||||
override val lang = "en"
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
/** The full URL to the site's API. */
|
||||
|
@ -55,13 +54,13 @@ abstract class MangAdventure(
|
|||
"(Android ${VERSION.RELEASE}; Mobile) " +
|
||||
"Tachiyomi/${BuildConfig.VERSION_NAME}"
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
override fun headersBuilder() = Headers.Builder().apply {
|
||||
add("User-Agent", userAgent)
|
||||
add("Referer", baseUrl)
|
||||
}
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) =
|
||||
GET("$apiUrl/releases/", headers)
|
||||
|
||||
|
@ -107,59 +106,59 @@ abstract class MangAdventure(
|
|||
}
|
||||
|
||||
override fun latestUpdatesParse(response: Response) =
|
||||
json.parseToJsonElement(response.asString()).jsonArray.run {
|
||||
MangasPage(
|
||||
map {
|
||||
val obj = it.jsonObject
|
||||
SManga.create().apply {
|
||||
url = obj["url"]!!.jsonPrimitive.content
|
||||
title = obj["title"]!!.jsonPrimitive.content
|
||||
thumbnail_url = obj["cover"]!!.jsonPrimitive.content
|
||||
description = httpDateToTimestamp(
|
||||
obj["latest_chapter"]!!.jsonObject["date"]!!.jsonPrimitive.content
|
||||
).toString()
|
||||
}
|
||||
json.parseToJsonElement(response.body!!.string()).run {
|
||||
MangasPage(jsonArray.map {
|
||||
val obj = it.jsonObject
|
||||
SManga.create().apply {
|
||||
url = obj["url"]!!.jsonPrimitive.content
|
||||
title = obj["title"]!!.jsonPrimitive.content
|
||||
thumbnail_url = obj["cover"]!!.jsonPrimitive.content
|
||||
// A bit of a hack to sort by date
|
||||
val latest = obj["latest_chapter"]!!.jsonObject
|
||||
description = httpDateToTimestamp(
|
||||
latest["date"]!!.jsonPrimitive.content
|
||||
).toString()
|
||||
}
|
||||
.sortedByDescending(SManga::description),
|
||||
false
|
||||
)
|
||||
}.sortedByDescending(SManga::description), false)
|
||||
}
|
||||
|
||||
override fun chapterListParse(response: Response) =
|
||||
json.parseToJsonElement(response.asString()).jsonObject["volumes"]!!.jsonObject.entries
|
||||
.reversed()
|
||||
.flatMap { vol ->
|
||||
json.parseToJsonElement(response.body!!.string())
|
||||
.jsonObject["volumes"]!!.jsonObject.entries.flatMap { vol ->
|
||||
vol.value.jsonObject.entries.map { ch ->
|
||||
SChapter.create().fromJSON(
|
||||
ch.value.jsonObject.toMutableMap().let {
|
||||
SChapter.create().fromJSON(JsonObject(
|
||||
ch.value.jsonObject.toMutableMap().also {
|
||||
it["volume"] = JsonPrimitive(vol.key)
|
||||
it["chapter"] = JsonPrimitive(ch.key)
|
||||
|
||||
JsonObject(it)
|
||||
}
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
override fun mangaDetailsParse(response: Response) =
|
||||
SManga.create().fromJSON(json.parseToJsonElement(response.asString()).jsonObject)
|
||||
SManga.create().fromJSON(
|
||||
json.parseToJsonElement(response.body!!.string()).jsonObject
|
||||
)
|
||||
|
||||
override fun pageListParse(response: Response) =
|
||||
json.parseToJsonElement(response.asString()).jsonObject.run {
|
||||
json.parseToJsonElement(response.body!!.string()).jsonObject.run {
|
||||
val url = get("url")!!.jsonPrimitive.content
|
||||
val root = get("pages_root")!!.jsonPrimitive.content
|
||||
|
||||
get("pages_list")!!.jsonArray.mapIndexed { i, jsonEl ->
|
||||
Page(i, "$url${i + 1}", "$root${jsonEl.jsonPrimitive.content}")
|
||||
get("pages_list")!!.jsonArray.mapIndexed { i, e ->
|
||||
Page(i, "$url${i + 1}", "$root${e.jsonPrimitive.content}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun searchMangaParse(response: Response) =
|
||||
json.parseToJsonElement(response.asString()).jsonArray.run {
|
||||
MangasPage(
|
||||
map { SManga.create().fromJSON(it.jsonObject) },
|
||||
false
|
||||
)
|
||||
json.parseToJsonElement(response.body!!.string()).run {
|
||||
MangasPage(jsonArray.map {
|
||||
val obj = it.jsonObject
|
||||
SManga.create().apply {
|
||||
url = obj["url"]!!.jsonPrimitive.content
|
||||
title = obj["title"]!!.jsonPrimitive.content
|
||||
thumbnail_url = obj["cover"]!!.jsonPrimitive.content
|
||||
}
|
||||
}.sortedBy(SManga::title), false)
|
||||
}
|
||||
|
||||
override fun getFilterList() =
|
||||
|
@ -250,7 +249,7 @@ abstract class MangAdventure(
|
|||
*/
|
||||
inner class Status : Filter.Select<String>("Status", STATUSES) {
|
||||
/** Returns the [state] as a string. */
|
||||
fun string() = values[state].toLowerCase(Locale.ENGLISH)
|
||||
fun string() = values[state].toLowerCase(Locale(lang))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,12 +11,8 @@ import kotlinx.serialization.json.intOrNull
|
|||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import okhttp3.Response
|
||||
import java.text.DecimalFormat
|
||||
|
||||
/** Returns the body of a response as a `String`. */
|
||||
fun Response.asString(): String = body!!.string()
|
||||
|
||||
/**
|
||||
* Formats the number according to [fmt].
|
||||
*
|
||||
|
@ -29,7 +25,6 @@ fun Number.format(fmt: String): String = DecimalFormat(fmt).format(this)
|
|||
* Joins each value of a given [field] of the array using [sep].
|
||||
*
|
||||
* @param field The index of a [JsonArray].
|
||||
* When its type is [String], it is treated as the key of a [JsonObject].
|
||||
* @param sep The separator used to join the array.
|
||||
* @return The joined string, or `null` if the array is empty.
|
||||
*/
|
||||
|
@ -41,7 +36,7 @@ fun JsonArray.joinField(field: Int, sep: String = ", ") =
|
|||
/**
|
||||
* Joins each value of a given [field] of the array using [sep].
|
||||
*
|
||||
* @param field The key of a [JSONObject].
|
||||
* @param field The key of a [JsonObject].
|
||||
* @param sep The separator used to join the array.
|
||||
* @return The joined string, or `null` if the array is empty.
|
||||
*/
|
||||
|
@ -76,20 +71,23 @@ val SChapter.path: String
|
|||
get() = url.substringAfter("/reader/")
|
||||
|
||||
/**
|
||||
* Creates a [SChapter] by parsing a [JSONObject].
|
||||
* Creates a [SChapter] by parsing a [JsonObject].
|
||||
*
|
||||
* @param obj The object containing the chapter info.
|
||||
*/
|
||||
fun SChapter.fromJSON(obj: JsonObject) = apply {
|
||||
url = obj["url"]!!.jsonPrimitive.content
|
||||
chapter_number = obj["chapter"]?.jsonPrimitive?.content?.toFloatOrNull() ?: -1f
|
||||
date_upload = MangAdventure.httpDateToTimestamp(obj["date"]!!.jsonPrimitive.content)
|
||||
chapter_number = obj["chapter"]?.jsonPrimitive?.content?.toFloat() ?: -1f
|
||||
date_upload = MangAdventure.httpDateToTimestamp(
|
||||
obj["date"]!!.jsonPrimitive.content
|
||||
)
|
||||
scanlator = obj["groups"]!!.jsonArray.joinField("name", " & ")
|
||||
name = obj["full_title"]?.jsonPrimitive?.contentOrNull
|
||||
?: buildString {
|
||||
obj["volume"]?.jsonPrimitive?.intOrNull?.let { if (it != 0) append("Vol. $it, ") }
|
||||
append("Ch. ${chapter_number.format("#.#")}: ")
|
||||
append(obj["title"]!!.jsonPrimitive.content)
|
||||
name = obj["full_title"]?.jsonPrimitive?.contentOrNull ?: buildString {
|
||||
obj["volume"]?.jsonPrimitive?.intOrNull?.let {
|
||||
if (it != 0) append("Vol. $it, ")
|
||||
}
|
||||
append("Ch. ${chapter_number.format("#.#")}: ")
|
||||
append(obj["title"]!!.jsonPrimitive.content)
|
||||
}
|
||||
if (obj["final"]!!.jsonPrimitive.boolean) name += " [END]"
|
||||
}
|
||||
|
|
|
@ -9,10 +9,11 @@ class MangAdventureGenerator : ThemeSourceGenerator {
|
|||
|
||||
override val themeClass = "MangAdventure"
|
||||
|
||||
override val baseVersionCode = 2
|
||||
override val baseVersionCode = 3
|
||||
|
||||
override val sources = listOf(
|
||||
SingleLang("Arc-Relight", "https://arc-relight.com", "en", className = "ArcRelight"),
|
||||
SingleLang("Assorted Scans", "https://assortedscans.com", "en"),
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
|