All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.org.jellyfin.sdk.api.client.ApiClient.kt Maven / Gradle / Ivy

package org.jellyfin.sdk.api.client

import org.jellyfin.sdk.api.client.exception.MissingBaseUrlException
import org.jellyfin.sdk.api.client.util.UrlBuilder
import org.jellyfin.sdk.api.operations.Api
import org.jellyfin.sdk.api.sockets.SocketInstance
import org.jellyfin.sdk.model.ClientInfo
import org.jellyfin.sdk.model.DeviceInfo
import org.jellyfin.sdk.model.UUID
import kotlin.reflect.KClass

public abstract class ApiClient {
	public companion object {
		/**
		 * The query parameter to use for access tokens. Used in the [createUrl] function when includeCredentials is
		 * true.
		 */
		public const val QUERY_ACCESS_TOKEN: String = "ApiKey"

		/**
		 * The recommended value for the accept header. It prefers JSON followed by octet stream and finally
		 * everything. The "any MIME type" (* / *) is required for some endpoints in the server.
		 */
		public const val HEADER_ACCEPT: String = "application/json, application/octet-stream;q=0.9, */*;q=0.8"
	}

	/**
	 * URL to use as base for API endpoints. Should include the protocol and may contain a path.
	 */
	public abstract var baseUrl: String?

	/**
	 * Access token to use for requests. Appended to all requests if set.
	 */
	public abstract var accessToken: String?

	/**
	 * User identifier that will automatically be used in user-specific API operations.
	 * Should correspond to the same user as [accessToken].
	 */
	public abstract var userId: UUID?

	/**
	 * Information about the client / application send in all API requests.
	 */
	public abstract var clientInfo: ClientInfo

	/**
	 * Information about the device send in all API requests. Only a single session is allowed per
	 * device id.
	 */
	public abstract var deviceInfo: DeviceInfo

	/**
	 * HTTP Options for this ApiClient.
	 */
	public abstract val httpClientOptions: HttpClientOptions

	/**
	 * Create a complete url based on the [baseUrl] and given parameters.
	 * Uses [UrlBuilder] to create the path from the [pathTemplate] and [pathParameters].
	 *
	 * When [includeCredentials] is true it will add the access token as query parameter using [QUERY_ACCESS_TOKEN]
	 * to the url to make an authenticated request.
	 *
	 * When [ignorePathParameters] is true, the [pathParameters] will be ignored and [pathTemplate] will not be parsed.
	 */
	public open fun createUrl(
		pathTemplate: String,
		pathParameters: Map = emptyMap(),
		queryParameters: Map = emptyMap(),
		includeCredentials: Boolean = false,
		ignorePathParameters: Boolean = false,
	): String = UrlBuilder.buildUrl(
		baseUrl ?: throw MissingBaseUrlException(),
		pathTemplate,
		pathParameters,
		queryParameters.run {
			if (includeCredentials) plus(QUERY_ACCESS_TOKEN to checkNotNull(accessToken))
			else this
		},
		ignorePathParameters,
	)

	public abstract suspend fun request(
		method: HttpMethod = HttpMethod.GET,
		pathTemplate: String,
		pathParameters: Map = emptyMap(),
		queryParameters: Map = emptyMap(),
		requestBody: Any? = null,
	): RawResponse

	public abstract fun ws(): SocketInstance

	private val apiInstances = mutableMapOf, Api>()

	@Suppress("UNCHECKED_CAST")
	public fun  getOrCreateApi(kclass: KClass, create: (apiClient: ApiClient) -> T): T =
		apiInstances.getOrPut(kclass) {
			create(this)
		} as T

	public inline fun  getOrCreateApi(noinline create: (apiClient: ApiClient) -> T): T =
		getOrCreateApi(T::class, create)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy