From c3654b404bd51cfd9cd57f4eb93df190736601be Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:19:17 -0600 Subject: [PATCH 1/3] Subdl: migrate to kotlinx serialization --- .../syncproviders/providers/Subdl.kt | 93 ++++++++++--------- 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt index 1f1e6de4450..f5551cce18a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt @@ -1,6 +1,5 @@ package com.lagradost.cloudstream3.syncproviders.providers -import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.subtitles.AbstractSubtitleEntities @@ -12,6 +11,8 @@ import com.lagradost.cloudstream3.syncproviders.AuthToken import com.lagradost.cloudstream3.syncproviders.AuthUser import com.lagradost.cloudstream3.syncproviders.SubtitleAPI import com.lagradost.cloudstream3.TvType +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable class SubDlApi : SubtitleAPI() { override val name = "SubDL" @@ -122,69 +123,77 @@ class SubDlApi : SubtitleAPI() { } } + @Serializable data class SubtitleOAuthEntity( - @JsonProperty("userEmail") var userEmail: String, - @JsonProperty("pass") var pass: String, - @JsonProperty("name") var name: String? = null, - @JsonProperty("accessToken") var accessToken: String? = null, - @JsonProperty("apiKey") var apiKey: String? = null, + @SerialName("userEmail") var userEmail: String, + @SerialName("pass") var pass: String, + @SerialName("name") var name: String? = null, + @SerialName("accessToken") var accessToken: String? = null, + @SerialName("apiKey") var apiKey: String? = null, ) + @Serializable data class OAuthTokenResponse( - @JsonProperty("token") val token: String, - @JsonProperty("userData") val userData: UserData? = null, - @JsonProperty("status") val status: Boolean? = null, - @JsonProperty("message") val message: String? = null, + @SerialName("token") val token: String, + @SerialName("userData") val userData: UserData? = null, + @SerialName("status") val status: Boolean? = null, + @SerialName("message") val message: String? = null, ) + @Serializable data class UserData( - @JsonProperty("email") val email: String, - @JsonProperty("name") val name: String, - @JsonProperty("country") val country: String, - @JsonProperty("scStepCode") val scStepCode: String, - @JsonProperty("scVerified") val scVerified: Boolean, - @JsonProperty("username") val username: String? = null, - @JsonProperty("scUsername") val scUsername: String, + @SerialName("email") val email: String, + @SerialName("name") val name: String, + @SerialName("country") val country: String, + @SerialName("scStepCode") val scStepCode: String, + @SerialName("scVerified") val scVerified: Boolean, + @SerialName("username") val username: String? = null, + @SerialName("scUsername") val scUsername: String, ) + @Serializable data class ApiKeyResponse( - @JsonProperty("ok") val ok: Boolean? = false, - @JsonProperty("api_key") val apiKey: String, - @JsonProperty("usage") val usage: Usage? = null, + @SerialName("ok") val ok: Boolean? = false, + @SerialName("api_key") val apiKey: String, + @SerialName("usage") val usage: Usage? = null, ) + @Serializable data class Usage( - @JsonProperty("total") val total: Long? = 0, - @JsonProperty("today") val today: Long? = 0, + @SerialName("total") val total: Long? = 0, + @SerialName("today") val today: Long? = 0, ) + @Serializable data class ApiResponse( - @JsonProperty("status") val status: Boolean? = null, - @JsonProperty("results") val results: List? = null, - @JsonProperty("subtitles") val subtitles: List? = null, + @SerialName("status") val status: Boolean? = null, + @SerialName("results") val results: List? = null, + @SerialName("subtitles") val subtitles: List? = null, ) + @Serializable data class Result( - @JsonProperty("sd_id") val sdId: Int? = null, - @JsonProperty("type") val type: String? = null, - @JsonProperty("name") val name: String? = null, - @JsonProperty("imdb_id") val imdbId: String? = null, - @JsonProperty("tmdb_id") val tmdbId: Long? = null, - @JsonProperty("first_air_date") val firstAirDate: String? = null, - @JsonProperty("year") val year: Int? = null, + @SerialName("sd_id") val sdId: Int? = null, + @SerialName("type") val type: String? = null, + @SerialName("name") val name: String? = null, + @SerialName("imdb_id") val imdbId: String? = null, + @SerialName("tmdb_id") val tmdbId: Long? = null, + @SerialName("first_air_date") val firstAirDate: String? = null, + @SerialName("year") val year: Int? = null, ) + @Serializable data class Subtitle( - @JsonProperty("release_name") val releaseName: String, - @JsonProperty("name") val name: String, - @JsonProperty("lang") val lang: String, // subdl language code - @JsonProperty("author") val author: String? = null, - @JsonProperty("url") val url: String? = null, - @JsonProperty("subtitlePage") val subtitlePage: String? = null, - @JsonProperty("season") val season: Int? = null, - @JsonProperty("episode") val episode: Int? = null, - @JsonProperty("language") val language: String? = null, // full language name - @JsonProperty("hi") val hearingImpaired: Boolean? = null, + @SerialName("release_name") val releaseName: String, + @SerialName("name") val name: String, + @SerialName("lang") val lang: String, // subdl language code + @SerialName("author") val author: String? = null, + @SerialName("url") val url: String? = null, + @SerialName("subtitlePage") val subtitlePage: String? = null, + @SerialName("season") val season: Int? = null, + @SerialName("episode") val episode: Int? = null, + @SerialName("language") val language: String? = null, // full language name + @SerialName("hi") val hearingImpaired: Boolean? = null, ) // https://subdl.com/api-files/language_list.json From cf93296ccf909b47c3060e280774ab18cdec0344 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:38:32 -0600 Subject: [PATCH 2/3] Keep JsonProperty where different than variable name --- .../cloudstream3/syncproviders/providers/Subdl.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt index f5551cce18a..ff95e77895e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.syncproviders.providers +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.subtitles.AbstractSubtitleEntities @@ -154,7 +155,7 @@ class SubDlApi : SubtitleAPI() { @Serializable data class ApiKeyResponse( @SerialName("ok") val ok: Boolean? = false, - @SerialName("api_key") val apiKey: String, + @JsonProperty("api_key") @SerialName("api_key") val apiKey: String, @SerialName("usage") val usage: Usage? = null, ) @@ -173,18 +174,18 @@ class SubDlApi : SubtitleAPI() { @Serializable data class Result( - @SerialName("sd_id") val sdId: Int? = null, + @JsonProperty("sd_id") @SerialName("sd_id") val sdId: Int? = null, @SerialName("type") val type: String? = null, @SerialName("name") val name: String? = null, - @SerialName("imdb_id") val imdbId: String? = null, - @SerialName("tmdb_id") val tmdbId: Long? = null, - @SerialName("first_air_date") val firstAirDate: String? = null, + @JsonProperty("imdb_id") @SerialName("imdb_id") val imdbId: String? = null, + @JsonProperty("tmdb_id") @SerialName("tmdb_id") val tmdbId: Long? = null, + @JsonProperty("first_air_date") @SerialName("first_air_date") val firstAirDate: String? = null, @SerialName("year") val year: Int? = null, ) @Serializable data class Subtitle( - @SerialName("release_name") val releaseName: String, + @JsonProperty("release_name") @SerialName("release_name") val releaseName: String, @SerialName("name") val name: String, @SerialName("lang") val lang: String, // subdl language code @SerialName("author") val author: String? = null, @@ -193,7 +194,7 @@ class SubDlApi : SubtitleAPI() { @SerialName("season") val season: Int? = null, @SerialName("episode") val episode: Int? = null, @SerialName("language") val language: String? = null, // full language name - @SerialName("hi") val hearingImpaired: Boolean? = null, + @JsonProperty("hi") @SerialName("hi") val hearingImpaired: Boolean? = null, ) // https://subdl.com/api-files/language_list.json From 8894d814b5c87ff28ee00b739335c3cfc064b26f Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:41:24 -0600 Subject: [PATCH 3/3] Keep all JsonProperty for now --- .../syncproviders/providers/Subdl.kt | 186 +++++++++--------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt index ff95e77895e..8029374292c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/Subdl.kt @@ -126,78 +126,78 @@ class SubDlApi : SubtitleAPI() { @Serializable data class SubtitleOAuthEntity( - @SerialName("userEmail") var userEmail: String, - @SerialName("pass") var pass: String, - @SerialName("name") var name: String? = null, - @SerialName("accessToken") var accessToken: String? = null, - @SerialName("apiKey") var apiKey: String? = null, + @JsonProperty("userEmail") @SerialName("userEmail") var userEmail: String, + @JsonProperty("pass") @SerialName("pass") var pass: String, + @JsonProperty("name") @SerialName("name") var name: String? = null, + @JsonProperty("accessToken") @SerialName("accessToken") var accessToken: String? = null, + @JsonProperty("apiKey") @SerialName("apiKey") var apiKey: String? = null, ) @Serializable data class OAuthTokenResponse( - @SerialName("token") val token: String, - @SerialName("userData") val userData: UserData? = null, - @SerialName("status") val status: Boolean? = null, - @SerialName("message") val message: String? = null, + @JsonProperty("token") @SerialName("token") val token: String, + @JsonProperty("userData") @SerialName("userData") val userData: UserData? = null, + @JsonProperty("status") @SerialName("status") val status: Boolean? = null, + @JsonProperty("message") @SerialName("message") val message: String? = null, ) @Serializable data class UserData( - @SerialName("email") val email: String, - @SerialName("name") val name: String, - @SerialName("country") val country: String, - @SerialName("scStepCode") val scStepCode: String, - @SerialName("scVerified") val scVerified: Boolean, - @SerialName("username") val username: String? = null, - @SerialName("scUsername") val scUsername: String, + @JsonProperty("email") @SerialName("email") val email: String, + @JsonProperty("name") @SerialName("name") val name: String, + @JsonProperty("country") @SerialName("country") val country: String, + @JsonProperty("scStepCode") @SerialName("scStepCode") val scStepCode: String, + @JsonProperty("scVerified") @SerialName("scVerified") val scVerified: Boolean, + @JsonProperty("username") @SerialName("username") val username: String? = null, + @JsonProperty("scUsername") @SerialName("scUsername") val scUsername: String, ) @Serializable data class ApiKeyResponse( - @SerialName("ok") val ok: Boolean? = false, + @JsonProperty("ok") @SerialName("ok") val ok: Boolean? = false, @JsonProperty("api_key") @SerialName("api_key") val apiKey: String, - @SerialName("usage") val usage: Usage? = null, + @JsonProperty("usage") @SerialName("usage") val usage: Usage? = null, ) @Serializable data class Usage( - @SerialName("total") val total: Long? = 0, - @SerialName("today") val today: Long? = 0, + @JsonProperty("total") @SerialName("total") val total: Long? = 0, + @JsonProperty("today") @SerialName("today") val today: Long? = 0, ) @Serializable data class ApiResponse( - @SerialName("status") val status: Boolean? = null, - @SerialName("results") val results: List? = null, - @SerialName("subtitles") val subtitles: List? = null, + @JsonProperty("status") @SerialName("status") val status: Boolean? = null, + @JsonProperty("results") @SerialName("results") val results: List? = null, + @JsonProperty("subtitles") @SerialName("subtitles") val subtitles: List? = null, ) @Serializable data class Result( @JsonProperty("sd_id") @SerialName("sd_id") val sdId: Int? = null, - @SerialName("type") val type: String? = null, - @SerialName("name") val name: String? = null, + @JsonProperty("type") @SerialName("type") val type: String? = null, + @JsonProperty("name") @SerialName("name") val name: String? = null, @JsonProperty("imdb_id") @SerialName("imdb_id") val imdbId: String? = null, @JsonProperty("tmdb_id") @SerialName("tmdb_id") val tmdbId: Long? = null, @JsonProperty("first_air_date") @SerialName("first_air_date") val firstAirDate: String? = null, - @SerialName("year") val year: Int? = null, + @JsonProperty("year") @SerialName("year") val year: Int? = null, ) @Serializable data class Subtitle( @JsonProperty("release_name") @SerialName("release_name") val releaseName: String, - @SerialName("name") val name: String, - @SerialName("lang") val lang: String, // subdl language code - @SerialName("author") val author: String? = null, - @SerialName("url") val url: String? = null, - @SerialName("subtitlePage") val subtitlePage: String? = null, - @SerialName("season") val season: Int? = null, - @SerialName("episode") val episode: Int? = null, - @SerialName("language") val language: String? = null, // full language name + @JsonProperty("name") @SerialName("name") val name: String, + @JsonProperty("lang") @SerialName("lang") val lang: String, // subdl language code + @JsonProperty("author") @SerialName("author") val author: String? = null, + @JsonProperty("url") @SerialName("url") val url: String? = null, + @JsonProperty("subtitlePage") @SerialName("subtitlePage") val subtitlePage: String? = null, + @JsonProperty("season") @SerialName("season") val season: Int? = null, + @JsonProperty("episode") @SerialName("episode") val episode: Int? = null, + @JsonProperty("language") @SerialName("language") val language: String? = null, // full language name @JsonProperty("hi") @SerialName("hi") val hearingImpaired: Boolean? = null, ) - // https://subdl.com/api-files/language_list.json + // https://subdl.com/api-files/language_list.json // most of it is IETF BPC 47 conformant tag // but there are some exceptions private val langTagIETF2subdl = mapOf( @@ -207,63 +207,63 @@ class SubDlApi : SubtitleAPI() { "en-nl" to "NL_EN", // "Dutch_English" "pt-br" to "BR_PT", // "Brazillian Portuguese" "zh-hant" to "ZH_BG", // "Big 5 code" -> traditional Chinese (?_?) - // "ar" to "AR", // "Arabic" - // "az" to "AZ", // "Azerbaijani" - // "be" to "BE", // "Belarusian" - // "bg" to "BG", // "Bulgarian" - // "bn" to "BN", // "Bengali" - // "bs" to "BS", // "Bosnian" - // "ca" to "CA", // "Catalan" - // "cs" to "CS", // "Czech" - // "da" to "DA", // "Danish" - // "de" to "DE", // "German" - // "el" to "EL", // "Greek" - // "en" to "EN", // "English" - // "eo" to "EO", // "Esperanto" - // "es" to "ES", // "Spanish" - // "et" to "ET", // "Estonian" - // "fa" to "FA", // "Farsi_Persian" - // "fi" to "FI", // "Finnish" - // "fr" to "FR", // "French" - // "he" to "HE", // "Hebrew" - // "hi" to "HI", // "Hindi" - // "hr" to "HR", // "Croatian" - // "hu" to "HU", // "Hungarian" - // "id" to "ID", // "Indonesian" - // "is" to "IS", // "Icelandic" - // "it" to "IT", // "Italian" - // "ja" to "JA", // "Japanese" - // "ka" to "KA", // "Georgian" - // "kl" to "KL", // "Greenlandic" - // "ko" to "KO", // "Korean" - // "ku" to "KU", // "Kurdish" - // "lt" to "LT", // "Lithuanian" - // "lv" to "LV", // "Latvian" - // "mk" to "MK", // "Macedonian" - // "ml" to "ML", // "Malayalam" - // "mni" to "MNI", // "Manipuri" - // "ms" to "MS", // "Malay" - // "my" to "MY", // "Burmese" - // "nl" to "NL", // "Dutch" - // "no" to "NO", // "Norwegian" - // "pl" to "PL", // "Polish" - // "pt" to "PT", // "Portuguese" - // "ro" to "RO", // "Romanian" - // "ru" to "RU", // "Russian" - // "si" to "SI", // "Sinhala" - // "sk" to "SK", // "Slovak" - // "sl" to "SL", // "Slovenian" - // "sq" to "SQ", // "Albanian" - // "sr" to "SR", // "Serbian" - // "sv" to "SV", // "Swedish" - // "ta" to "TA", // "Tamil" - // "te" to "TE", // "Telugu" - // "th" to "TH", // "Thai" - // "tl" to "TL", // "Tagalog" - // "tr" to "TR", // "Turkish" - // "uk" to "UK", // "Ukranian" - // "ur" to "UR", // "Urdu" - // "vi" to "VI", // "Vietnamese" - // "zh" to "ZH", // "Chinese BG code" + // "ar" to "AR", // "Arabic" + // "az" to "AZ", // "Azerbaijani" + // "be" to "BE", // "Belarusian" + // "bg" to "BG", // "Bulgarian" + // "bn" to "BN", // "Bengali" + // "bs" to "BS", // "Bosnian" + // "ca" to "CA", // "Catalan" + // "cs" to "CS", // "Czech" + // "da" to "DA", // "Danish" + // "de" to "DE", // "German" + // "el" to "EL", // "Greek" + // "en" to "EN", // "English" + // "eo" to "EO", // "Esperanto" + // "es" to "ES", // "Spanish" + // "et" to "ET", // "Estonian" + // "fa" to "FA", // "Farsi_Persian" + // "fi" to "FI", // "Finnish" + // "fr" to "FR", // "French" + // "he" to "HE", // "Hebrew" + // "hi" to "HI", // "Hindi" + // "hr" to "HR", // "Croatian" + // "hu" to "HU", // "Hungarian" + // "id" to "ID", // "Indonesian" + // "is" to "IS", // "Icelandic" + // "it" to "IT", // "Italian" + // "ja" to "JA", // "Japanese" + // "ka" to "KA", // "Georgian" + // "kl" to "KL", // "Greenlandic" + // "ko" to "KO", // "Korean" + // "ku" to "KU", // "Kurdish" + // "lt" to "LT", // "Lithuanian" + // "lv" to "LV", // "Latvian" + // "mk" to "MK", // "Macedonian" + // "ml" to "ML", // "Malayalam" + // "mni" to "MNI", // "Manipuri" + // "ms" to "MS", // "Malay" + // "my" to "MY", // "Burmese" + // "nl" to "NL", // "Dutch" + // "no" to "NO", // "Norwegian" + // "pl" to "PL", // "Polish" + // "pt" to "PT", // "Portuguese" + // "ro" to "RO", // "Romanian" + // "ru" to "RU", // "Russian" + // "si" to "SI", // "Sinhala" + // "sk" to "SK", // "Slovak" + // "sl" to "SL", // "Slovenian" + // "sq" to "SQ", // "Albanian" + // "sr" to "SR", // "Serbian" + // "sv" to "SV", // "Swedish" + // "ta" to "TA", // "Tamil" + // "te" to "TE", // "Telugu" + // "th" to "TH", // "Thai" + // "tl" to "TL", // "Tagalog" + // "tr" to "TR", // "Turkish" + // "uk" to "UK", // "Ukranian" + // "ur" to "UR", // "Urdu" + // "vi" to "VI", // "Vietnamese" + // "zh" to "ZH", // "Chinese BG code" ) }