Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ enum class ConfigPropertyKey(val key: String) {
CRUNCHYROLL_FETCH_API_SIZE("crunchyroll_fetch_api_size"),
DISABLE_BOT_DETECTION("disable_bot_detection"),
DISCORD_TOKEN("discord_token"),
DISNEY_PLUS_ACCESS_TOKEN("disney_plus_access_token"),
DISNEY_PLUS_AUTHORIZATION("disney_plus_authorization"),
DISNEY_PLUS_REFRESH_TOKEN("disney_plus_refresh_token"),
EMAIL_HOST("email_host"),
EMAIL_PASSWORD("email_password"),
EMAIL_PORT("email_port"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
package fr.shikkanime.wrappers.factories

import com.google.gson.reflect.TypeToken
import fr.shikkanime.entities.Config
import fr.shikkanime.entities.enums.ConfigPropertyKey
import fr.shikkanime.services.ConfigService
import fr.shikkanime.services.caches.ConfigCacheService
import fr.shikkanime.utils.Constant
import fr.shikkanime.utils.HttpRequest
import fr.shikkanime.utils.MapCache
import fr.shikkanime.utils.MapCacheValue
import fr.shikkanime.utils.ObjectParser
import fr.shikkanime.utils.ObjectParser.getAsString
import fr.shikkanime.utils.StringUtils
import io.ktor.client.statement.bodyAsText
import io.ktor.http.*
import kotlinx.coroutines.runBlocking
import java.io.Serializable
import java.time.Duration

abstract class AbstractDisneyPlusWrapper : IStreamingPlatformWrapper<String, AbstractDisneyPlusWrapper.Show, AbstractDisneyPlusWrapper.Episode> {
data class Show(
Expand Down Expand Up @@ -78,9 +89,42 @@ abstract class AbstractDisneyPlusWrapper : IStreamingPlatformWrapper<String, Abs

protected val baseUrl = "https://disney.api.edge.bamgrid.com/"
protected val configCacheService: ConfigCacheService by lazy { Constant.injector.getInstance(ConfigCacheService::class.java) }
protected val configService: ConfigService by lazy { Constant.injector.getInstance(ConfigService::class.java) }

protected suspend fun HttpRequest.getWithAccessToken(url: String) = get(url, headers = mapOf(HttpHeaders.Authorization to "Bearer ${configCacheService.getValueAsString(ConfigPropertyKey.DISNEY_PLUS_ACCESS_TOKEN)}"))
protected suspend fun HttpRequest.postWithAccessToken(url: String, headers: Map<String, String>, body: String) = post(url, headers = mapOf(HttpHeaders.Authorization to "Bearer ${configCacheService.getValueAsString(ConfigPropertyKey.DISNEY_PLUS_ACCESS_TOKEN)}").plus(headers), body = body)
@Synchronized
private fun getAccessToken() = MapCache.getOrCompute(
"AbstractDisneyPlusWrapper.getAccessToken",
duration = Duration.ofHours(2),
classes = listOf(Config::class.java),
typeToken = object : TypeToken<MapCacheValue<String>>() {},
key = StringUtils.EMPTY_STRING
) {
runBlocking {
val refreshTokenConfig = configService.findByName(ConfigPropertyKey.DISNEY_PLUS_REFRESH_TOKEN.name)
if (refreshTokenConfig == null || refreshTokenConfig.propertyValue.isNullOrBlank())
throw IllegalStateException("Disney Plus refresh token is not set")

val response = HttpRequest.post(
"https://login.disney.com/token",
headers = mapOf(
HttpHeaders.ContentType to ContentType.Application.FormUrlEncoded.toString(),
"X-Dss-Client-Api-Key" to (configCacheService.getValueAsString(ConfigPropertyKey.DISNEY_PLUS_AUTHORIZATION) ?: StringUtils.EMPTY_STRING)
),
body = "grant_type=refresh_token&client_id=DTCI-DISNEYPLUS.WEB&scope=openid streaming api:identity:user.write&refresh_token=${refreshTokenConfig.propertyValue}"
)
require(response.status == HttpStatusCode.OK) { "Failed to get access token (${response.status.value})" }
val json = ObjectParser.fromJson(response.bodyAsText())

// Change refresh token
refreshTokenConfig.propertyValue = requireNotNull(json.getAsString("refresh_token")) { "Refresh token is null or empty"}
configService.update(refreshTokenConfig)

requireNotNull(json.getAsString("access_token")) { "Access token is null or empty"}
}
}

protected suspend fun HttpRequest.getWithAccessToken(url: String) = get(url, headers = mapOf(HttpHeaders.Authorization to "Bearer ${getAccessToken()}"))
protected suspend fun HttpRequest.postWithAccessToken(url: String, headers: Map<String, String>, body: String) = post(url, headers = mapOf(HttpHeaders.Authorization to "Bearer ${getAccessToken()}").plus(headers), body = body)

abstract suspend fun getLatestShowIds(): Array<String>

Expand Down
48 changes: 48 additions & 0 deletions src/main/resources/db/changelog/2026/10/02-changelog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<property global="false" name="id" value="1792414317967"/>
<property global="false" name="author" value="Ziedelth"/>

<changeSet id="${id}-1" author="${author}" dbms="postgresql">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="1">SELECT COUNT(*)
FROM config
WHERE property_key = 'disney_plus_access_token'</sqlCheck>
</preConditions>

<delete tableName="config">
<where>property_key = 'disney_plus_access_token'</where>
</delete>
</changeSet>

<changeSet id="${id}-2" author="${author}" dbms="postgresql">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">SELECT COUNT(*)
FROM config
WHERE property_key = 'disney_plus_authorization'</sqlCheck>
</preConditions>

<insert tableName="config">
<column name="uuid" valueComputed="gen_random_uuid()"/>
<column name="property_key" value="disney_plus_authorization"/>
<column name="property_value" value=""/>
</insert>
</changeSet>

<changeSet id="${id}-3" author="${author}" dbms="postgresql">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">SELECT COUNT(*)
FROM config
WHERE property_key = 'disney_plus_refresh_token'</sqlCheck>
</preConditions>

<insert tableName="config">
<column name="uuid" valueComputed="gen_random_uuid()"/>
<column name="property_key" value="disney_plus_refresh_token"/>
<column name="property_value" value=""/>
</insert>
</changeSet>
</databaseChangeLog>
1 change: 1 addition & 0 deletions src/main/resources/db/changelog/db.changelog-master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,5 @@
<!-- September 2026 -->
<!-- October 2026 -->
<include file="/db/changelog/2026/10/01-changelog.xml"/>
<include file="/db/changelog/2026/10/02-changelog.xml"/>
</databaseChangeLog>
Loading