luminate/Sources/LuminateServices/Discovery/JellyfinClient+System.swift

77 lines
3.2 KiB
Swift

//
// JellyfinClient+System.swift
//
// Copyright 2026 Brendan Szymanski <hello@bscubed.dev>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
import LuminateAPI
import LuminateCore
/// Server discovery and identification.
extension JellyfinClient {
/// Fetches the identifying details a server exposes without authentication.
///
/// This doubles as Luminate's connection test: it is the cheapest call that proves a URL points
/// at a reachable Jellyfin server, and it needs no token.
///
/// - Returns: The server's public information.
/// - Throws: ``JellyfinClientError/serviceUnavailable(retryAfterSeconds:)`` while the server is
/// starting, ``JellyfinClientError/unexpectedStatus(operation:statusCode:)`` for any other
/// status, or a transport error if the host is unreachable.
package func publicServerInfo() async throws -> JellyfinServerInfo {
switch try await current.getPublicSystemInfo(.init()) {
case .ok(let response):
return JellyfinServerInfo(response.body.payload)
case .serviceUnavailable(let response):
throw JellyfinClientError.serviceUnavailable(
retryAfterSeconds: response.headers.retryAfter
)
case .undocumented(let statusCode, _):
throw JellyfinClientError.unexpectedStatus(
operation: Operations.GetPublicSystemInfo.id,
statusCode: statusCode
)
}
}
/// Fetches the full identifying details of the signed-in server.
///
/// - Returns: The server's information.
/// - Throws: ``JellyfinClientError/unauthorized`` if the token is missing or rejected,
/// ``JellyfinClientError/forbidden`` if the account may not read it, or
/// ``JellyfinClientError/serviceUnavailable(retryAfterSeconds:)`` while the server is starting.
package func serverInfo() async throws -> JellyfinServerInfo {
switch try await current.getSystemInfo(.init()) {
case .ok(let response):
return JellyfinServerInfo(response.body.payload)
case .forbidden:
throw JellyfinClientError.forbidden
case .serviceUnavailable(let response):
throw JellyfinClientError.serviceUnavailable(
retryAfterSeconds: response.headers.retryAfter
)
case .unauthorized:
throw JellyfinClientError.unauthorized
case .undocumented(let statusCode, _):
throw JellyfinClientError.unexpectedStatus(
operation: Operations.GetSystemInfo.id,
statusCode: statusCode
)
}
}
}