-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve the customizable HttpClient configuration
1 parent
817b551
commit ae8131a
Showing
12 changed files
with
315 additions
and
201 deletions.
There are no files selected for viewing
132 changes: 84 additions & 48 deletions
132
tmdb-api/src/commonMain/kotlin/app/moviebase/tmdb/Tmdb3.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,89 @@ | ||
package app.moviebase.tmdb | ||
|
||
import app.moviebase.tmdb.api.* | ||
import app.moviebase.tmdb.remote.TmdbHttpClientFactory | ||
import app.moviebase.tmdb.remote.TmdbLogLevel | ||
import app.moviebase.tmdb.remote.TmdbSessionProvider | ||
import io.ktor.client.* | ||
|
||
class Tmdb3( | ||
tmdbApiKey: String, | ||
logLevel: TmdbLogLevel = TmdbLogLevel.NONE, | ||
tmdbSessionProvider: TmdbSessionProvider? = null, | ||
httpClientConfigBlock: (HttpClientConfig<*>.() -> Unit)? = null, | ||
) { | ||
private val client: HttpClient = TmdbHttpClientFactory.create( | ||
tmdbApiKey = tmdbApiKey, | ||
logLevel = logLevel, | ||
httpClientConfigBlock = httpClientConfigBlock, | ||
) | ||
private val clientWithSession: HttpClient = TmdbHttpClientFactory.createWithSession( | ||
tmdbApiKey = tmdbApiKey, | ||
logLevel = logLevel, | ||
tmdbSessionProvider = tmdbSessionProvider, | ||
httpClientConfigBlock = httpClientConfigBlock, | ||
) | ||
|
||
val account = TmdbAccountApi(clientWithSession) | ||
val authentication = TmdbAuthenticationApi(client) | ||
val certifications = TmdbCertificationsApi(client) | ||
val changes = TmdbChangesApi(client) | ||
val collections = TmdbCollectionsApi(client) | ||
val companies = TmdbCompaniesApi(client) | ||
val configuration = TmdbConfigurationApi(client) | ||
val credits = TmdbCreditsApi(client) | ||
val discover = TmdbDiscoverApi(client) | ||
val find = TmdbFindApi(client) | ||
val genres = TmdbGenresApi(client) | ||
val guestSessions = TmdbGuestSessionsApi(client) | ||
val keywords = TmdbKeywordsApi(client) | ||
val lists = TmdbListsApi(client) | ||
val movies = TmdbMoviesApi(client) | ||
val networks = TmdbNetworksApi(client) | ||
val trending = TmdbTrendingApi(client) | ||
val people = TmdbPeopleApi(client) | ||
val reviews = TmdbReviewsApi(client) | ||
val search = TmdbSearchApi(client) | ||
val show = TmdbShowApi(client) | ||
val showSeasons = TmdbShowSeasonsApi(client) | ||
val showEpisodes = TmdbShowEpisodesApi(client) | ||
val showEpisodeGroups = TmdbShowEpisodeGroupsApi(client) | ||
import app.moviebase.tmdb.api.TmdbAccountApi | ||
import app.moviebase.tmdb.api.TmdbAuthenticationApi | ||
import app.moviebase.tmdb.api.TmdbCertificationsApi | ||
import app.moviebase.tmdb.api.TmdbChangesApi | ||
import app.moviebase.tmdb.api.TmdbCollectionsApi | ||
import app.moviebase.tmdb.api.TmdbCompaniesApi | ||
import app.moviebase.tmdb.api.TmdbConfigurationApi | ||
import app.moviebase.tmdb.api.TmdbCreditsApi | ||
import app.moviebase.tmdb.api.TmdbDiscoverApi | ||
import app.moviebase.tmdb.api.TmdbFindApi | ||
import app.moviebase.tmdb.api.TmdbGenresApi | ||
import app.moviebase.tmdb.api.TmdbGuestSessionsApi | ||
import app.moviebase.tmdb.api.TmdbKeywordsApi | ||
import app.moviebase.tmdb.api.TmdbListsApi | ||
import app.moviebase.tmdb.api.TmdbMoviesApi | ||
import app.moviebase.tmdb.api.TmdbNetworksApi | ||
import app.moviebase.tmdb.api.TmdbPeopleApi | ||
import app.moviebase.tmdb.api.TmdbReviewsApi | ||
import app.moviebase.tmdb.api.TmdbSearchApi | ||
import app.moviebase.tmdb.api.TmdbShowApi | ||
import app.moviebase.tmdb.api.TmdbShowEpisodeGroupsApi | ||
import app.moviebase.tmdb.api.TmdbShowEpisodesApi | ||
import app.moviebase.tmdb.api.TmdbShowSeasonsApi | ||
import app.moviebase.tmdb.api.TmdbTrendingApi | ||
import app.moviebase.tmdb.remote.HttpClientFactory | ||
import app.moviebase.tmdb.remote.TmdbDsl | ||
import app.moviebase.tmdb.remote.interceptRequest | ||
import io.ktor.client.HttpClient | ||
import io.ktor.client.request.* | ||
|
||
@TmdbDsl | ||
fun Tmdb3(block: TmdbClientConfig.() -> Unit): Tmdb3 { | ||
val config = TmdbClientConfig().apply(block) | ||
return Tmdb3(config) | ||
} | ||
|
||
class Tmdb3 internal constructor(private val config: TmdbClientConfig) { | ||
|
||
constructor(tmdbApiKey: String) : this(TmdbClientConfig.buildDefault(tmdbApiKey)) | ||
|
||
init { | ||
requireNotNull(config.tmdbApiKey) { | ||
"TMDB API key unavailable. Set the tmdbApiKey field in the class TmdbClientConfig when instantiate the TMDB client." | ||
} | ||
} | ||
|
||
private val client: HttpClient by lazy { | ||
HttpClientFactory.buildHttpClient(TmdbVersion.V3, config).apply { | ||
interceptRequest { | ||
it.parameter(TmdbUrlParameter.API_KEY, config.tmdbApiKey) | ||
|
||
config.tmdbCredentials?.sessionIdProvider?.invoke()?.let { sessionId -> | ||
it.parameter(TmdbUrlParameter.SESSION_ID, sessionId) | ||
} | ||
} | ||
} | ||
} | ||
|
||
val account: TmdbAccountApi by buildApi(::TmdbAccountApi) | ||
val authentication by buildApi(::TmdbAuthenticationApi) | ||
val certifications by buildApi(::TmdbCertificationsApi) | ||
val changes by buildApi(::TmdbChangesApi) | ||
val collections by buildApi(::TmdbCollectionsApi) | ||
val companies by buildApi(::TmdbCompaniesApi) | ||
val configuration by buildApi(::TmdbConfigurationApi) | ||
val credits by buildApi(::TmdbCreditsApi) | ||
val discover by buildApi(::TmdbDiscoverApi) | ||
val find by buildApi(::TmdbFindApi) | ||
val genres by buildApi(::TmdbGenresApi) | ||
val guestSessions by buildApi(::TmdbGuestSessionsApi) | ||
val keywords by buildApi(::TmdbKeywordsApi) | ||
val lists by buildApi(::TmdbListsApi) | ||
val movies by buildApi(::TmdbMoviesApi) | ||
val networks by buildApi(::TmdbNetworksApi) | ||
val trending by buildApi(::TmdbTrendingApi) | ||
val people by buildApi(::TmdbPeopleApi) | ||
val reviews by buildApi(::TmdbReviewsApi) | ||
val search by buildApi(::TmdbSearchApi) | ||
val show by buildApi(::TmdbShowApi) | ||
val showSeasons by buildApi(::TmdbShowSeasonsApi) | ||
val showEpisodes by buildApi(::TmdbShowEpisodesApi) | ||
val showEpisodeGroups by buildApi(::TmdbShowEpisodeGroupsApi) | ||
|
||
private inline fun <T> buildApi(crossinline builder: (HttpClient) -> T) = lazy { | ||
builder(client) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
tmdb-api/src/commonMain/kotlin/app/moviebase/tmdb/TmdbClientConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package app.moviebase.tmdb | ||
|
||
import app.moviebase.tmdb.remote.TmdbDsl | ||
import io.ktor.client.* | ||
import io.ktor.client.engine.* | ||
import io.ktor.client.plugins.logging.* | ||
|
||
@TmdbDsl | ||
class TmdbClientConfig { | ||
|
||
var tmdbApiKey: String? = null | ||
var tmdbAuthenticationToken: String? = null | ||
internal var tmdbCredentials: TmdbCredentials? = null | ||
|
||
var expectSuccess: Boolean = true | ||
var useCache: Boolean = false | ||
var useTimeout: Boolean = false | ||
|
||
internal var httpClientConfigBlock: (HttpClientConfig<*>.() -> Unit)? = null | ||
internal var httpClientBuilder: (() -> HttpClient)? = null | ||
internal var httpClientLoggingBlock: (Logging.Config.() -> Unit)? = null | ||
|
||
fun tmdbAccountCredentials(block: TmdbCredentials.() -> Unit) { | ||
tmdbCredentials = TmdbCredentials().apply(block) | ||
} | ||
|
||
fun logging(block: Logging.Config.() -> Unit) { | ||
httpClientLoggingBlock = block | ||
} | ||
|
||
/** | ||
* Set custom HttpClient configuration for the default HttpClient. | ||
*/ | ||
fun httpClient(block: HttpClientConfig<*>.() -> Unit) { | ||
this.httpClientConfigBlock = block | ||
} | ||
|
||
/** | ||
* Creates an custom [HttpClient] with the specified [HttpClientEngineFactory] and optional [block] configuration. | ||
* Note that the TMDB config will be added afterwards. | ||
*/ | ||
fun <T : HttpClientEngineConfig> httpClient( | ||
engineFactory: HttpClientEngineFactory<T>, | ||
block: HttpClientConfig<T>.() -> Unit = {} | ||
) { | ||
httpClientBuilder = { | ||
HttpClient(engineFactory, block) | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
internal fun buildDefault( | ||
tmdbApiKey: String, | ||
tmdbAuthenticationToken: String? = null | ||
) = TmdbClientConfig().apply { | ||
this.tmdbApiKey = tmdbApiKey | ||
this.tmdbAuthenticationToken = tmdbAuthenticationToken | ||
} | ||
} | ||
} | ||
|
||
@TmdbDsl | ||
class TmdbCredentials { | ||
|
||
internal var sessionIdProvider: (() -> String?)? = null | ||
internal var accessTokenProvider: (() -> String?)? = null | ||
internal var requestTokenProvider: (() -> String?)? = null | ||
|
||
fun sessionId(provider: () -> String?) { | ||
sessionIdProvider = provider | ||
} | ||
|
||
fun accessToken(provider: () -> String?) { | ||
accessTokenProvider = provider | ||
} | ||
|
||
fun requestToken(provider: () -> String?) { | ||
requestTokenProvider = provider | ||
} | ||
} |
16 changes: 10 additions & 6 deletions
16
tmdb-api/src/commonMain/kotlin/app/moviebase/tmdb/TmdbWebConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,24 @@ | ||
package app.moviebase.tmdb | ||
|
||
object TmdbWebConfig { | ||
|
||
internal object TmdbWebConfig { | ||
const val BASE_URL_TMDB = "https://api.themoviedb.org" | ||
const val WEBSITE_BASE_URL = "https://www.themoviedb.org" | ||
|
||
const val VERSION_PATH_V3 = "3" | ||
const val VERSION_PATH_V4 = "4" | ||
const val BASE_URL_TMDB_IMAGE = "https://image.tmdb.org/t/p/" | ||
const val BASE_URL_YOUTUBE_IMAGE = "https://img.youtube.com/vi" | ||
const val LOGO_FILTER = "_filter(negate,000,666)" | ||
|
||
const val VERSION_PATH_V3 = "3" | ||
const val VERSION_PATH_V4 = "4" | ||
const val LOGO_FILTER = "_filter(negate,000,666)" | ||
} | ||
|
||
object TmdbUrlParameter { | ||
internal object TmdbUrlParameter { | ||
const val API_KEY = "api_key" | ||
const val SESSION_ID = "session_id" | ||
const val ACCESS_TOKEN = "access_token" | ||
} | ||
|
||
internal enum class TmdbVersion(val path: String) { | ||
V3(TmdbWebConfig.VERSION_PATH_V3), | ||
V4(TmdbWebConfig.VERSION_PATH_V4) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.