mirror of
https://github.com/keiyoushi/extensions-source.git
synced 2024-11-25 11:42:47 +01:00
OlympusScanlation: Update domain and minor refactor (#1300)
* Update domain and other things * Change popular endpoint * fetchFilters in getFilterList * Make SManga and SChapter in DTO * I just want to update the domain * Move attempts to finally block * idk * update --------- Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>
This commit is contained in:
parent
edecdb4e8d
commit
5901557544
@ -1,7 +1,7 @@
|
||||
ext {
|
||||
extName = 'Olympus Scanlation'
|
||||
extClass = '.OlympusScanlation'
|
||||
extVersionCode = 6
|
||||
extVersionCode = 7
|
||||
}
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
||||
|
@ -18,13 +18,14 @@ import uy.kohesive.injekt.injectLazy
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class OlympusScanlation : HttpSource() {
|
||||
|
||||
override val versionId = 2
|
||||
|
||||
override val baseUrl: String = "https://olympusvisor.com"
|
||||
private val apiBaseUrl: String = "https://dashboard.olympusvisor.com"
|
||||
override val baseUrl: String = "https://visorolym.com"
|
||||
private val apiBaseUrl: String = "https://dashboard.visorolym.com"
|
||||
|
||||
override val lang: String = "es"
|
||||
override val name: String = "Olympus Scanlation"
|
||||
@ -37,27 +38,21 @@ class OlympusScanlation : HttpSource() {
|
||||
.build()
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", Locale.US).apply {
|
||||
timeZone = TimeZone.getTimeZone("UTC")
|
||||
}
|
||||
|
||||
override fun popularMangaRequest(page: Int): Request {
|
||||
val apiUrl = "$apiBaseUrl/api/series?page=1&direction=asc&type=comic".toHttpUrl().newBuilder()
|
||||
val apiUrl = "$apiBaseUrl/api/sf/home".toHttpUrl().newBuilder()
|
||||
.build()
|
||||
return GET(apiUrl, headers)
|
||||
}
|
||||
|
||||
override fun popularMangaParse(response: Response): MangasPage {
|
||||
runCatching { fetchFilters() }
|
||||
val result = json.decodeFromString<PayloadSeriesDto>(response.body.string())
|
||||
val resultMangaList = json.decodeFromString<List<MangaDto>>(result.data.recommended_series)
|
||||
val mangaList = resultMangaList.filter { it.type == "comic" }.map {
|
||||
SManga.create().apply {
|
||||
url = "/series/comic-${it.slug}"
|
||||
title = it.name
|
||||
thumbnail_url = it.cover
|
||||
}
|
||||
}
|
||||
val result = json.decodeFromString<PayloadHomeDto>(response.body.string())
|
||||
val popularJson = json.decodeFromString<List<MangaDto>>(result.data.popularComics)
|
||||
val mangaList = popularJson.filter { it.type == "comic" }.map { it.toSManga() }
|
||||
return MangasPage(mangaList, hasNextPage = false)
|
||||
}
|
||||
|
||||
@ -68,15 +63,8 @@ class OlympusScanlation : HttpSource() {
|
||||
}
|
||||
|
||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||
runCatching { fetchFilters() }
|
||||
val result = json.decodeFromString<NewChaptersDto>(response.body.string())
|
||||
val mangaList = result.data.filter { it.type == "comic" }.map {
|
||||
SManga.create().apply {
|
||||
url = "/series/comic-${it.slug}"
|
||||
title = it.name
|
||||
thumbnail_url = it.cover
|
||||
}
|
||||
}
|
||||
val mangaList = result.data.filter { it.type == "comic" }.map { it.toSManga() }
|
||||
val hasNextPage = result.current_page < result.last_page
|
||||
return MangasPage(mangaList, hasNextPage)
|
||||
}
|
||||
@ -118,27 +106,14 @@ class OlympusScanlation : HttpSource() {
|
||||
}
|
||||
|
||||
override fun searchMangaParse(response: Response): MangasPage {
|
||||
runCatching { fetchFilters() }
|
||||
if (response.request.url.toString().startsWith("$apiBaseUrl/api/search")) {
|
||||
val result = json.decodeFromString<PayloadMangaDto>(response.body.string())
|
||||
val mangaList = result.data.filter { it.type == "comic" }.map {
|
||||
SManga.create().apply {
|
||||
url = "/series/comic-${it.slug}"
|
||||
title = it.name
|
||||
thumbnail_url = it.cover
|
||||
}
|
||||
}
|
||||
val mangaList = result.data.filter { it.type == "comic" }.map { it.toSManga() }
|
||||
return MangasPage(mangaList, hasNextPage = false)
|
||||
}
|
||||
|
||||
val result = json.decodeFromString<PayloadSeriesDto>(response.body.string())
|
||||
val mangaList = result.data.series.data.map {
|
||||
SManga.create().apply {
|
||||
url = "/series/comic-${it.slug}"
|
||||
title = it.name
|
||||
thumbnail_url = it.cover
|
||||
}
|
||||
}
|
||||
val mangaList = result.data.series.data.map { it.toSManga() }
|
||||
val hasNextPage = result.data.series.current_page < result.data.series.last_page
|
||||
return MangasPage(mangaList, hasNextPage)
|
||||
}
|
||||
@ -152,14 +127,7 @@ class OlympusScanlation : HttpSource() {
|
||||
val newRequest = GET(url = apiUrl, headers = headers)
|
||||
val newResponse = client.newCall(newRequest).execute()
|
||||
val result = json.decodeFromString<MangaDetailDto>(newResponse.body.string())
|
||||
return SManga.create().apply {
|
||||
url = "/series/comic-$slug"
|
||||
title = result.data.name
|
||||
thumbnail_url = result.data.cover
|
||||
description = result.data.summary
|
||||
status = parseStatus(result.data.status?.id)
|
||||
genre = result.data.genres?.joinToString { it.name.trim() }
|
||||
}
|
||||
return result.data.toSMangaDetails()
|
||||
}
|
||||
|
||||
override fun getChapterUrl(chapter: SChapter): String = baseUrl + chapter.url
|
||||
@ -196,14 +164,7 @@ class OlympusScanlation : HttpSource() {
|
||||
resultSize += newData.data.size
|
||||
page += 1
|
||||
}
|
||||
return data.data.map { chap -> chapterFromObject(chap, slug) }
|
||||
}
|
||||
|
||||
private fun chapterFromObject(chapter: ChapterDto, slug: String) = SChapter.create().apply {
|
||||
url = "/capitulo/${chapter.id}/comic-$slug"
|
||||
name = "Capitulo ${chapter.name}"
|
||||
date_upload = runCatching { dateFormat.parse(chapter.date)?.time }
|
||||
.getOrNull() ?: 0L
|
||||
return data.data.map { it.toSChapter(slug, dateFormat) }
|
||||
}
|
||||
|
||||
override fun pageListRequest(chapter: SChapter): Request {
|
||||
@ -220,20 +181,12 @@ class OlympusScanlation : HttpSource() {
|
||||
|
||||
override fun pageListParse(response: Response): List<Page> {
|
||||
return json.decodeFromString<PayloadPagesDto>(response.body.string()).chapter.pages.mapIndexed { i, img ->
|
||||
Page(i, "", img)
|
||||
Page(i, imageUrl = img)
|
||||
}
|
||||
}
|
||||
|
||||
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException()
|
||||
|
||||
private fun parseStatus(statusId: Int?) = when (statusId) {
|
||||
1 -> SManga.ONGOING
|
||||
3 -> SManga.ON_HIATUS
|
||||
4 -> SManga.COMPLETED
|
||||
5 -> SManga.CANCELLED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
|
||||
private class SortFilter : Filter.Sort(
|
||||
"Ordenar",
|
||||
arrayOf("Alfabético"),
|
||||
@ -257,13 +210,14 @@ class OlympusScanlation : HttpSource() {
|
||||
)
|
||||
|
||||
override fun getFilterList(): FilterList {
|
||||
fetchFilters()
|
||||
val filters = mutableListOf<Filter<*>>(
|
||||
Filter.Header("Los filtros no funcionan en la búsqueda por texto"),
|
||||
Filter.Separator(),
|
||||
SortFilter(),
|
||||
)
|
||||
|
||||
if (genresList.isNotEmpty() || statusesList.isNotEmpty()) {
|
||||
if (filtersState == FiltersState.FETCHED) {
|
||||
filters += listOf(
|
||||
Filter.Separator(),
|
||||
Filter.Header("Filtrar por género"),
|
||||
@ -287,20 +241,25 @@ class OlympusScanlation : HttpSource() {
|
||||
|
||||
private var genresList: List<Pair<String, Int>> = emptyList()
|
||||
private var statusesList: List<Pair<String, Int>> = emptyList()
|
||||
private var fetchFiltersAttemps = 0
|
||||
private var fetchFiltersFailed = false
|
||||
private var fetchFiltersAttempts = 0
|
||||
private var filtersState = FiltersState.NOT_FETCHED
|
||||
|
||||
private fun fetchFilters() {
|
||||
if (fetchFiltersAttemps <= 3 && ((genresList.isEmpty() && statusesList.isEmpty()) || fetchFiltersFailed)) {
|
||||
val filters = runCatching {
|
||||
if (filtersState != FiltersState.NOT_FETCHED || fetchFiltersAttempts >= 3) return
|
||||
filtersState = FiltersState.FETCHING
|
||||
fetchFiltersAttempts++
|
||||
thread {
|
||||
try {
|
||||
val response = client.newCall(GET("$apiBaseUrl/api/genres-statuses", headers)).execute()
|
||||
json.decodeFromString<GenresStatusesDto>(response.body.string())
|
||||
}
|
||||
val filters = json.decodeFromString<GenresStatusesDto>(response.body.string())
|
||||
|
||||
fetchFiltersFailed = filters.isFailure
|
||||
genresList = filters.getOrNull()?.genres?.map { it.name.trim() to it.id } ?: emptyList()
|
||||
statusesList = filters.getOrNull()?.statuses?.map { it.name.trim() to it.id } ?: emptyList()
|
||||
fetchFiltersAttemps++
|
||||
genresList = filters.genres.map { it.name.trim() to it.id }
|
||||
statusesList = filters.statuses.map { it.name.trim() to it.id }
|
||||
|
||||
filtersState = FiltersState.FETCHED
|
||||
} catch (e: Throwable) {
|
||||
filtersState = FiltersState.NOT_FETCHED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,4 +267,6 @@ class OlympusScanlation : HttpSource() {
|
||||
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
|
||||
fun toUriPart() = vals[state].second
|
||||
}
|
||||
|
||||
private enum class FiltersState { NOT_FETCHED, FETCHING, FETCHED }
|
||||
}
|
||||
|
@ -1,93 +1,142 @@
|
||||
package eu.kanade.tachiyomi.extension.es.olympusscanlation
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
@Serializable
|
||||
data class PayloadSeriesDto(val data: PayloadSeriesDataDto)
|
||||
|
||||
@Serializable
|
||||
data class PayloadSeriesDataDto(
|
||||
val series: SeriesDto,
|
||||
val recommended_series: String,
|
||||
class PayloadHomeDto(
|
||||
val data: HomeDto,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SeriesDto(
|
||||
class HomeDto(
|
||||
@SerialName("popular_comics") val popularComics: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class PayloadSeriesDto(val data: PayloadSeriesDataDto)
|
||||
|
||||
@Serializable
|
||||
class PayloadSeriesDataDto(
|
||||
val series: SeriesDto,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class SeriesDto(
|
||||
val current_page: Int,
|
||||
val data: List<MangaDto>,
|
||||
val last_page: Int,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PayloadMangaDto(val data: List<MangaDto>)
|
||||
class PayloadMangaDto(val data: List<MangaDto>)
|
||||
|
||||
@Serializable
|
||||
data class MangaDto(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val slug: String,
|
||||
val cover: String? = null,
|
||||
class MangaDto(
|
||||
private val name: String,
|
||||
private val slug: String,
|
||||
private val cover: String? = null,
|
||||
val type: String? = null,
|
||||
val summary: String? = null,
|
||||
val status: MangaStatusDto? = null,
|
||||
val genres: List<FilterDto>? = null,
|
||||
)
|
||||
private val summary: String? = null,
|
||||
private val status: MangaStatusDto? = null,
|
||||
private val genres: List<FilterDto>? = null,
|
||||
) {
|
||||
fun toSManga() = SManga.create().apply {
|
||||
title = name
|
||||
url = "/series/comic-$slug"
|
||||
thumbnail_url = cover
|
||||
}
|
||||
|
||||
fun toSMangaDetails() = toSManga().apply {
|
||||
description = summary
|
||||
status = parseStatus()
|
||||
genre = genres?.joinToString { it.name.trim() }
|
||||
}
|
||||
|
||||
private fun parseStatus(): Int {
|
||||
val status = this.status ?: return SManga.UNKNOWN
|
||||
return when (status.id) {
|
||||
1 -> SManga.ONGOING
|
||||
3 -> SManga.ON_HIATUS
|
||||
4 -> SManga.COMPLETED
|
||||
5 -> SManga.CANCELLED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class NewChaptersDto(
|
||||
class NewChaptersDto(
|
||||
val data: List<LatestMangaDto>,
|
||||
val current_page: Int,
|
||||
val last_page: Int,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class LatestMangaDto(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val slug: String,
|
||||
val cover: String? = null,
|
||||
class LatestMangaDto(
|
||||
private val name: String,
|
||||
private val slug: String,
|
||||
private val cover: String? = null,
|
||||
val type: String? = null,
|
||||
)
|
||||
) {
|
||||
fun toSManga() = SManga.create().apply {
|
||||
title = name
|
||||
url = "/series/comic-$slug"
|
||||
thumbnail_url = cover
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class MangaDetailDto(
|
||||
class MangaDetailDto(
|
||||
var data: MangaDto,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PayloadChapterDto(var data: List<ChapterDto>, val meta: MetaDto)
|
||||
class PayloadChapterDto(var data: List<ChapterDto>, val meta: MetaDto)
|
||||
|
||||
@Serializable
|
||||
data class ChapterDto(
|
||||
class ChapterDto(
|
||||
private val id: Int,
|
||||
private val name: String,
|
||||
@SerialName("published_at") private val date: String,
|
||||
) {
|
||||
fun toSChapter(mangaSlug: String, dateFormat: SimpleDateFormat) = SChapter.create().apply {
|
||||
name = "Capitulo ${this@ChapterDto.name}"
|
||||
url = "/capitulo/$id/comic-$mangaSlug"
|
||||
date_upload = try {
|
||||
dateFormat.parse(date)!!.time
|
||||
} catch (e: ParseException) {
|
||||
0L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class MetaDto(val total: Int)
|
||||
|
||||
@Serializable
|
||||
class PayloadPagesDto(val chapter: PageDto)
|
||||
|
||||
@Serializable
|
||||
class PageDto(val pages: List<String>)
|
||||
|
||||
@Serializable
|
||||
class MangaStatusDto(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
@SerialName("published_at") val date: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class MetaDto(val total: Int)
|
||||
|
||||
@Serializable
|
||||
data class PayloadPagesDto(val chapter: PageDto)
|
||||
|
||||
@Serializable
|
||||
data class PageDto(val pages: List<String>)
|
||||
|
||||
@Serializable
|
||||
data class MangaStatusDto(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GenresStatusesDto(
|
||||
class GenresStatusesDto(
|
||||
val genres: List<FilterDto>,
|
||||
val statuses: List<FilterDto>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class FilterDto(
|
||||
class FilterDto(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user