// // JellyfinClient+System.swift // // Copyright 2026 Brendan Szymanski // // 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 . // // 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 ) } } }