parent
d83c178465
commit
1a0e173779
@ -5,8 +5,7 @@ ext {
|
|||||||
appName = 'Tachiyomi: Arc-Relight'
|
appName = 'Tachiyomi: Arc-Relight'
|
||||||
pkgNameSuffix = 'en.arcrelight'
|
pkgNameSuffix = 'en.arcrelight'
|
||||||
extClass = '.ArcRelight'
|
extClass = '.ArcRelight'
|
||||||
extVersionCode = 1
|
extVersionCode = 2
|
||||||
extVersionSuffix = 1
|
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,20 +7,21 @@ private val STATUSES = arrayOf("Any", "Completed", "Ongoing")
|
|||||||
|
|
||||||
/** List containing the possible categories of a manga */
|
/** List containing the possible categories of a manga */
|
||||||
private val CATEGORIES = listOf(
|
private val CATEGORIES = listOf(
|
||||||
Category("4-Koma"),
|
Category("4-Koma"),
|
||||||
Category("Chaos;Head"),
|
Category("Chaos;Head"),
|
||||||
Category("Comedy"),
|
Category("Collection"),
|
||||||
Category("Drama"),
|
Category("Comedy"),
|
||||||
Category("Mystery"),
|
Category("Drama"),
|
||||||
Category("Psychological"),
|
Category("Mystery"),
|
||||||
Category("Robotics;Notes"),
|
Category("Psychological"),
|
||||||
Category("Romance"),
|
Category("Robotics;Notes"),
|
||||||
Category("Sci-Fi"),
|
Category("Romance"),
|
||||||
Category("Seinen"),
|
Category("Sci-Fi"),
|
||||||
Category("Shounen"),
|
Category("Seinen"),
|
||||||
Category("Steins;Gate"),
|
Category("Shounen"),
|
||||||
Category("Supernatural"),
|
Category("Steins;Gate"),
|
||||||
Category("Tragedy")
|
Category("Supernatural"),
|
||||||
|
Category("Tragedy")
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,7 +42,7 @@ class Status : Filter.Select<String>("Status", STATUSES) {
|
|||||||
*/
|
*/
|
||||||
class Category(name: String) : Filter.TriState(name) {
|
class Category(name: String) : Filter.TriState(name) {
|
||||||
/** Returns the [state] as a string, or null if [isIgnored]. */
|
/** Returns the [state] as a string, or null if [isIgnored]. */
|
||||||
fun stringOpt() = when(state) {
|
fun optString() = when (state) {
|
||||||
STATE_INCLUDE -> name.toLowerCase()
|
STATE_INCLUDE -> name.toLowerCase()
|
||||||
STATE_EXCLUDE -> "-" + name.toLowerCase()
|
STATE_EXCLUDE -> "-" + name.toLowerCase()
|
||||||
else -> null
|
else -> null
|
||||||
|
@ -4,7 +4,6 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
|||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@ -74,14 +73,12 @@ fun SManga.fromJSON(obj: JSONObject) {
|
|||||||
*/
|
*/
|
||||||
fun SChapter.fromJSON(obj: JSONObject) {
|
fun SChapter.fromJSON(obj: JSONObject) {
|
||||||
url = obj.getString("url")
|
url = obj.getString("url")
|
||||||
chapter_number = obj.getString("chapter").toFloat()
|
chapter_number = obj.optString("chapter", "0").toFloat()
|
||||||
date_upload = httpDateToTimestamp(obj.getString("date"))
|
date_upload = httpDateToTimestamp(obj.getString("date"))
|
||||||
scanlator = obj.getJSONArray("groups")?.joinField("name", " & ")
|
scanlator = obj.getJSONArray("groups")?.joinField("name", " & ")
|
||||||
val vol = obj.getString("volume")
|
|
||||||
val ch = DecimalFormat("0.#").format(chapter_number)
|
|
||||||
name = buildString {
|
name = buildString {
|
||||||
if (vol != "0") append("Vol.$vol ")
|
obj.optInt("volume").let { if (it != 0) append("Vol.$it ") }
|
||||||
append("Ch.$ch - ")
|
append("Ch.${DecimalFormat("#.#").format(chapter_number)} - ")
|
||||||
append(obj.getString("title"))
|
append(obj.getString("title"))
|
||||||
if (obj.getBoolean("final")) append(" [END]")
|
if (obj.getBoolean("final")) append(" [END]")
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,17 @@ import android.net.Uri
|
|||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import eu.kanade.tachiyomi.extension.BuildConfig
|
import eu.kanade.tachiyomi.extension.BuildConfig
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.source.model.*
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
/** Arc-Relight source */
|
/** Arc-Relight source */
|
||||||
class ArcRelight : HttpSource() {
|
class ArcRelight : HttpSource() {
|
||||||
@ -29,8 +33,8 @@ class ArcRelight : HttpSource() {
|
|||||||
* Includes the user's Android version
|
* Includes the user's Android version
|
||||||
* and the current extension version.
|
* and the current extension version.
|
||||||
*/
|
*/
|
||||||
private val userAgent = "Mozilla/5.0 (" +
|
private val userAgent = "Mozilla/5.0 " +
|
||||||
"Android ${VERSION.RELEASE}; Mobile) " +
|
"(Android ${VERSION.RELEASE}; Mobile) " +
|
||||||
"Tachiyomi/${BuildConfig.VERSION_NAME}"
|
"Tachiyomi/${BuildConfig.VERSION_NAME}"
|
||||||
|
|
||||||
override fun headersBuilder() = Headers.Builder().apply {
|
override fun headersBuilder() = Headers.Builder().apply {
|
||||||
@ -38,19 +42,28 @@ class ArcRelight : HttpSource() {
|
|||||||
add("Referer", baseUrl)
|
add("Referer", baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int) =
|
override fun latestUpdatesRequest(page: Int) = GET(
|
||||||
GET("$baseUrl/releases/", headers)
|
"$baseUrl/releases/", headers
|
||||||
|
)
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter) =
|
override fun pageListRequest(chapter: SChapter) = GET(
|
||||||
GET(Uri.parse(chapter.url).path.replace(
|
"$baseUrl/series/${chapter.url.substringAfter("/reader/")}", headers
|
||||||
"/reader/", "$baseUrl/series/"), headers)
|
)
|
||||||
|
|
||||||
override fun mangaDetailsRequest(manga: SManga) =
|
override fun chapterListRequest(manga: SManga) = GET(
|
||||||
GET("$baseUrl/series/${manga.url.split("/")
|
"$baseUrl/series/${Uri.parse(manga.url).lastPathSegment}/", headers
|
||||||
.last { it != "" }}/", headers)
|
)
|
||||||
|
|
||||||
override fun chapterListRequest(manga: SManga) =
|
override fun mangaDetailsRequest(manga: SManga): Request {
|
||||||
mangaDetailsRequest(manga)
|
// Workaround to get the proper URL in openInBrowser
|
||||||
|
val method = Thread.currentThread()
|
||||||
|
.stackTrace.getOrNull(2)?.methodName ?: ""
|
||||||
|
return if (method == "openInBrowser") {
|
||||||
|
GET(manga.url, headers)
|
||||||
|
} else {
|
||||||
|
chapterListRequest(manga)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String,
|
override fun searchMangaRequest(page: Int, query: String,
|
||||||
filters: FilterList): Request {
|
filters: FilterList): Request {
|
||||||
@ -61,8 +74,8 @@ class ArcRelight : HttpSource() {
|
|||||||
when (it) {
|
when (it) {
|
||||||
is Person -> uri.appendQueryParameter("author", it.state)
|
is Person -> uri.appendQueryParameter("author", it.state)
|
||||||
is Status -> uri.appendQueryParameter("status", it.string())
|
is Status -> uri.appendQueryParameter("status", it.string())
|
||||||
is CategoryList -> cat.addAll(it.state.mapNotNull {
|
is CategoryList -> cat.addAll(it.state.mapNotNull { c ->
|
||||||
c -> Uri.encode(c.stringOpt())
|
Uri.encode(c.optString())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,16 +84,20 @@ class ArcRelight : HttpSource() {
|
|||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||||
val arr = JSONArray(response.body()!!.string())
|
val arr = JSONArray(response.body()!!.string())
|
||||||
val ret = ArrayList<SManga>(arr.length())
|
val ret = mutableListOf<SManga>()
|
||||||
for (i in 0 until arr.length()) {
|
for (i in 0 until arr.length()) {
|
||||||
val obj = arr.getJSONObject(i)
|
val obj = arr.getJSONObject(i)
|
||||||
ret.add(SManga.create().apply {
|
ret.add(SManga.create().apply {
|
||||||
url = obj.getString("url")
|
url = obj.getString("url")
|
||||||
title = obj.getString("title")
|
title = obj.getString("title")
|
||||||
thumbnail_url = obj.getString("cover")
|
thumbnail_url = obj.getString("cover")
|
||||||
|
// A bit of a hack to sort by date
|
||||||
|
description = httpDateToTimestamp(
|
||||||
|
obj.getJSONObject("latest_chapter").getString("date")
|
||||||
|
).toString()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return MangasPage(ret, false)
|
return MangasPage(ret.sortedByDescending { it.description }, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
@ -90,19 +107,19 @@ class ArcRelight : HttpSource() {
|
|||||||
volumes.keys().forEach { vol ->
|
volumes.keys().forEach { vol ->
|
||||||
val chapters = volumes.getJSONObject(vol)
|
val chapters = volumes.getJSONObject(vol)
|
||||||
chapters.keys().forEach { ch ->
|
chapters.keys().forEach { ch ->
|
||||||
val obj = chapters.getJSONObject(ch)
|
ret.add(SChapter.create().apply {
|
||||||
obj.put("chapter", ch)
|
fromJSON(chapters.getJSONObject(ch).also {
|
||||||
obj.put("volume", vol)
|
it.put("volume", vol)
|
||||||
ret.add(SChapter.create().apply { fromJSON(obj) })
|
it.put("chapter", ch)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret.sortedByDescending { it.name }
|
return ret.sortedByDescending { it.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response) =
|
override fun mangaDetailsParse(response: Response) = SManga.create()
|
||||||
SManga.create().apply {
|
.apply { fromJSON(JSONObject(response.body()!!.string())) }
|
||||||
fromJSON(JSONObject(response.body()!!.string()))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val obj = JSONObject(response.body()!!.string())
|
val obj = JSONObject(response.body()!!.string())
|
||||||
@ -128,7 +145,7 @@ class ArcRelight : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
override fun getFilterList() = FilterList(
|
||||||
Person(), Status(), CategoryList()
|
Person(), Status(), CategoryList()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun fetchPopularManga(page: Int) =
|
override fun fetchPopularManga(page: Int) =
|
||||||
@ -136,14 +153,17 @@ class ArcRelight : HttpSource() {
|
|||||||
|
|
||||||
override fun popularMangaRequest(page: Int) =
|
override fun popularMangaRequest(page: Int) =
|
||||||
throw UnsupportedOperationException(
|
throw UnsupportedOperationException(
|
||||||
"This method should not be called!")
|
"This method should not be called!"
|
||||||
|
)
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response) =
|
override fun popularMangaParse(response: Response) =
|
||||||
throw UnsupportedOperationException(
|
throw UnsupportedOperationException(
|
||||||
"This method should not be called!")
|
"This method should not be called!"
|
||||||
|
)
|
||||||
|
|
||||||
override fun imageUrlParse(response: Response) =
|
override fun imageUrlParse(response: Response) =
|
||||||
throw UnsupportedOperationException(
|
throw UnsupportedOperationException(
|
||||||
"This method should not be called!")
|
"This method should not be called!"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user