Consolidated DTOs under `DocumentService.Application.Common.DTOs.Requests` to centralize and align them with the application layer. Introduced `PdfBase64RequestBase` to encapsulate shared properties, reducing redundancy across request DTOs. Updated controllers, clients, and tests to use the new DTO structure. Removed redundant DTOs and cleaned up unused namespaces and comments. Improved documentation and ensured consistent naming conventions across the codebase.
162 lines
7.1 KiB
C#
162 lines
7.1 KiB
C#
using DocumentService.Client.Interfaces;
|
|
using DocumentService.Application.Common.DTOs.Requests;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
|
|
namespace DocumentService.Client.Clients;
|
|
|
|
/// <summary>
|
|
/// Implementation of PDF operations client (merge, annotate, stamp).
|
|
/// </summary>
|
|
public class PdfOperationsClient(HttpClient httpClient, ILogger<PdfOperationsClient> logger) : BaseDocumentClient(httpClient, logger), IPdfOperationsClient
|
|
{
|
|
|
|
// ==================== MERGE OPERATIONS ====================
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Stream> MergeAsync(IEnumerable<Stream> pdfStreams, List<string?>? pageRanges = null, CancellationToken cancellationToken = default)
|
|
{
|
|
using var content = new MultipartFormDataContent();
|
|
|
|
foreach (var stream in pdfStreams)
|
|
{
|
|
var streamContent = new StreamContent(stream);
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
|
|
content.Add(streamContent, "files", $"file_{Guid.NewGuid()}.pdf");
|
|
}
|
|
|
|
return await SendMultipartContentForStreamAsync("/api/pdf/operations/merge", content, cancellationToken);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Stream> MergeAsync(IEnumerable<byte[]> pdfByteArrays, List<string?>? pageRanges = null, CancellationToken cancellationToken = default)
|
|
{
|
|
var request = new MergePdfsBase64Request
|
|
{
|
|
Base64Pdfs = [.. pdfByteArrays.Select(ToBase64)],
|
|
PageRanges = pageRanges
|
|
};
|
|
|
|
return await SendJsonForStreamAsync(
|
|
"/api/pdf/operations/merge",
|
|
request,
|
|
cancellationToken);
|
|
}
|
|
|
|
// ==================== ANNOTATION OPERATIONS ====================
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Stream> AnnotateAsync(Stream pdfStream, AddAnnotationBase64Request request, CancellationToken cancellationToken = default)
|
|
{
|
|
// For multipart, we need to send form data with all annotation parameters
|
|
using var content = new MultipartFormDataContent();
|
|
|
|
var streamContent = new StreamContent(pdfStream);
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
|
|
content.Add(streamContent, "File", "document.pdf");
|
|
|
|
// Add annotation parameters as form fields
|
|
content.Add(new StringContent(request.AnnotationType.ToString()), "AnnotationType");
|
|
content.Add(new StringContent(request.PageNumber.ToString()), "PageNumber");
|
|
content.Add(new StringContent(request.X1.ToString()), "X1");
|
|
content.Add(new StringContent(request.Y1.ToString()), "Y1");
|
|
|
|
if (request.X2.HasValue)
|
|
content.Add(new StringContent(request.X2.Value.ToString()), "X2");
|
|
if (request.Y2.HasValue)
|
|
content.Add(new StringContent(request.Y2.Value.ToString()), "Y2");
|
|
if (request.Width.HasValue)
|
|
content.Add(new StringContent(request.Width.Value.ToString()), "Width");
|
|
if (request.Height.HasValue)
|
|
content.Add(new StringContent(request.Height.Value.ToString()), "Height");
|
|
if (!string.IsNullOrEmpty(request.Content))
|
|
content.Add(new StringContent(request.Content), "Content");
|
|
if (!string.IsNullOrEmpty(request.Author))
|
|
content.Add(new StringContent(request.Author), "Author");
|
|
if (!string.IsNullOrEmpty(request.Color))
|
|
content.Add(new StringContent(request.Color), "Color");
|
|
if (request.TextMarkupStyle.HasValue)
|
|
content.Add(new StringContent(request.TextMarkupStyle.Value.ToString()), "TextMarkupStyle");
|
|
|
|
content.Add(new StringContent(request.Origin.ToString()), "Origin");
|
|
|
|
return await SendMultipartContentForStreamAsync("/api/pdf/operations/annotate", content, cancellationToken);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Stream> AnnotateAsync(byte[] pdfBytes, AddAnnotationBase64Request request, CancellationToken cancellationToken = default)
|
|
{
|
|
var requestWithPdf = request with { Base64Pdf = ToBase64(pdfBytes) };
|
|
|
|
return await SendJsonForStreamAsync(
|
|
"/api/pdf/operations/annotate",
|
|
requestWithPdf,
|
|
cancellationToken);
|
|
}
|
|
|
|
// ==================== STAMP OPERATIONS ====================
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Stream> StampAsync(Stream pdfStream, AddStampBase64Request request, CancellationToken cancellationToken = default)
|
|
{
|
|
// For multipart, we need to send form data with all stamp parameters
|
|
using var content = new MultipartFormDataContent();
|
|
|
|
var streamContent = new StreamContent(pdfStream);
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
|
|
content.Add(streamContent, "File", "document.pdf");
|
|
|
|
// Add stamp parameters as form fields
|
|
content.Add(new StringContent(request.StampType.ToString()), "StampType");
|
|
content.Add(new StringContent(request.X.ToString()), "X");
|
|
content.Add(new StringContent(request.Y.ToString()), "Y");
|
|
|
|
if (request.PageNumbers != null && request.PageNumbers.Length > 0)
|
|
{
|
|
foreach (var pageNum in request.PageNumbers)
|
|
{
|
|
content.Add(new StringContent(pageNum.ToString()), "PageNumbers");
|
|
}
|
|
}
|
|
|
|
if (request.Width.HasValue)
|
|
content.Add(new StringContent(request.Width.Value.ToString()), "Width");
|
|
if (request.Height.HasValue)
|
|
content.Add(new StringContent(request.Height.Value.ToString()), "Height");
|
|
|
|
content.Add(new StringContent(request.Origin.ToString()), "Origin");
|
|
|
|
if (!string.IsNullOrEmpty(request.Text))
|
|
content.Add(new StringContent(request.Text), "Text");
|
|
if (!string.IsNullOrEmpty(request.FontName))
|
|
content.Add(new StringContent(request.FontName), "FontName");
|
|
if (request.FontSize.HasValue)
|
|
content.Add(new StringContent(request.FontSize.Value.ToString()), "FontSize");
|
|
if (!string.IsNullOrEmpty(request.Color))
|
|
content.Add(new StringContent(request.Color), "Color");
|
|
if (request.Opacity.HasValue)
|
|
content.Add(new StringContent(request.Opacity.Value.ToString()), "Opacity");
|
|
if (request.Rotation.HasValue)
|
|
content.Add(new StringContent(request.Rotation.Value.ToString()), "Rotation");
|
|
|
|
content.Add(new StringContent(request.Placement.ToString()), "Placement");
|
|
|
|
if (request.PredefinedType.HasValue)
|
|
content.Add(new StringContent(request.PredefinedType.Value.ToString()), "PredefinedType");
|
|
|
|
return await SendMultipartContentForStreamAsync("/api/pdf/operations/stamp", content, cancellationToken);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<Stream> StampAsync(byte[] pdfBytes, AddStampBase64Request request, CancellationToken cancellationToken = default)
|
|
{
|
|
var requestWithPdf = request with { Base64Pdf = ToBase64(pdfBytes) };
|
|
|
|
return await SendJsonForStreamAsync(
|
|
"/api/pdf/operations/stamp",
|
|
requestWithPdf,
|
|
cancellationToken);
|
|
}
|
|
}
|