OlympusScanlation: Use site bookmarks to update manga url (#8429)
* use bookmarks * bump * use slugmap * change message * fixes
This commit is contained in:
parent
7586d7ff61
commit
2dee930bbf
src/es/olympusscanlation
build.gradle
src/eu/kanade/tachiyomi/extension/es/olympusscanlation
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Olympus Scanlation'
|
extName = 'Olympus Scanlation'
|
||||||
extClass = '.OlympusScanlation'
|
extClass = '.OlympusScanlation'
|
||||||
extVersionCode = 15
|
extVersionCode = 16
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
236
src/es/olympusscanlation/src/eu/kanade/tachiyomi/extension/es/olympusscanlation/OlympusScanlation.kt
236
src/es/olympusscanlation/src/eu/kanade/tachiyomi/extension/es/olympusscanlation/OlympusScanlation.kt
@ -2,9 +2,9 @@ package eu.kanade.tachiyomi.extension.es.olympusscanlation
|
|||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.preference.CheckBoxPreference
|
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
|
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
@ -17,12 +17,12 @@ 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 keiyoushi.utils.getPreferences
|
import keiyoushi.utils.getPreferences
|
||||||
import kotlinx.serialization.decodeFromString
|
import keiyoushi.utils.parseAs
|
||||||
import kotlinx.serialization.json.Json
|
import keiyoushi.utils.toJsonString
|
||||||
|
import kotlinx.serialization.SerializationException
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.TimeZone
|
import java.util.TimeZone
|
||||||
@ -31,7 +31,7 @@ import kotlin.math.min
|
|||||||
|
|
||||||
class OlympusScanlation : HttpSource(), ConfigurableSource {
|
class OlympusScanlation : HttpSource(), ConfigurableSource {
|
||||||
|
|
||||||
override val versionId = 2
|
override val versionId = 3
|
||||||
private val isCi = System.getenv("CI") == "true"
|
private val isCi = System.getenv("CI") == "true"
|
||||||
|
|
||||||
override val baseUrl: String get() = when {
|
override val baseUrl: String get() = when {
|
||||||
@ -67,16 +67,30 @@ class OlympusScanlation : HttpSource(), ConfigurableSource {
|
|||||||
|
|
||||||
override val supportsLatest: Boolean = true
|
override val supportsLatest: Boolean = true
|
||||||
|
|
||||||
private val preferences: SharedPreferences = getPreferences()
|
private val preferences: SharedPreferences = getPreferences {
|
||||||
|
this.getString(DEFAULT_BASE_URL_PREF, null).let { domain ->
|
||||||
|
if (domain != defaultBaseUrl) {
|
||||||
|
this.edit()
|
||||||
|
.putString(BASE_URL_PREF, defaultBaseUrl)
|
||||||
|
.putString(DEFAULT_BASE_URL_PREF, defaultBaseUrl)
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val client by lazy {
|
override val client by lazy {
|
||||||
network.cloudflareClient.newBuilder()
|
val client = network.cloudflareClient.newBuilder()
|
||||||
.rateLimitHost(fetchedDomainUrl.toHttpUrl(), 1, 2)
|
.rateLimitHost(fetchedDomainUrl.toHttpUrl(), 1, 2)
|
||||||
.rateLimitHost(apiBaseUrl.toHttpUrl(), 2, 1)
|
.rateLimitHost(apiBaseUrl.toHttpUrl(), 2, 1)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
fetchBookmarks()
|
||||||
|
|
||||||
|
return@lazy client
|
||||||
}
|
}
|
||||||
|
|
||||||
private val json: Json by injectLazy()
|
override fun headersBuilder() = super.headersBuilder()
|
||||||
|
.add("Referer", "$baseUrl/")
|
||||||
|
|
||||||
private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", Locale.US).apply {
|
private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", Locale.US).apply {
|
||||||
timeZone = TimeZone.getTimeZone("UTC")
|
timeZone = TimeZone.getTimeZone("UTC")
|
||||||
@ -89,8 +103,15 @@ class OlympusScanlation : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
val result = json.decodeFromString<PayloadHomeDto>(response.body.string())
|
val result = response.parseAs<PayloadHomeDto>()
|
||||||
val mangaList = result.data.popularComics.filter { it.type == "comic" }.map { it.toSManga() }
|
val slugMap = preferences.slugMap.toMutableMap()
|
||||||
|
val mangaList = result.data.popularComics
|
||||||
|
.filter { it.type == "comic" }
|
||||||
|
.map {
|
||||||
|
slugMap[it.id] = it.slug
|
||||||
|
it.toSManga()
|
||||||
|
}
|
||||||
|
preferences.slugMap = slugMap
|
||||||
return MangasPage(mangaList, hasNextPage = false)
|
return MangasPage(mangaList, hasNextPage = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,10 +122,15 @@ class OlympusScanlation : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||||
val result = json.decodeFromString<NewChaptersDto>(response.body.string())
|
val result = response.parseAs<NewChaptersDto>()
|
||||||
val mangaList = result.data.filter { it.type == "comic" }.map { it.toSManga() }
|
val slugMap = preferences.slugMap.toMutableMap()
|
||||||
val hasNextPage = result.current_page < result.last_page
|
val mangaList = result.data.filter { it.type == "comic" }
|
||||||
return MangasPage(mangaList, hasNextPage)
|
.map {
|
||||||
|
slugMap[it.id] = it.slug
|
||||||
|
it.toSManga()
|
||||||
|
}
|
||||||
|
preferences.slugMap = slugMap
|
||||||
|
return MangasPage(mangaList, result.hasNextPage())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
@ -148,80 +174,114 @@ class OlympusScanlation : HttpSource(), ConfigurableSource {
|
|||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
if (response.request.url.toString().startsWith("$apiBaseUrl/api/search")) {
|
if (response.request.url.toString().startsWith("$apiBaseUrl/api/search")) {
|
||||||
val result = json.decodeFromString<PayloadMangaDto>(response.body.string())
|
val result = response.parseAs<PayloadMangaDto>()
|
||||||
val mangaList = result.data.filter { it.type == "comic" }.map { it.toSManga() }
|
val slugMap = preferences.slugMap.toMutableMap()
|
||||||
|
val mangaList = result.data.filter { it.type == "comic" }
|
||||||
|
.map {
|
||||||
|
slugMap[it.id] = it.slug
|
||||||
|
it.toSManga()
|
||||||
|
}
|
||||||
|
preferences.slugMap = slugMap
|
||||||
return MangasPage(mangaList, hasNextPage = false)
|
return MangasPage(mangaList, hasNextPage = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = json.decodeFromString<PayloadSeriesDto>(response.body.string())
|
val result = response.parseAs<PayloadSeriesDto>()
|
||||||
val mangaList = result.data.series.data.map { it.toSManga() }
|
val mangaList = result.data.series.data.map { it.toSManga() }
|
||||||
val hasNextPage = result.data.series.current_page < result.data.series.last_page
|
return MangasPage(mangaList, result.data.series.hasNextPage())
|
||||||
return MangasPage(mangaList, hasNextPage)
|
}
|
||||||
|
|
||||||
|
private var bookmarksState = BookmarksState.NOT_FETCHED
|
||||||
|
|
||||||
|
private fun fetchBookmarks() {
|
||||||
|
if (!preferences.fetchBookmarksPref()) return
|
||||||
|
if (bookmarksState != BookmarksState.NOT_FETCHED) return
|
||||||
|
bookmarksState = BookmarksState.FETCHING
|
||||||
|
val slugMap = preferences.slugMap.toMutableMap()
|
||||||
|
var page = 1
|
||||||
|
try {
|
||||||
|
do {
|
||||||
|
val response = network.cloudflareClient.newCall(GET("$apiBaseUrl/api/user/bookmarks?page=$page", headers)).execute()
|
||||||
|
if (!response.isSuccessful) return
|
||||||
|
val result = response.parseAs<BookmarksWrapperDto>()
|
||||||
|
result.getBookmarks().forEach { bookmark ->
|
||||||
|
slugMap[bookmark.id!!] = bookmark.slug!!
|
||||||
|
}
|
||||||
|
page++
|
||||||
|
} while (result.meta.hasNextPage())
|
||||||
|
} catch (_: Exception) { } finally {
|
||||||
|
bookmarksState = BookmarksState.FETCHED
|
||||||
|
}
|
||||||
|
preferences.slugMap = slugMap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMangaUrl(manga: SManga): String {
|
||||||
|
val slug = preferences.slugMap[manga.url.toInt()]!!
|
||||||
|
return "$baseUrl/series/comic-$slug"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mangaDetailsRequest(manga: SManga): Request {
|
||||||
|
val slug = preferences.slugMap[manga.url.toInt()]!!
|
||||||
|
|
||||||
|
val apiUrl = "$apiBaseUrl/api/series/$slug?type=comic"
|
||||||
|
return GET(url = apiUrl, headers = headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val slug = response.request.url
|
val result = response.parseAs<MangaDetailDto>()
|
||||||
.toString()
|
|
||||||
.substringAfter("/series/comic-")
|
|
||||||
.substringBefore("/chapters")
|
|
||||||
val apiUrl = "$apiBaseUrl/api/series/$slug?type=comic"
|
|
||||||
val newRequest = GET(url = apiUrl, headers = headers)
|
|
||||||
val newResponse = client.newCall(newRequest).execute()
|
|
||||||
val result = json.decodeFromString<MangaDetailDto>(newResponse.body.string())
|
|
||||||
return result.data.toSMangaDetails()
|
return result.data.toSMangaDetails()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChapterUrl(chapter: SChapter): String = baseUrl + chapter.url
|
override fun getChapterUrl(chapter: SChapter): String {
|
||||||
|
val mangaId = chapter.url.substringBefore("/")
|
||||||
override fun chapterListRequest(manga: SManga): Request {
|
val chapterId = chapter.url.substringAfter("/")
|
||||||
return paginatedChapterListRequest(
|
val mangaSlug = preferences.slugMap[mangaId.toInt()]!!
|
||||||
manga.url
|
return "$baseUrl/capitulo/$chapterId/comic-$mangaSlug"
|
||||||
.substringAfter("/series/comic-")
|
|
||||||
.substringBefore("/chapters"),
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun paginatedChapterListRequest(mangaUrl: String, page: Int): Request {
|
override fun chapterListRequest(manga: SManga): Request {
|
||||||
|
val mangaId = manga.url
|
||||||
|
val mangaSlug = preferences.slugMap[mangaId.toInt()]!!
|
||||||
|
|
||||||
|
return paginatedChapterListRequest(mangaSlug, mangaId, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun paginatedChapterListRequest(mangaSlug: String, mangaId: String, page: Int): Request {
|
||||||
return GET(
|
return GET(
|
||||||
url = "$apiBaseUrl/api/series/$mangaUrl/chapters?page=$page&direction=desc&type=comic",
|
url = "$apiBaseUrl/api/series/$mangaSlug/chapters?page=$page&direction=desc&type=comic#$mangaId",
|
||||||
headers = headers,
|
headers = headers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
val slug = response.request.url
|
val mangaId = response.request.url.fragment ?: ""
|
||||||
.toString()
|
val slug = response.request.url.toString()
|
||||||
.substringAfter("/series/")
|
.substringAfter("/series/")
|
||||||
.substringBefore("/chapters")
|
.substringBefore("/chapters")
|
||||||
val data = json.decodeFromString<PayloadChapterDto>(response.body.string())
|
|
||||||
|
val data = response.parseAs<PayloadChapterDto>()
|
||||||
var resultSize = data.data.size
|
var resultSize = data.data.size
|
||||||
var page = 2
|
var page = 2
|
||||||
while (data.meta.total > resultSize) {
|
while (data.meta.total > resultSize) {
|
||||||
val newRequest = paginatedChapterListRequest(slug, page)
|
val newRequest = paginatedChapterListRequest(slug, mangaId, page)
|
||||||
val newResponse = client.newCall(newRequest).execute()
|
val newResponse = client.newCall(newRequest).execute()
|
||||||
val newData = json.decodeFromString<PayloadChapterDto>(newResponse.body.string())
|
val newData = newResponse.parseAs<PayloadChapterDto>()
|
||||||
data.data += newData.data
|
data.data += newData.data
|
||||||
resultSize += newData.data.size
|
resultSize += newData.data.size
|
||||||
page += 1
|
page += 1
|
||||||
}
|
}
|
||||||
return data.data.map { it.toSChapter(slug, dateFormat) }
|
return data.data.map { it.toSChapter(mangaId, dateFormat) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request {
|
override fun pageListRequest(chapter: SChapter): Request {
|
||||||
val id = chapter.url
|
val mangaId = chapter.url.substringBefore("/")
|
||||||
.substringAfter("/capitulo/")
|
val chapterId = chapter.url.substringAfter("/")
|
||||||
.substringBefore("/chapters")
|
val mangaSlug = preferences.slugMap[mangaId.toInt()]!!
|
||||||
.substringBefore("/comic")
|
|
||||||
val slug = chapter.url
|
return GET("$apiBaseUrl/api/series/$mangaSlug/chapters/$chapterId?type=comic")
|
||||||
.substringAfter("comic-")
|
|
||||||
.substringBefore("/chapters")
|
|
||||||
.substringBefore("/comic")
|
|
||||||
return GET("$apiBaseUrl/api/series/$slug/chapters/$id?type=comic")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
return json.decodeFromString<PayloadPagesDto>(response.body.string()).chapter.pages.mapIndexed { i, img ->
|
return response.parseAs<PayloadPagesDto>().chapter.pages.mapIndexed { i, img ->
|
||||||
Page(i, imageUrl = img)
|
Page(i, imageUrl = img)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,7 +352,7 @@ class OlympusScanlation : HttpSource(), ConfigurableSource {
|
|||||||
thread {
|
thread {
|
||||||
try {
|
try {
|
||||||
val response = client.newCall(GET("$apiBaseUrl/api/genres-statuses", headers)).execute()
|
val response = client.newCall(GET("$apiBaseUrl/api/genres-statuses", headers)).execute()
|
||||||
val filters = json.decodeFromString<GenresStatusesDto>(response.body.string())
|
val filters = response.parseAs<GenresStatusesDto>()
|
||||||
|
|
||||||
genresList = filters.genres.map { it.name.trim() to it.id }
|
genresList = filters.genres.map { it.name.trim() to it.id }
|
||||||
statusesList = filters.statuses.map { it.name.trim() to it.id }
|
statusesList = filters.statuses.map { it.name.trim() to it.id }
|
||||||
@ -304,30 +364,42 @@ class OlympusScanlation : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class UriPartFilter(displayName: String, val vals: Array<Pair<String, Int>>) :
|
open class UriPartFilter(displayName: String, private val vals: Array<Pair<String, Int>>) :
|
||||||
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
|
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
|
||||||
fun toUriPart() = vals[state].second
|
fun toUriPart() = vals[state].second
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class FiltersState { NOT_FETCHED, FETCHING, FETCHED }
|
private enum class FiltersState { NOT_FETCHED, FETCHING, FETCHED }
|
||||||
|
private enum class BookmarksState { NOT_FETCHED, FETCHING, FETCHED }
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
CheckBoxPreference(screen.context).apply {
|
SwitchPreferenceCompat(screen.context).apply {
|
||||||
|
key = FETCH_BOOKMARKS_PREF
|
||||||
|
title = "Usar marcadores"
|
||||||
|
summary = "Usa los marcadores del sitio para obtener la url actual de la serie.\nRequiere iniciar sesión en WebView y seguir la serie."
|
||||||
|
setDefaultValue(FETCH_BOOKMARKS_PREF_DEFAULT)
|
||||||
|
setOnPreferenceChangeListener { _, _ ->
|
||||||
|
Toast.makeText(screen.context, "Reinicie la aplicación para aplicar los cambios", Toast.LENGTH_LONG).show()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}.also { screen.addPreference(it) }
|
||||||
|
|
||||||
|
SwitchPreferenceCompat(screen.context).apply {
|
||||||
key = FETCH_DOMAIN_PREF
|
key = FETCH_DOMAIN_PREF
|
||||||
title = FETCH_DOMAIN_PREF_TITLE
|
title = "Buscar dominio automáticamente"
|
||||||
summary = FETCH_DOMAIN_PREF_SUMMARY
|
summary = "Intenta buscar el dominio automáticamente al abrir la fuente."
|
||||||
setDefaultValue(FETCH_DOMAIN_PREF_DEFAULT)
|
setDefaultValue(FETCH_DOMAIN_PREF_DEFAULT)
|
||||||
}.also { screen.addPreference(it) }
|
}.also { screen.addPreference(it) }
|
||||||
|
|
||||||
EditTextPreference(screen.context).apply {
|
EditTextPreference(screen.context).apply {
|
||||||
key = BASE_URL_PREF
|
key = BASE_URL_PREF
|
||||||
title = BASE_URL_PREF_TITLE
|
title = "Editar URL de la fuente"
|
||||||
summary = BASE_URL_PREF_SUMMARY
|
summary = "Para uso temporal, si la extensión se actualiza se perderá el cambio."
|
||||||
dialogTitle = BASE_URL_PREF_TITLE
|
dialogTitle = "Editar URL de la fuente"
|
||||||
dialogMessage = "URL por defecto:\n$defaultBaseUrl"
|
dialogMessage = "URL por defecto:\n$defaultBaseUrl"
|
||||||
setDefaultValue(defaultBaseUrl)
|
setDefaultValue(defaultBaseUrl)
|
||||||
setOnPreferenceChangeListener { _, _ ->
|
setOnPreferenceChangeListener { _, _ ->
|
||||||
Toast.makeText(screen.context, RESTART_APP_MESSAGE, Toast.LENGTH_LONG).show()
|
Toast.makeText(screen.context, "Reinicie la aplicación para aplicar los cambios", Toast.LENGTH_LONG).show()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}.also { screen.addPreference(it) }
|
}.also { screen.addPreference(it) }
|
||||||
@ -347,29 +419,35 @@ class OlympusScanlation : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun SharedPreferences.fetchDomainPref() = getBoolean(FETCH_DOMAIN_PREF, FETCH_DOMAIN_PREF_DEFAULT)
|
private fun SharedPreferences.fetchDomainPref() = getBoolean(FETCH_DOMAIN_PREF, FETCH_DOMAIN_PREF_DEFAULT)
|
||||||
|
private fun SharedPreferences.fetchBookmarksPref() = getBoolean(FETCH_BOOKMARKS_PREF, FETCH_BOOKMARKS_PREF_DEFAULT)
|
||||||
|
|
||||||
|
private var _slugMap: Map<Int, String>? = null
|
||||||
|
private var SharedPreferences.slugMap: Map<Int, String>
|
||||||
|
get() {
|
||||||
|
_slugMap?.let { return it }
|
||||||
|
val json = getString(SLUG_MAP, "{}")!!
|
||||||
|
_slugMap = try {
|
||||||
|
json.parseAs<Map<Int, String>>()
|
||||||
|
} catch (_: SerializationException) {
|
||||||
|
emptyMap()
|
||||||
|
}
|
||||||
|
return _slugMap!!
|
||||||
|
}
|
||||||
|
set(map) {
|
||||||
|
_slugMap = map
|
||||||
|
edit().putString(SLUG_MAP, map.toJsonString()).apply()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val BASE_URL_PREF = "overrideBaseUrl"
|
private const val BASE_URL_PREF = "overrideBaseUrl"
|
||||||
private const val BASE_URL_PREF_TITLE = "Editar URL de la fuente"
|
|
||||||
private const val BASE_URL_PREF_SUMMARY = "Para uso temporal, si la extensión se actualiza se perderá el cambio."
|
|
||||||
private const val DEFAULT_BASE_URL_PREF = "defaultBaseUrl"
|
private const val DEFAULT_BASE_URL_PREF = "defaultBaseUrl"
|
||||||
private const val RESTART_APP_MESSAGE = "Reinicie la aplicación para aplicar los cambios"
|
|
||||||
|
|
||||||
private const val FETCH_DOMAIN_PREF = "fetchDomain"
|
private const val FETCH_DOMAIN_PREF = "fetchDomain"
|
||||||
private const val FETCH_DOMAIN_PREF_TITLE = "Buscar dominio automáticamente"
|
|
||||||
private const val FETCH_DOMAIN_PREF_SUMMARY = "Intenta buscar el dominio automáticamente al abrir la fuente."
|
|
||||||
private const val FETCH_DOMAIN_PREF_DEFAULT = true
|
private const val FETCH_DOMAIN_PREF_DEFAULT = true
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
private const val FETCH_BOOKMARKS_PREF = "fetchBookmarks"
|
||||||
preferences.getString(DEFAULT_BASE_URL_PREF, null).let { domain ->
|
private const val FETCH_BOOKMARKS_PREF_DEFAULT = false
|
||||||
if (domain != defaultBaseUrl) {
|
|
||||||
preferences.edit()
|
private const val SLUG_MAP = "slugMap"
|
||||||
.putString(BASE_URL_PREF, defaultBaseUrl)
|
|
||||||
.putString(DEFAULT_BASE_URL_PREF, defaultBaseUrl)
|
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,18 +44,21 @@ class PayloadSeriesDataDto(
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class SeriesDto(
|
class SeriesDto(
|
||||||
val current_page: Int,
|
|
||||||
val data: List<MangaDto>,
|
val data: List<MangaDto>,
|
||||||
val last_page: Int,
|
@SerialName("current_page") private val currentPage: Int,
|
||||||
)
|
@SerialName("last_page") private val lastPage: Int,
|
||||||
|
) {
|
||||||
|
fun hasNextPage() = currentPage < lastPage
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class PayloadMangaDto(val data: List<MangaDto>)
|
class PayloadMangaDto(val data: List<MangaDto>)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class MangaDto(
|
class MangaDto(
|
||||||
|
val id: Int,
|
||||||
private val name: String,
|
private val name: String,
|
||||||
private val slug: String,
|
val slug: String,
|
||||||
private val cover: String? = null,
|
private val cover: String? = null,
|
||||||
val type: String? = null,
|
val type: String? = null,
|
||||||
private val summary: String? = null,
|
private val summary: String? = null,
|
||||||
@ -64,7 +67,7 @@ class MangaDto(
|
|||||||
) {
|
) {
|
||||||
fun toSManga() = SManga.create().apply {
|
fun toSManga() = SManga.create().apply {
|
||||||
title = name
|
title = name
|
||||||
url = "/series/comic-$slug"
|
url = id.toString()
|
||||||
thumbnail_url = cover
|
thumbnail_url = cover
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,20 +92,23 @@ class MangaDto(
|
|||||||
@Serializable
|
@Serializable
|
||||||
class NewChaptersDto(
|
class NewChaptersDto(
|
||||||
val data: List<LatestMangaDto>,
|
val data: List<LatestMangaDto>,
|
||||||
val current_page: Int,
|
@SerialName("current_page") private val currentPage: Int,
|
||||||
val last_page: Int,
|
@SerialName("last_page") private val lastPage: Int,
|
||||||
)
|
) {
|
||||||
|
fun hasNextPage() = currentPage < lastPage
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class LatestMangaDto(
|
class LatestMangaDto(
|
||||||
|
val id: Int,
|
||||||
private val name: String,
|
private val name: String,
|
||||||
private val slug: String,
|
val slug: String,
|
||||||
private val cover: String? = null,
|
private val cover: String? = null,
|
||||||
val type: String? = null,
|
val type: String? = null,
|
||||||
) {
|
) {
|
||||||
fun toSManga() = SManga.create().apply {
|
fun toSManga() = SManga.create().apply {
|
||||||
title = name
|
title = name
|
||||||
url = "/series/comic-$slug"
|
url = id.toString()
|
||||||
thumbnail_url = cover
|
thumbnail_url = cover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,9 +127,9 @@ class ChapterDto(
|
|||||||
private val name: String,
|
private val name: String,
|
||||||
@SerialName("published_at") private val date: String,
|
@SerialName("published_at") private val date: String,
|
||||||
) {
|
) {
|
||||||
fun toSChapter(mangaSlug: String, dateFormat: SimpleDateFormat) = SChapter.create().apply {
|
fun toSChapter(mangaId: String, dateFormat: SimpleDateFormat) = SChapter.create().apply {
|
||||||
name = "Capitulo ${this@ChapterDto.name}"
|
name = "Capitulo ${this@ChapterDto.name}"
|
||||||
url = "/capitulo/$id/comic-$mangaSlug"
|
url = "$mangaId/$id"
|
||||||
date_upload = try {
|
date_upload = try {
|
||||||
dateFormat.parse(date)!!.time
|
dateFormat.parse(date)!!.time
|
||||||
} catch (e: ParseException) {
|
} catch (e: ParseException) {
|
||||||
@ -157,3 +163,26 @@ class FilterDto(
|
|||||||
val id: Int,
|
val id: Int,
|
||||||
val name: String,
|
val name: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class BookmarksWrapperDto(
|
||||||
|
private val data: List<BookmarkDto> = emptyList(),
|
||||||
|
val meta: BookmarksMetaDto,
|
||||||
|
) {
|
||||||
|
fun getBookmarks() = data.filter { it.type == "comic" && it.id != null && it.slug != null }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class BookmarkDto(
|
||||||
|
val id: Int?,
|
||||||
|
val slug: String?,
|
||||||
|
val type: String?,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class BookmarksMetaDto(
|
||||||
|
@SerialName("current_page") private val currentPage: Int,
|
||||||
|
@SerialName("last_page") private val lastPage: Int,
|
||||||
|
) {
|
||||||
|
fun hasNextPage() = currentPage < lastPage
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user