125 lines
4.6 KiB
C#
125 lines
4.6 KiB
C#
using DocumentService.Client.Interfaces;
|
|
using DocumentService.Client.Models.Requests;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.IO.Compression;
|
|
using System.Net.Http;
|
|
|
|
namespace DocumentService.Client.Clients;
|
|
|
|
/// <summary>
|
|
/// Implementation of PDF attachment client.
|
|
/// </summary>
|
|
public class PdfAttachmentClient(HttpClient httpClient, ILogger<PdfAttachmentClient> logger)
|
|
: BaseDocumentClient(httpClient, logger), IPdfAttachmentClient
|
|
{
|
|
/// <inheritdoc />
|
|
public async Task<AttachmentCheckResult> CheckAttachmentsAsync(Stream pdfStream, CancellationToken cancellationToken = default)
|
|
{
|
|
Logger.LogDebug("Checking PDF attachments from stream (multipart)");
|
|
|
|
var result = await SendMultipartAsync<AttachmentCheckResult>(
|
|
"/api/pdf/attachments/check",
|
|
pdfStream,
|
|
"document.pdf",
|
|
cancellationToken);
|
|
|
|
return result ?? throw new InvalidOperationException("API returned null response");
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<AttachmentCheckResult> CheckAttachmentsAsync(byte[] pdfBytes, CancellationToken cancellationToken = default)
|
|
{
|
|
Logger.LogDebug("Checking PDF attachments from byte array (Base64 JSON)");
|
|
|
|
var request = new CheckPdfAttachmentsRequest { Base64Pdf = ToBase64(pdfBytes) };
|
|
|
|
var result = await SendJsonAsync<CheckPdfAttachmentsRequest, AttachmentCheckResult>(
|
|
"/api/pdf/attachments/check",
|
|
request,
|
|
cancellationToken);
|
|
|
|
return result ?? throw new InvalidOperationException("API returned null response");
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Dictionary<string, Stream>> ExtractAttachmentsAsync(Stream pdfStream, CancellationToken cancellationToken = default)
|
|
{
|
|
Logger.LogDebug("Extracting PDF attachments from stream (multipart)");
|
|
|
|
var zipStream = await SendMultipartForStreamAsync(
|
|
"/api/pdf/attachments/extract",
|
|
pdfStream,
|
|
"document.pdf",
|
|
cancellationToken);
|
|
|
|
return UnzipToStreams(zipStream);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Dictionary<string, Stream>> ExtractAttachmentsAsync(byte[] pdfBytes, CancellationToken cancellationToken = default)
|
|
{
|
|
Logger.LogDebug("Extracting PDF attachments from byte array (Base64 JSON)");
|
|
|
|
var request = new ExtractPdfAttachmentsRequest { Base64Pdf = ToBase64(pdfBytes) };
|
|
|
|
var zipStream = await SendJsonForStreamAsync(
|
|
"/api/pdf/attachments/extract",
|
|
request,
|
|
cancellationToken);
|
|
|
|
return UnzipToStreams(zipStream);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
[Obsolete("API endpoint not implemented yet")]
|
|
public Task<Stream> AddAttachmentsAsync(Stream pdfStream, List<AttachmentRequestDto> attachments, CancellationToken cancellationToken = default)
|
|
{
|
|
Logger.LogWarning("AddAttachments endpoint is not implemented yet in API");
|
|
throw new NotImplementedException("API endpoint /api/pdf/attachments/add is not implemented yet");
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
[Obsolete("API endpoint not implemented yet")]
|
|
public Task<Stream> AddAttachmentsAsync(byte[] pdfBytes, List<AttachmentRequestDto> attachments, CancellationToken cancellationToken = default)
|
|
{
|
|
Logger.LogWarning("AddAttachments endpoint is not implemented yet in API");
|
|
throw new NotImplementedException("API endpoint /api/pdf/attachments/add is not implemented yet");
|
|
}
|
|
|
|
// ?????????????????????????????????????????????????????????????????????????
|
|
// Private helpers
|
|
// ?????????????????????????????????????????????????????????????????????????
|
|
|
|
/// <summary>
|
|
/// Reads a ZIP stream and returns a dictionary mapping each entry's full name
|
|
/// to an in-memory <see cref="MemoryStream"/> containing the decompressed bytes.
|
|
/// The caller owns the returned streams and is responsible for disposing them.
|
|
/// </summary>
|
|
private static Dictionary<string, Stream> UnzipToStreams(Stream zipStream)
|
|
{
|
|
var result = new Dictionary<string, Stream>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
using var archive = new ZipArchive(zipStream, ZipArchiveMode.Read, leaveOpen: false);
|
|
|
|
foreach (var entry in archive.Entries)
|
|
{
|
|
// Skip directory entries (name ends with '/')
|
|
if (string.IsNullOrEmpty(entry.Name))
|
|
continue;
|
|
|
|
var ms = new MemoryStream((int)entry.Length);
|
|
|
|
using (var entryStream = entry.Open())
|
|
{
|
|
entryStream.CopyTo(ms);
|
|
}
|
|
|
|
ms.Position = 0;
|
|
result[entry.FullName] = ms;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|