From b687d0e3aac3b21de0cea1709b20dd191d3b6774 Mon Sep 17 00:00:00 2001 From: Secozzi <49240133+Secozzi@users.noreply.github.com> Date: Wed, 30 Aug 2023 14:27:58 +0000 Subject: [PATCH] fix(all/jellyfin): Fix subtitles, pages, and some small code refactoring (#2103) Co-authored-by: jmir1 --- src/all/jellyfin/build.gradle | 4 +- .../animeextension/all/jellyfin/Jellyfin.kt | 269 +++++++++--------- .../all/jellyfin/JellyfinFactory.kt | 11 + 3 files changed, 145 insertions(+), 139 deletions(-) create mode 100644 src/all/jellyfin/src/eu/kanade/tachiyomi/animeextension/all/jellyfin/JellyfinFactory.kt diff --git a/src/all/jellyfin/build.gradle b/src/all/jellyfin/build.gradle index f295fd29c..63f725788 100644 --- a/src/all/jellyfin/build.gradle +++ b/src/all/jellyfin/build.gradle @@ -5,8 +5,8 @@ apply plugin: 'kotlinx-serialization' ext { extName = 'Jellyfin' pkgNameSuffix = 'all.jellyfin' - extClass = '.Jellyfin' - extVersionCode = 8 + extClass = '.JellyfinFactory' + extVersionCode = 9 libVersion = '13' } diff --git a/src/all/jellyfin/src/eu/kanade/tachiyomi/animeextension/all/jellyfin/Jellyfin.kt b/src/all/jellyfin/src/eu/kanade/tachiyomi/animeextension/all/jellyfin/Jellyfin.kt index 71fe11e46..a3563568d 100644 --- a/src/all/jellyfin/src/eu/kanade/tachiyomi/animeextension/all/jellyfin/Jellyfin.kt +++ b/src/all/jellyfin/src/eu/kanade/tachiyomi/animeextension/all/jellyfin/Jellyfin.kt @@ -22,7 +22,6 @@ import eu.kanade.tachiyomi.network.asObservableSuccess import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext -import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import okhttp3.Dns @@ -38,9 +37,9 @@ import uy.kohesive.injekt.injectLazy import kotlin.math.ceil import kotlin.math.floor -class Jellyfin : ConfigurableAnimeSource, AnimeHttpSource() { +class Jellyfin(private val suffix: String) : ConfigurableAnimeSource, AnimeHttpSource() { - override val name = "Jellyfin" + override val name = "Jellyfin$suffix" override val lang = "all" @@ -108,23 +107,21 @@ class Jellyfin : ConfigurableAnimeSource, AnimeHttpSource() { } override fun popularAnimeRequest(page: Int): Request { - if (parentId.isEmpty()) { - throw Exception("Select library in the extension settings.") - } + require(parentId.isNotEmpty()) { "Select library in the extension settings." } val startIndex = (page - 1) * 20 - val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder() - - url.addQueryParameter("api_key", apiKey) - url.addQueryParameter("StartIndex", startIndex.toString()) - url.addQueryParameter("Limit", "20") - url.addQueryParameter("Recursive", "true") - url.addQueryParameter("SortBy", "SortName") - url.addQueryParameter("SortOrder", "Ascending") - url.addQueryParameter("includeItemTypes", "Movie,Series,Season,BoxSet") - url.addQueryParameter("ImageTypeLimit", "1") - url.addQueryParameter("ParentId", parentId) - url.addQueryParameter("EnableImageTypes", "Primary") + val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder().apply { + addQueryParameter("api_key", apiKey) + addQueryParameter("StartIndex", startIndex.toString()) + addQueryParameter("Limit", "20") + addQueryParameter("Recursive", "true") + addQueryParameter("SortBy", "SortName") + addQueryParameter("SortOrder", "Ascending") + addQueryParameter("includeItemTypes", "Movie,Season,BoxSet") + addQueryParameter("ImageTypeLimit", "1") + addQueryParameter("ParentId", parentId) + addQueryParameter("EnableImageTypes", "Primary") + } return GET(url.toString()) } @@ -150,24 +147,21 @@ class Jellyfin : ConfigurableAnimeSource, AnimeHttpSource() { } override fun latestUpdatesRequest(page: Int): Request { - if (parentId.isEmpty()) { - throw Exception("Select library in the extension settings.") - } - + require(parentId.isNotEmpty()) { "Select library in the extension settings." } val startIndex = (page - 1) * 20 - val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder() - - url.addQueryParameter("api_key", apiKey) - url.addQueryParameter("StartIndex", startIndex.toString()) - url.addQueryParameter("Limit", "20") - url.addQueryParameter("Recursive", "true") - url.addQueryParameter("SortBy", "DateCreated,SortName") - url.addQueryParameter("SortOrder", "Descending") - url.addQueryParameter("includeItemTypes", "Movie,Series,Season,BoxSet") - url.addQueryParameter("ImageTypeLimit", "1") - url.addQueryParameter("ParentId", parentId) - url.addQueryParameter("EnableImageTypes", "Primary") + val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder().apply { + addQueryParameter("api_key", apiKey) + addQueryParameter("StartIndex", startIndex.toString()) + addQueryParameter("Limit", "20") + addQueryParameter("Recursive", "true") + addQueryParameter("SortBy", "DateCreated,SortName") + addQueryParameter("SortOrder", "Descending") + addQueryParameter("includeItemTypes", "Movie,Season,BoxSet") + addQueryParameter("ImageTypeLimit", "1") + addQueryParameter("ParentId", parentId) + addQueryParameter("EnableImageTypes", "Primary") + } return GET(url.toString()) } @@ -181,51 +175,45 @@ class Jellyfin : ConfigurableAnimeSource, AnimeHttpSource() { override fun searchAnimeParse(response: Response) = throw Exception("Not used") override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable { - if (parentId.isEmpty()) { - throw Exception("Select library in the extension settings.") - } - - val animeList = mutableListOf() + require(parentId.isNotEmpty()) { "Select library in the extension settings." } val startIndex = (page - 1) * 5 - val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder() + val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder().apply { + addQueryParameter("api_key", apiKey) + addQueryParameter("StartIndex", startIndex.toString()) + addQueryParameter("Limit", "5") + addQueryParameter("Recursive", "true") + addQueryParameter("SortBy", "SortName") + addQueryParameter("SortOrder", "Ascending") + addQueryParameter("includeItemTypes", "Movie,Season,BoxSet") + addQueryParameter("ImageTypeLimit", "1") + addQueryParameter("EnableImageTypes", "Primary") + addQueryParameter("ParentId", parentId) + addQueryParameter("SearchTerm", query) + } - url.addQueryParameter("api_key", apiKey) - url.addQueryParameter("StartIndex", startIndex.toString()) - url.addQueryParameter("Limit", "5") - url.addQueryParameter("Recursive", "true") - url.addQueryParameter("SortBy", "SortName") - url.addQueryParameter("SortOrder", "Ascending") - url.addQueryParameter("includeItemTypes", "Movie,Series,BoxSet") - url.addQueryParameter("ImageTypeLimit", "1") - url.addQueryParameter("EnableImageTypes", "Primary") - url.addQueryParameter("ParentId", parentId) - url.addQueryParameter("SearchTerm", query) - - val response = client.newCall( + val items = client.newCall( GET(url.build().toString(), headers = headers), - ).execute() - val items = json.decodeFromString(response.body.string()) - items.Items.forEach { - animeList.addAll( - getAnimeFromId(it.Id), - ) + ).execute().parseAs() + + val animeList = items.Items.flatMap { + getAnimeFromId(it.Id) } return Observable.just(AnimesPage(animeList, 5 * page < items.TotalRecordCount)) } private fun getAnimeFromId(id: String): List { - val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder() - - url.addQueryParameter("api_key", apiKey) - url.addQueryParameter("Recursive", "true") - url.addQueryParameter("SortBy", "SortName") - url.addQueryParameter("SortOrder", "Ascending") - url.addQueryParameter("includeItemTypes", "Movie,Series,Season") - url.addQueryParameter("ImageTypeLimit", "1") - url.addQueryParameter("EnableImageTypes", "Primary") - url.addQueryParameter("ParentId", id) + val url = "$baseUrl/Users/$userId/Items".toHttpUrl().newBuilder().apply { + addQueryParameter("api_key", apiKey) + addQueryParameter("Recursive", "true") + addQueryParameter("SortBy", "SortName") + addQueryParameter("SortOrder", "Ascending") + addQueryParameter("includeItemTypes", "Movie,Series,Season") + addQueryParameter("ImageTypeLimit", "1") + addQueryParameter("EnableImageTypes", "Primary") + addQueryParameter("ParentId", id) + } val response = client.newCall( GET(url.build().toString()), @@ -244,22 +232,22 @@ class Jellyfin : ConfigurableAnimeSource, AnimeHttpSource() { mediaId.seasonId } - val url = "$baseUrl/Users/$userId/Items/$infoId".toHttpUrl().newBuilder() - - url.addQueryParameter("api_key", apiKey) - url.addQueryParameter("fields", "Studios") + val url = "$baseUrl/Users/$userId/Items/$infoId".toHttpUrl().newBuilder().apply { + addQueryParameter("api_key", apiKey) + addQueryParameter("fields", "Studios") + } return GET(url.toString()) } override fun animeDetailsParse(response: Response): SAnime { - val info = json.decodeFromString(response.body.string()) + val info = response.parseAs() val anime = SAnime.create() if (info.Genres != null) anime.genre = info.Genres.joinToString(", ") - if (info.Studios != null && info.Studios.isNotEmpty()) { + if (!info.Studios.isNullOrEmpty()) { anime.author = info.Studios.mapNotNull { it.Name }.joinToString(", ") } else if (info.SeriesStudio != null) anime.author = info.SeriesStudio @@ -297,13 +285,15 @@ class Jellyfin : ConfigurableAnimeSource, AnimeHttpSource() { override fun episodeListParse(response: Response): List { val episodeList = if (response.request.url.toString().startsWith("$baseUrl/Users/")) { val parsed = json.decodeFromString(response.body.string()) - val episode = SEpisode.create() - episode.episode_number = 1.0F - episode.name = "Movie ${parsed.Name}" - episode.setUrlWithoutDomain(response.request.url.toString().substringAfter(baseUrl)) - listOf(episode) + listOf( + SEpisode.create().apply { + setUrlWithoutDomain(response.request.url.toString()) + name = "Movie ${parsed.Name}" + episode_number = 1.0F + }, + ) } else { - val parsed = json.decodeFromString(response.body.string()) + val parsed = response.parseAs() parsed.Items.map { ep -> @@ -333,14 +323,14 @@ class Jellyfin : ConfigurableAnimeSource, AnimeHttpSource() { override fun videoListParse(response: Response): List