From 48e65f5f9299679592b4cff96d4ddadfc2385cf7 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Fri, 23 Oct 2020 22:20:55 +0000 Subject: [PATCH] --- .../AyaNova/Controllers/ExportController.cs | 178 +++--------------- 1 file changed, 30 insertions(+), 148 deletions(-) diff --git a/server/AyaNova/Controllers/ExportController.cs b/server/AyaNova/Controllers/ExportController.cs index cdaf6fbb..0c70d74d 100644 --- a/server/AyaNova/Controllers/ExportController.cs +++ b/server/AyaNova/Controllers/ExportController.cs @@ -1,11 +1,9 @@ -using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; using AyaNova.Models; @@ -14,6 +12,8 @@ using AyaNova.Biz; using AyaNova.Util; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System.IO; +using System.IO.Compression; namespace AyaNova.Api.Controllers { @@ -83,31 +83,38 @@ namespace AyaNova.Api.Controllers log.LogDebug($"Fetching data for {dataListSelection.SelectedRowIds.Length} {dataListSelection.ObjectType} items"); var TheData = await ((IExportAbleObject)biz).GetExportData(dataListSelection.SelectedRowIds); - string outputFileName = StringUtil.ReplaceLastOccurrence(FileUtil.NewRandomFileName, ".", "") + ".pdf"; - string outputFullPath = System.IO.Path.Combine(FileUtil.TemporaryFilesFolder, outputFileName); + string outputRandomFileNameNoExtension = StringUtil.ReplaceLastOccurrence(FileUtil.NewRandomFileName, ".", ""); + string outputSourceFileName = outputRandomFileNameNoExtension + "." + format; + string outputSourceFullPath = System.IO.Path.Combine(FileUtil.TemporaryFilesFolder, outputSourceFileName); + string outputZipFullpath = System.IO.Path.Combine(FileUtil.TemporaryFilesFolder, outputRandomFileNameNoExtension + ".zip"); + // string outputFullPathSourceFile=outputFullPathNoExtension + // string outputFullpathZipFile=outputFullPathNoExtension + ".zip"; log.LogDebug($"Calling render export data to file"); - //TODO: RENDER DATA TO FILE HERE await page.PdfAsync(outputFullPath, PdfOptions); + switch (format) + { + case "csv": + throw new System.NotImplementedException("CSV export not implemented yet"); + break; + case "json": + using (StreamWriter file = System.IO.File.CreateText(outputSourceFullPath)) + using (JsonTextWriter writer = new JsonTextWriter(file)) + { + TheData.WriteTo(writer); + } + break; + } + + //zip it + using (FileStream fs = new FileStream(outputZipFullpath, FileMode.Create)) + using (ZipArchive arch = new ZipArchive(fs, ZipArchiveMode.Create)) + { + arch.CreateEntryFromFile(outputSourceFullPath, outputSourceFileName); + } log.LogDebug($"Completed, returning results"); - return Ok(ApiOkResponse.Response(outputFileName)); + return Ok(ApiOkResponse.Response(outputRandomFileNameNoExtension + ".zip")); - // var httpConnectionFeature = HttpContext.Features.Get(); - // var API_URL = $"http://127.0.0.1:{httpConnectionFeature.LocalPort}/api/v8/"; - // try - // { - // var result = await biz.RenderExport(ExportParam, API_URL); - // if (string.IsNullOrWhiteSpace(result)) - // return BadRequest(new ApiErrorResponse(biz.Errors)); - // else - // return Ok(ApiOkResponse.Response(result)); - // } - // catch (System.Exception ex) - // { - // //The Javascript evaluation stack trace can be in the message making it long and internalized, - // //however the info is useful as it can indicate exactly which function failed etc so sending it all back is best - // return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, ex.Message)); - // } } @@ -137,136 +144,11 @@ namespace AyaNova.Api.Controllers } var FilePath = FileUtil.GetFullPathForTemporaryFile(fileName); - return PhysicalFile(FilePath, "application/pdf"); + return PhysicalFile(FilePath, "application/zip"); } - /// - /// Download Export template - /// - /// Export id - /// download token - /// A single Export template as a file - [AllowAnonymous] - [HttpGet("export/{id}")] - public async Task DownloadTemplate([FromRoute] long id, [FromQuery] string t) - { - if (serverState.IsClosed) - return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); - - if (!ModelState.IsValid) - return BadRequest(new ApiErrorResponse(ModelState)); - - if (await UserBiz.ValidateDownloadTokenAndReturnUserAsync(t, ct) == null) - { - await Task.Delay(ServerBootConfig.FAILED_AUTH_DELAY);//DOS protection - return StatusCode(401, new ApiErrorResponse(ApiErrorCode.AUTHENTICATION_FAILED)); - } - - var o = await ct.Export.SingleOrDefaultAsync(z => z.Id == id); - //turn into correct format and then send as file - if (o == null) - { - return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); - } - var asText = Newtonsoft.Json.JsonConvert.SerializeObject( - o, - Newtonsoft.Json.Formatting.None, - new JsonSerializerSettings { ContractResolver = new AyaNova.Util.JsonUtil.ShouldSerializeContractResolver(new string[] { "Concurrency", "Id" }) }); - var bytes = System.Text.Encoding.UTF8.GetBytes(asText); - var file = new FileContentResult(bytes, "application/octet-stream"); - file.FileDownloadName = Util.FileUtil.StringToSafeFileName(o.Name) + ".ayrt"; - return file; - } - - - - - /// - /// Upload Reprot template export file - /// Max 15mb total - /// - /// Accepted - [Authorize] - [HttpPost("upload")] - [DisableFormValueModelBinding] - [RequestSizeLimit(15000000)]//currently the largest v7 export for a Export template is 828kb, I'm guessing 15mb is more than enough - public async Task UploadAsync() - { - //Adapted from the example found here: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads#uploading-large-files-with-streaming - - if (!serverState.IsOpen) - return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); - - - // AyaTypeId attachToObject = null; - ApiUploadProcessor.ApiUploadedFilesResult uploadFormData = null; - try - { - if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) - return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, $"Expected a multipart request, but got {Request.ContentType}")); - - //Save uploads to disk under temporary file names until we decide how to handle them - uploadFormData = await ApiUploadProcessor.ProcessUploadAsync(HttpContext); - - - - List FileData = new List(); - - if (!uploadFormData.FormFieldData.ContainsKey("FileData"))//only filedata is required - { - return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Missing required FormFieldData value: FileData")); - } - - //fileData in JSON stringify format - FileData = Newtonsoft.Json.JsonConvert.DeserializeObject>(uploadFormData.FormFieldData["FileData"].ToString()); - - //Instantiate the business object handler - ExportBiz biz = ExportBiz.GetBiz(ct, HttpContext); - - - //We have our files now can parse and insert into db - if (uploadFormData.UploadedFiles.Count > 0) - { - //deserialize each file and import - foreach (UploadedFileInfo a in uploadFormData.UploadedFiles) - { - JObject o = JObject.Parse(System.IO.File.ReadAllText(a.InitialUploadedPathName)); - if (!await biz.ImportAsync(o)) - { - //delete all the files temporarily uploaded and return bad request - DeleteTempUploadFile(uploadFormData); - return BadRequest(new ApiErrorResponse(biz.Errors)); - } - } - } - } - catch (System.IO.InvalidDataException ex) - { - return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, ex.Message)); - } - finally - { - //delete all the files temporarily uploaded and return bad request - - DeleteTempUploadFile(uploadFormData); - } - - //Return the list of attachment ids and filenames - return Accepted(); - } - - private static void DeleteTempUploadFile(ApiUploadProcessor.ApiUploadedFilesResult uploadFormData) - { - if (uploadFormData.UploadedFiles.Count > 0) - { - foreach (UploadedFileInfo a in uploadFormData.UploadedFiles) - { - System.IO.File.Delete(a.InitialUploadedPathName); - } - } - } //-----------------------------------------