test av integration mot hardcover

This commit is contained in:
2025-09-17 23:46:52 +02:00
parent 910f500460
commit 1e90a68a6e
6 changed files with 128 additions and 2 deletions

View File

@@ -11,6 +11,8 @@
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="GraphQL.Client" Version="6.1.0" />
<PackageReference Include="GraphQL.Client.Serializer.Newtonsoft" Version="6.1.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SpaProxy">
<Version>9.*-*</Version>

View File

@@ -0,0 +1,26 @@
using Bibblan.Models;
using Microsoft.Extensions.Options;
using System.Net.Http.Headers;
namespace Bibblan.Business.Clients
{
public class HardcoverAuthenticationHandler : DelegatingHandler
{
public BibblanOptions settings;
public HardcoverAuthenticationHandler(IOptions<BibblanOptions> options) : base()
{
settings = options.Value;
InnerHandler = new HttpClientHandler();
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", settings.HardcoverApiToken);
return await base.SendAsync(request, cancellationToken);
}
}
}

View File

@@ -1,19 +1,60 @@
using Bibblan.Business.Services;
using GraphQL;
using GraphQL.Client.Abstractions;
using Microsoft.AspNetCore.Mvc;
namespace Bibblan.Controllers
{
public class Publisher
{
public string Name { get; set; }
}
public class Image
{
public string Url { get; set; }
}
public class Author
{
public string Name { get; set; }
}
public class Contributor
{
public Author Author { get; set; }
}
public class Edition
{
public long Id { get; set; }
public string Title { get; set; }
public string Edition_Format { get; set; }
public int? Pages { get; set; }
public DateTime? Release_Date { get; set; }
public string Isbn_10 { get; set; }
public string Isbn_13 { get; set; }
public Publisher Publisher { get; set; }
public List<Contributor> Contributions { get; set; }
public Image Image { get; set; }
}
public class EditionsCollectionType
{
public List<Edition> Editions { get; set; }
}
[ApiController]
[Route("api/[controller]")]
public class BibblanController : ControllerBase
{
DatabaseService _db;
CalibreService _calibre;
private readonly IGraphQLClient _client;
public BibblanController(DatabaseService databaseService, CalibreService calibre)
public BibblanController(DatabaseService databaseService, CalibreService calibre, IGraphQLClient client)
{
_db = databaseService;
_calibre = calibre;
_client = client;
}
[HttpGet("cover")]
@@ -99,5 +140,45 @@ namespace Bibblan.Controllers
var tags = _db.GetTags(filter).ToList();
return Ok(tags);
}
//test
[HttpGet("lookup")]
public async Task<IActionResult> HardcoverLookup(string title, string author)
{
var query = new GraphQLRequest
{
Query = @"
query SomeNameHere($title: String!, $author: String!) {
editions(
where: {title: {_eq: $title}, _and: {contributions: {author: {name: {_eq: $author}}}}}
) {
id
title
edition_format
pages
release_date
isbn_10
isbn_13
publisher {
name
}
contributions {
author {
name
}
}
image {
url
}
}
}",
Variables = new
{
title,
author
}
};
var response = await _client.SendQueryAsync<EditionsCollectionType>(query);
return Ok(response.Data.Editions);
}
}
}

View File

@@ -7,5 +7,7 @@
public string CalibreDb { get; set; } = String.Empty;
public string CalibreRoot { get; set; } = String.Empty;
public string BibblanConnection { get; set; } = String.Empty;
public string HardcoverApiToken { get; set; } = string.Empty;
public string HardcoverApiUrl { get; set; } = string.Empty;
}
}

View File

@@ -1,10 +1,15 @@
using Bibblan.Business.Clients;
using Bibblan.Business.Services;
using Bibblan.Models;
using Bibblan.ViewModels;
using Dapper;
using GraphQL.Client.Abstractions;
using GraphQL.Client.Http;
using GraphQL.Client.Serializer.Newtonsoft;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System.ComponentModel.DataAnnotations.Schema;
using System.Net.Http;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile($"appsettings.user.json", true, true);
@@ -23,7 +28,15 @@ builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
//hardcover registration
builder.Services.AddTransient<HardcoverAuthenticationHandler>();//m<>ste vara transient
builder.Services.AddScoped<IGraphQLClient>(s => new GraphQLHttpClient(new GraphQLHttpClientOptions
{
HttpMessageHandler = s.GetRequiredService<HardcoverAuthenticationHandler>(),
EndPoint = new Uri(config.HardcoverApiUrl),
}, new NewtonsoftJsonSerializer()));
//databases
builder.Services.AddDbContext<SqliteCalibreContext>(options => options.UseSqlite($"Data Source={config.CalibreDb};Mode=ReadOnly;"));
builder.Services.AddDbContext<PostgresCalibreContext>(options => options.UseNpgsql(config.BibblanConnection));

View File

@@ -9,6 +9,8 @@
"Bibblan": {
"CalibreDb": "metadata.db",
"CalibreRoot": "c:\\my_books\\",
"BibblanConnection": "Server=localhost;Port=5432;Database=bibblan;User Id=bibblanuser;Password=1234567;"
"BibblanConnection": "Server=localhost;Port=5432;Database=bibblan;User Id=bibblanuser;Password=1234567;",
"HardcoverApiUrl": "https://api.hardcover.app/v1/graphql",
"HardcoverApiToken": ""
}
}