using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Serilog; using LCU.Api.Internal.FileOperations.Services; using LCU.Library.Internal.FileOperationsModels.Models; using LCU.Library.Internal.Exceptions; using LCU.Library.Internal.FileOperationsModels.Models.HtmlToPdfModels; using LCU.Api.Internal.FileOperations.Extensions; using LCU.Api.Internal.FileOperations.Services.QueueServices; using LCU.Api.Internal.FileOperations.Services.PdfServices; namespace LCU.Api.Internal.FileOperations.Controllers; [ApiController] [Route("api/[controller]")] public class PdfController : ControllerBase { private readonly IQueueFileOperationsService _queueFileOperationsService; private readonly IPdfParserService _pdfParserService; private readonly IBatchPdfParserService _batchPdfParserService; private readonly IDirectFileService _directFileService; private readonly IHtmlToPdfService _htmlToPdfService; public PdfController(IQueueFileOperationsService queueFileOperationsService, IPdfParserService pdfParserService, IBatchPdfParserService batchPdfParserService, IDirectFileService directFileService, IHtmlToPdfService htmlToPdfService) { _queueFileOperationsService = queueFileOperationsService; _batchPdfParserService = batchPdfParserService; _pdfParserService = pdfParserService; _directFileService = directFileService; _htmlToPdfService = htmlToPdfService; } [HttpPost("QueueBatchPdfParser")] [ProducesResponseType(202)] [ProducesResponseType(400)] [ProducesResponseType(500)] public async Task QueueBatchPdfParser([FromBody] BatchParsePdfRequest request) { try { var requestResponse = _batchPdfParserService.IsRequestValid(request, new RequestResponse()); if (!requestResponse.IsSuccessful) { return BadRequest($"Request is invalid. Response: {String.Join("\n ", requestResponse.MessageStack.ToArray())}"); } await _queueFileOperationsService.QueueFileOperations(request, FileOperationType.BatchPdfParser); return Accepted(); } catch (ServiceException exception) { return StatusCode(StatusCodes.Status500InternalServerError, exception.Message); } catch (Exception exception) { Log.Error(exception, "Unexpected Exception"); return StatusCode(StatusCodes.Status500InternalServerError); } } /// /// This will parse a PDF from a starting page to and a stopping page, save new pdf to RootPath, /// and returns the PDF name. The PDF name will be set to ParsedPdfname or the default "{pdfParserRequest.PdfName}.{pdfParserRequest.StartingPage}.pdf". /// /// Notes: /// - Page numbers range from 1-x. /// - If PDF exists it will automatically overwrite. /// - Original PDF can be open at the time of parsing. /// /// /// [HttpPost("ParsePdf")] [ProducesResponseType(200)] [ProducesResponseType(typeof(ParsePdfRequest), 400)] [ProducesResponseType(500)] public IActionResult ParsePdf([FromBody] ParsePdfRequest pdfParserRequest) { try { if (!ModelState.IsValid) { return BadRequest(ModelState.GetErrorMessages()); } var result = _pdfParserService.ParsePdf(pdfParserRequest); return Ok(result); } catch (ServiceException exception) { return StatusCode(StatusCodes.Status500InternalServerError, exception.Message); } catch (Exception exception) { Log.Error(exception, "Unexpected Exception"); return StatusCode(StatusCodes.Status500InternalServerError); } } [HttpGet("GetPdfContent/{pdfPath}")] [ProducesResponseType(200)] [ProducesResponseType(400)] [ProducesResponseType(500)] public IActionResult GetPdfContent([FromRoute] string pdfPath) { if (string.IsNullOrWhiteSpace(pdfPath)) { return BadRequest("PDF Path is required"); } try { var result = _directFileService.GetFileBytes(pdfPath); return new FileContentResult(result, "application/pdf"); } catch (ArgumentException ae) { Log.Error(ae, $"Request for bad PDF path {pdfPath}"); return BadRequest("PDF path not found"); } catch (Exception ex) { Log.Error(ex, $"Unexpected error retrieving PDF path {pdfPath}"); return StatusCode(StatusCodes.Status500InternalServerError); } } /// /// ConvertHmtlToPdf will take the HtmlToPdfRequest and generate a HTML file filling in the tags with the supplied data. /// It will then utilize Chrome functionality to print a pdf and save it to a location. Finally converting to byte array and returning. /// /// HtmlToPdfRequest: /// - HtmlTemplateFilePath: (REQUIRED) File Path of the main html template that the HTML file will start to build. /// - PdfName: (REQUIRED) What the PDF and HTML files will be called. /// - KeepHtmlFile: (Defaults = False) Mostly for testing purposes. If set to true it will keep the generated HTML file. /// - KeepPdfFile: (Defaults = False) Mostly for testing purposes. If set to true it will keep the generated PDF file /// - HtmlSaveFilePath: (REQUIRED) Location that the generated HTML file will be temporarily (KeepHtmlFile = false) stored. /// - PdfSaveFilePath: (REQUIRED) Location that the generated PDF file will be temporarily (KeepHtmlFile = false) stored. /// - BodyTagValues: Tags that will be filled in with supplied values. /// - TagValues: /// - Tag: (REQUIRED) Name of the tag in the HTML. In HTML should be surrounded by {}. This tag does not need {}. /// - Value: (REQUIRED) Value in which will replace the {TagName}. /// - BodyValueCollections: List of ValueCollections that give us the ability to replace a tag that is associated with a HTML Template. The ValucollectionItems is /// looped through to generate what will replace the tag. Common use case would be a list of items or a table of items. /// - CollectionTag: (REQUIRED) Name of the tag in the HTML. In HTML should be surrounded by {}. This tag does not need {}. /// - CollectionHtmlTemplateFilePath: (REQUIRED) File Path of the collections html template that the HTML file will start to build. /// - ValueCollectionItems: List of ValueCollectionItems that can be looped through to help build out what the CollectionTag will be replaced with. /// ValueCollection has a nested ValueCollectionItems, giving the ability to create infinite amount of nested collections within collections. /// - TagValues: List of TagValues /// - ValueCollections: List of ValueCollections /// /// Notes: /// - In HTML templates tags should be surrounded by braces {TagName}. The request does not need the braces {}. /// - Any unused tags surrounded by braces will be removed at the end of the process. /// - Can use \\\\zeus\DataIntegrationsQA\\PDFCreation\\ folder to store templates, generated HTML files, and generated PDF /// - \\\\zeus\DataIntegrationsQA\\PDFCreation\\Html_Templates /// - \\\\zeus\DataIntegrationsQA\\PDFCreation\\Html_Drop /// - \\\\zeus\DataIntegrationsQA\\PDFCreation\\PDF_Drop /// [HttpPost("ConvertHtmlToPdf")] [ProducesResponseType(200)] [ProducesResponseType(400)] [ProducesResponseType(500)] public IActionResult ConvertHtmlToPdf([FromBody] HtmlToPdfRequest htmlToPdfRequest) { try { var result = _htmlToPdfService.ConvertHtmlToPdf(htmlToPdfRequest); return new FileContentResult(result, "application/pdf"); } catch (ServiceException exception) { return StatusCode(StatusCodes.Status500InternalServerError, exception.Message); } catch (Exception exception) { Log.Error(exception, "Unexpected Exception"); return StatusCode(StatusCodes.Status500InternalServerError); } } }