using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using System.IO; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using AyaNova.Models; using AyaNova.Api.ControllerHelpers; using AyaNova.Biz; using AyaNova.Util; using PuppeteerSharp; namespace AyaNova.Api.Controllers { [ApiController] [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/report")] [Produces("application/json")] [Authorize] public class ReportController : ControllerBase { private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; /// /// ctor /// /// /// /// public ReportController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) { ct = dbcontext; log = logger; serverState = apiServerState; } [HttpGet("render-test")] [AllowAnonymous] public async Task GetTestReport([FromRoute] string test) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); string outputFile = FileUtil.NewRandomTempFilesFolderFileName; switch (test) { case "chrome-reddit-to-pdf": //first test, just render a web page to pdf and return it //return PhysicalFile(filePath, mimetype, dbObject.DisplayFileName); outputFile += ".pdf"; //http://www.puppeteersharp.com/api/index.html //https://github.com/hardkoded/puppeteer-sharp await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision); var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }); var page = await browser.NewPageAsync(); await page.GoToAsync("https://github.com/hardkoded/puppeteer-sharp"); await page.PdfAsync(outputFile); return PhysicalFile(outputFile, "application/pdf"); } return NotFound(test); } //--------------------------------------------------------------------- [HttpGet("render")] [AllowAnonymous] public async Task GetPdfReport([FromRoute] string url) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); var ReportJSFolderPath = Path.Combine(ServerBootConfig.AYANOVA_CONTENT_ROOT_PATH, "resource", "reportjs"); if (!Directory.Exists(ReportJSFolderPath)) throw new System.Exception($"E1012: \"reportjs\" folder not found where expected: \"{ReportJSFolderPath}\", installation damaged?"); var hbspath = Path.Combine(ReportJSFolderPath, "ayhandlebars.js"); if (!System.IO.File.Exists(hbspath)) throw new System.Exception($"E1012: \"ayhandlebars.js\" file not found where expected: \"{hbspath}\", installation damaged?"); await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision); //sample CSS var templateCSS = @" @page { margin: 1cm; } @page :first { margin: 2cm; }"; //sample template var templateHtml = "'
{{#with person}}{{firstname}} {{lastname}}{{/with}}
'"; //data object var jsonData = "{person: {firstname: \"Yehuda\",lastname: \"Katz\",}}"; var dat="{ person: { firstname: 'Yehuda', lastname: 'Katz' } }"; using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true })) using (var page = await browser.NewPageAsync()) { //Add handlebars JS for compiling and presenting await page.AddScriptTagAsync(new AddTagOptions() { Path = hbspath }); //script //var theScript = $"let fun=Handlebars.compile({templateHtml});fun({dat})"; var theScript = $"let fun=Handlebars.compile({templateHtml});fun({dat});"; //COMPILE into function var f3 = await page.EvaluateExpressionAsync(theScript); //get result by running hb function against data // string html = await page.EvaluateExpressionAsync(sfunc); //open page with result // await page.AddStyleTagAsync(new AddTagOptions { Content = templateCSS }); // await page.SetContentAsync(templateHtml); //pdf-ize and return var pdfBuffer = await page.PdfDataAsync(); return new FileContentResult(pdfBuffer, "application/pdf"); } } //----------------------------------------- //------------ /* NOTES/TODO during testing Need job to automatically erase any temp files older than 5 minutes (or whatever) */ }//eoc }//eons