JellyGlass/backend/src/Repositories/JellyfinApiClient.cs
2026-02-22 21:58:23 +00:00

160 lines
No EOL
3.8 KiB
C#

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<Item[]> GetInstanceLibraries()
{
try
{
var request = new HttpRequestMessage(HttpMethod.Get, $"{InstanceUrl}/Library/MediaFolders");
var response = await MakeRequest(request);
response.EnsureSuccessStatusCode();
var apiResponse = await response.Content.ReadFromJsonAsync<ItemResponse>();
return apiResponse.Items.ToArray();
}
catch (HttpRequestException e)
{
throw new JellyfinApiClientException(e.Message);
}
}
public async Task<Item[]> 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<ItemResponse>();
return apiResponse!.Items.ToArray();
}
catch (HttpRequestException e)
{
throw new JellyfinApiClientException(e.Message);
}
}
public async Task<Item[]> 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<ItemResponse>();
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<AuthResponse>();
_apiKey = authResponse!.AccessToken;
ID = authResponse.ServerId;
}
catch (HttpRequestException e)
{
//TODO: What to do on an exception
throw new JellyfinApiClientException(e.Message);
}
}
private async Task<HttpResponseMessage> 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;
}
}