jel/Jel/Controllers/JellyfinClientController.swift

131 lines
3.4 KiB
Swift

//
// JellyfinClientController.swift
// Jel
//
// Created by zerocool on 12/12/23.
//
import Foundation
import Get
import JellyfinKit
import Pulse
struct AuthHeaders: Codable {
var Client: String
var Device: String
var DeviceId: String
var Version: String
var Token: String
}
enum JellyfinClientError: Error {
case badResponseCode
}
extension AuthHeaders {
func format() -> String {
return "MediaBrowser Client=\(self.Client), Device=\(self.Device), DeviceId=\(self.DeviceId), Version=\(self.Version), Token=\(self.Token)"
}
}
class JellyfinClientController: ObservableObject {
private var api: APIClient
private var authHeaders: AuthHeaders
private var authState: AuthStateController
init(authHeaders: AuthHeaders, serverUrl: URL? = nil, authState: AuthStateController = AuthStateController.shared) {
self.authHeaders = authHeaders
self.authState = authState
self.api = APIClient(baseURL: serverUrl)
self.setUrl(url: serverUrl)
self.setToken(token: self.authState.authToken ?? "")
}
func setToken(token: String) {
self.authHeaders.Token = token
self.setUrl(url: self.authState.serverUrl)
}
func setUrl(url: URL?) {
if url == nil {
return
}
self.api = APIClient(baseURL: url, {
$0.sessionConfiguration.httpAdditionalHeaders = ["Authorization": self.authHeaders.format()]
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601withFractionalSeconds
$0.decoder = decoder
$0.sessionDelegate = Pulse.URLSessionProxyDelegate()
})
}
func getUrl() -> URL? {
return self.api.configuration.baseURL
}
@discardableResult func send<T>(
_ request: Request<T>,
delegate: URLSessionDataDelegate? = nil,
configure: ((inout URLRequest) throws -> Void)? = nil
) async throws -> Response<T> where T : Decodable {
return try await self.api.send(request, delegate: delegate, configure: configure)
}
@discardableResult func send(
_ request: Request<Void>,
delegate: URLSessionDataDelegate? = nil,
configure: ((inout URLRequest) throws -> Void)? = nil
) async throws -> Response<Void> {
return try await self.api.send(request, delegate: delegate, configure: configure)
}
}
extension JellyfinClientController {
func getPublicServerInfo() async -> PublicSystemInfo? {
let request = Paths.getPublicSystemInfo
do {
let res = try await api.send(request)
if res.statusCode != 200 {
throw JellyfinClientError.badResponseCode
}
return res.value
} catch {
return nil
}
}
func signIn(username: String, pw: String) async throws {
let request = Paths.authenticateUserByName(AuthenticateUserByName(pw: pw, username: username))
let res = try await self.api.send(request)
DispatchQueue.main.async {
self.authState.loggedIn = true
self.authState.authToken = res.value.accessToken
self.authState.userId = res.value.user?.id
self.authState.username = username
self.authState.save()
self.setToken(token: self.authState.authToken ?? "")
}
}
func search(parameters: Paths.GetParameters) async -> SearchHintResult? {
let request = Paths.get(parameters: parameters)
do {
let res = try await self.api.send(request)
return res.value
} catch {
}
return nil
}
}