From 7cd6c229908191cf55df5a37e9b151bd889f66e2 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Fri, 7 Aug 2020 16:31:16 +0000 Subject: [PATCH] --- server/AyaNova/Controllers/LogoController.cs | 228 +++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 server/AyaNova/Controllers/LogoController.cs diff --git a/server/AyaNova/Controllers/LogoController.cs b/server/AyaNova/Controllers/LogoController.cs new file mode 100644 index 00000000..3200ff85 --- /dev/null +++ b/server/AyaNova/Controllers/LogoController.cs @@ -0,0 +1,228 @@ +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.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +using AyaNova.Models; +using AyaNova.Api.ControllerHelpers; +using AyaNova.Biz; +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Linq; +using System.Linq; +using AyaNova.Util; + + + +namespace AyaNova.Api.Controllers +{ + + /// + /// Logo controller + /// + [ApiController] + [ApiVersion("8.0")] + [Route("api/v{version:apiVersion}/Logo")] + [Produces("application/json")] + [Authorize] + public class LogoController : ControllerBase + { + private readonly AyContext ct; + private readonly ILogger log; + private readonly ApiServerState serverState; + + + /// + /// ctor + /// + /// + /// + /// + public LogoController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) + { + ct = dbcontext; + log = logger; + serverState = apiServerState; + } + + + + + + /// + /// Get Logo + /// + /// One of "small", "medium", "large" + /// A single Logo and it's values + [AllowAnonymous] + [HttpGet("{size}")] + public async Task DownloadLogo([FromRoute] string size) + { + if (serverState.IsClosed) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + + + if (!ModelState.IsValid) + { + return BadRequest(new ApiErrorResponse(ModelState)); + } + + + + + var o = await ct.Logo.Include(z => z.LogoItems).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 ShouldSerializeContractResolver(new string[] { "Concurrency", "Id", "LogoId" }) }); + var bytes = System.Text.Encoding.UTF8.GetBytes(asText); + var file = new FileContentResult(bytes, "application/octet-stream"); + file.FileDownloadName = Util.FileUtil.StringToSafeFileName(o.Name) + ".json"; + return file; + } + + + public class ShouldSerializeContractResolver : DefaultContractResolver + { + private readonly IEnumerable _excludePropertyNames; + + public ShouldSerializeContractResolver(IEnumerable excludePropertyNames) + { + _excludePropertyNames = excludePropertyNames; + } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); + + // only serializer properties that start with the specified character + properties = + properties.Where(p => !_excludePropertyNames.Any(p2 => p2 == p.PropertyName)).ToList(); + + return properties; + } + } + + + + /// + /// Upload Logo + /// Max 15mb total + /// + /// One of "small", "medium", "large" + /// Accepted + [Authorize] + [HttpPost("{size}")] + [DisableFormValueModelBinding] + [RequestSizeLimit(15000000)]//currently export file is 200kb * 50 maximum at a time = 15mb https://github.com/aspnet/Announcements/issues/267 + public async Task UploadAsync([FromRoute] string size) + { + + //https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1#upload-small-files-with-buffered-model-binding-to-a-database + + 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); + + bool badRequest = false; + string UploadObjectType = string.Empty; + string UploadObjectId = string.Empty; + string errorMessage = string.Empty; + string Notes = string.Empty; + List FileData = new List(); + + if ( + !uploadFormData.FormFieldData.ContainsKey("FileData"))//only filedata is required + { + badRequest = true; + errorMessage = "Missing required FormFieldData value: FileData"; + } + if (!badRequest) + { + if (uploadFormData.FormFieldData.ContainsKey("ObjectType")) + UploadObjectType = uploadFormData.FormFieldData["ObjectType"].ToString(); + if (uploadFormData.FormFieldData.ContainsKey("ObjectId")) + UploadObjectId = uploadFormData.FormFieldData["ObjectId"].ToString(); + if (uploadFormData.FormFieldData.ContainsKey("Notes")) + Notes = uploadFormData.FormFieldData["Notes"].ToString(); + //fileData in JSON stringify format which contains the actual last modified dates etc + //"[{\"name\":\"Client.csv\",\"lastModified\":1582822079618},{\"name\":\"wmi4fu06nrs41.jpg\",\"lastModified\":1586900220990}]" + FileData = Newtonsoft.Json.JsonConvert.DeserializeObject>(uploadFormData.FormFieldData["FileData"].ToString()); + + } + + + // long UserId = UserIdFromContext.Id(HttpContext.Items); + //Instantiate the business object handler + LogoBiz biz = LogoBiz.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); + } + } + } + + + + } +} \ No newline at end of file