diff --git a/src/all/kamyroll/build.gradle b/src/all/kamyroll/build.gradle index 2d871e31e..ea6ac8064 100644 --- a/src/all/kamyroll/build.gradle +++ b/src/all/kamyroll/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'Yomiroll' pkgNameSuffix = 'all.kamyroll' extClass = '.Yomiroll' - extVersionCode = 18 + extVersionCode = 19 libVersion = '13' } diff --git a/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/DataModel.kt b/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/DataModel.kt index 79269cc0f..256638a16 100644 --- a/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/DataModel.kt +++ b/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/DataModel.kt @@ -132,7 +132,7 @@ data class EpisodeResult( @SerialName("episode_air_date") val airDate: String? = null, val versions: ArrayList? = null, - val streams_link: String, + val streams_link: String? = null, ) { @Serializable data class Version( @@ -143,14 +143,6 @@ data class EpisodeResult( } } -data class TempEpisode( - var epData: EpisodeData, - var name: String, - var episode_number: Float, - var date_upload: Long, - var scanlator: String?, -) - @Serializable data class EpisodeData( val ids: List>, diff --git a/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/Yomiroll.kt b/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/Yomiroll.kt index ec16662bf..3f27ee36f 100644 --- a/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/Yomiroll.kt +++ b/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/Yomiroll.kt @@ -94,7 +94,9 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() { val queries = response.request.url.encodedQuery ?: "0" val position = if (queries.contains("start=")) { queries.substringAfter("start=").substringBefore("&").toInt() - } else { 0 } + } else { + 0 + } return AnimesPage(animeList, position + 36 < parsed.total) } @@ -142,7 +144,9 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() { val queries = response.request.url.encodedQuery ?: "0" val position = if (queries.contains("start=")) { queries.substringAfter("start=").substringBefore("&").toInt() - } else { 0 } + } else { + 0 + } return AnimesPage(animeList, position + 36 < total) } @@ -165,7 +169,8 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() { author = info.data.first().content_provider status = SAnime.COMPLETED if (genre.isNullOrBlank()) { - genre = info.data.first().genres?.joinToString { gen -> gen.replaceFirstChar { it.uppercase() } } + genre = + info.data.first().genres?.joinToString { gen -> gen.replaceFirstChar { it.uppercase() } } } }, ) @@ -187,56 +192,44 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() { override fun episodeListParse(response: Response): List { val seasons = json.decodeFromString(response.body.string()) val series = response.request.url.encodedPath.contains("series/") - // Why all this? well crunchy sends same season twice with different quality eg. One Piece - // which causes the number of episodes to be higher that what it actually is. + return if (series) { - seasons.data.sortedBy { it.season_number }.groupBy { it.season_number } - .map { (_, sList) -> - sList.parallelMap { seasonData -> - runCatching { - val episodeResp = - client.newCall(GET("$crUrl/content/v2/cms/seasons/${seasonData.id}/episodes")) - .execute() - val episodes = - json.decodeFromString(episodeResp.body.string()) - episodes.data.sortedBy { it.episode_number }.parallelMap { ep -> - TempEpisode( - epData = EpisodeData( - ep.versions?.map { Pair(it.mediaId, it.audio_locale) } - ?: listOf( - Pair( - ep.streams_link.substringAfter("videos/") - .substringBefore("/streams"), - ep.audio_locale, - ), - ), - ), - name = if (ep.episode_number > 0 && ep.episode.isNumeric()) { - "Season ${seasonData.season_number} Ep ${df.format(ep.episode_number)}: " + ep.title - } else { - ep.title - }, - episode_number = ep.episode_number, - date_upload = ep.airDate?.let { parseDate(it) } ?: 0L, - scanlator = ep.versions?.sortedBy { it.audio_locale } - ?.joinToString { it.audio_locale.substringBefore("-") } - ?: ep.audio_locale.substringBefore("-"), - ) - } - }.getOrNull() - }.asSequence().filterNotNull().flatten().groupBy { it.episode_number } - .map { (_, eList) -> - val versions = EpisodeData(eList.parallelMap { it.epData.ids }.flatten()).toJsonString() - val ep = eList.first() + seasons.data.sortedBy { it.season_number }.chunked(6).map { chunk -> + chunk.parallelMap { seasonData -> + runCatching { + val episodeResp = + client.newCall(GET("$crUrl/content/v2/cms/seasons/${seasonData.id}/episodes")) + .execute() + val body = episodeResp.body.string() + val episodes = + json.decodeFromString(body) + episodes.data.sortedBy { it.episode_number }.parallelMap { ep -> SEpisode.create().apply { - this.url = versions - this.name = ep.name - this.episode_number = ep.episode_number - this.date_upload = ep.date_upload - this.scanlator = eList.map { it.scanlator }.joinToString() + url = EpisodeData( + ep.versions?.map { Pair(it.mediaId, it.audio_locale) } + ?: listOf( + Pair( + ep.streams_link!!.substringAfter("videos/") + .substringBefore("/streams"), + ep.audio_locale, + ), + ), + ).toJsonString() + name = if (ep.episode_number > 0 && ep.episode.isNumeric()) { + "Season ${seasonData.season_number} Ep ${df.format(ep.episode_number)}: " + ep.title + } else { + ep.title + } + episode_number = ep.episode_number + date_upload = ep.airDate?.let { parseDate(it) } ?: 0L + scanlator = ep.versions?.sortedBy { it.audio_locale } + ?.joinToString { it.audio_locale.substringBefore("-") } + ?: ep.audio_locale.substringBefore("-") } } - }.flatten().reversed() + }.getOrNull() + }.filterNotNull().flatten() + }.flatten().reversed() } else { seasons.data.mapIndexed { index, movie -> SEpisode.create().apply { @@ -269,17 +262,22 @@ class Yomiroll : ConfigurableAnimeSource, AnimeHttpSource() { // ============================= Utilities ============================== - private fun extractVideo(media: Pair, proxyToken: AccessToken, localToken: AccessToken?): List