using System.Net; using System.Net.Http.Headers; using System.Text; using System.Text.Json; using JellyGlass.Exceptions; using JellyGlass.Models; using JellyGlass.Models.JellyfinApi; namespace JellyGlass.Repositories; public class JellyfinApiClient { private string _apiKey = string.Empty; public readonly string InstanceUrl; private readonly HttpClient _client; private readonly string _username, _password; public string ID { get; private set; } = string.Empty; public JellyfinApiClient(string instanceUrl, string username, string password) { InstanceUrl = instanceUrl; _client = new HttpClient(); _client.DefaultRequestHeaders.Clear(); _username = username; _password = password; } public async Task GetInstanceLibraries() { try { var request = new HttpRequestMessage(HttpMethod.Get, $"{InstanceUrl}/Library/MediaFolders"); var response = await MakeRequest(request); response.EnsureSuccessStatusCode(); var apiResponse = await response.Content.ReadFromJsonAsync(); return apiResponse.Items.ToArray(); } catch (HttpRequestException e) { throw new JellyfinApiClientException(e.Message); } } public async Task GetItemChildren(string itemId) { try { var request = new HttpRequestMessage(HttpMethod.Get, $"{InstanceUrl}/items?ParentId={itemId}"); var response = await MakeRequest(request); response.EnsureSuccessStatusCode(); var apiResponse = await response.Content.ReadFromJsonAsync(); return apiResponse!.Items.ToArray(); } catch (HttpRequestException e) { throw new JellyfinApiClientException(e.Message); } } public async Task GetItems(string searchTerm = "", string years = "", string itemTypes = "", string limit = "", string parentId = "") { try { var request = new HttpRequestMessage(HttpMethod.Get, $"{InstanceUrl}/items?searchTerm={searchTerm}&recursive=true&includeItemTypes=Series,Movie"); var response = await MakeRequest(request); response.EnsureSuccessStatusCode(); var apiResponse = await response.Content.ReadFromJsonAsync(); return apiResponse!.Items.ToArray(); } catch (HttpRequestException e) { throw new JellyfinApiClientException(e.Message); } } public async Task Authenticate() { var request = new HttpRequestMessage(HttpMethod.Post, $"{InstanceUrl}/Users/AuthenticateByName"); request.Headers.Authorization = new AuthenticationHeaderValue("MediaBrowser", GetAuthHeader()); var body = new { Username = _username, Pw = _password }; request.Content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json"); try { var response = await _client.SendAsync(request); response.EnsureSuccessStatusCode(); var authResponse = await response.Content.ReadFromJsonAsync(); _apiKey = authResponse!.AccessToken; ID = authResponse.ServerId; } catch (HttpRequestException e) { //TODO: What to do on an exception throw new JellyfinApiClientException(e.Message); } } private async Task MakeRequest(HttpRequestMessage request) { request.Headers.Authorization = new AuthenticationHeaderValue("MediaBrowser", GetAuthHeader()); HttpResponseMessage response; try { response = await _client.SendAsync(request); } catch (HttpRequestException e) { if (e.StatusCode == HttpStatusCode.Unauthorized) { await Authenticate(); request.Headers.Authorization = new AuthenticationHeaderValue("MediaBrowser", GetAuthHeader()); response = await _client.SendAsync(request); } else { throw new JellyfinApiClientException(e.Message); } } return response; } private string GetAuthHeader() { var header = "Client=Test, Device=Test, DeviceId=Test, Version=1"; if (_apiKey != String.Empty) { header += ", Token=" + _apiKey; } return header; } }