From 4d3e88b9f54e893a6de49724538cd73c9dc6ea5f Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Wed, 29 Apr 2026 23:26:18 +1000 Subject: v0.13a --- HyperBooru.cs | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 HyperBooru.cs (limited to 'HyperBooru.cs') diff --git a/HyperBooru.cs b/HyperBooru.cs new file mode 100644 index 0000000..dac901a --- /dev/null +++ b/HyperBooru.cs @@ -0,0 +1,82 @@ +using HyperBooru.ApiModels; +using System.Net; +using System.Net.Http.Json; + +namespace HyperBooru.ApiClient; + +public sealed class HBSession : IDisposable { + public Media Media { get; private init; } + public Tag Tag { get; private init; } + public Uri BaseUri { get; private init; } + + internal HttpClient HttpClient { get; private init; } + + public HBSession ( + Uri baseUri, + bool skipCertificateCheck) { + + BaseUri = new($"{baseUri.Scheme}://{baseUri.Host}:{baseUri.Port}/"); + + var handler = new HttpClientHandler() { + AllowAutoRedirect = true, + UseCookies = true, + CookieContainer = new CookieContainer() + }; + + if(skipCertificateCheck) { + handler.ClientCertificateOptions = ClientCertificateOption.Manual; + handler.ServerCertificateCustomValidationCallback = + (request, cert, certChain, policyErrors) => true; + } + + HttpClient = new(new ErrorHandler(handler)) { + BaseAddress = BaseUri + }; + + Media = new(this); + Tag = new(this); + } + + public async Task LoginAsync(string username, string password) { + var formData = new FormUrlEncodedContent(new[] { + new KeyValuePair("username", username), + new KeyValuePair("password", password) + }); + + var resp = await HttpClient.PostAsync($"/Login", formData); + + if(resp.StatusCode == HttpStatusCode.Forbidden) { + throw new Exception("Invalid username or password"); + } else if(!resp.IsSuccessStatusCode) { + var content = await resp.Content.ReadAsStringAsync(); + throw new Exception($"Unknown error while logging in: {content}"); + } + } + + public async Task LogoutAsync() => + await HttpClient.PostAsync("/Logout", null); + + public void Dispose() => + HttpClient.Dispose(); +} + +public class ErrorHandler : DelegatingHandler { + public ErrorHandler(HttpMessageHandler innerHandler) : base(innerHandler) {} + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken ct) { + var resp = await base.SendAsync(request, ct); + + if(resp.IsSuccessStatusCode) + return resp; + + HBException e; + try { + e = await resp.Content.ReadFromJsonAsync(ct) ?? + throw new NullReferenceException(); + } catch { + throw new HBException("An unknown error occurred"); + } + + throw e; + } +} -- cgit v1.3