using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using Manager.DTOs; using Manager.Services; using ManagerService.Data; using ManagerService.Data.SubSection; using ManagerService.DTOs; using ManagerService.Helpers; using ManagerService.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using NSwag.Annotations; namespace ManagerService.Controllers { [Authorize] // TODO Add ROLES (Roles = "Admin") [ApiController, Route("api/[controller]")] [OpenApiTag("Resource", Description = "Resource management")] public class ResourceController : ControllerBase { private readonly MyInfoMateDbContext _myInfoMateDbContext; private ResourceDatabaseService _resourceService; private SectionDatabaseService _sectionService; private ConfigurationDatabaseService _configurationService; private readonly ILogger _logger; IHexIdGeneratorService idService = new HexIdGeneratorService(); private static int MaxWidth = 1024; private static int MaxHeight = 1024; public ResourceController(ILogger logger, ResourceDatabaseService resourceService, SectionDatabaseService sectionService, ConfigurationDatabaseService configurationService, MyInfoMateDbContext myInfoMateDbContext) { _logger = logger; _resourceService = resourceService; _sectionService = sectionService; _configurationService = configurationService; _myInfoMateDbContext = myInfoMateDbContext; } /// /// Get a list of all resources (summary) /// /// id instance /// types of resource [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 500)] [HttpGet] public ObjectResult Get([FromQuery] string instanceId, [FromQuery] List types) { try { if (instanceId == null) throw new ArgumentNullException("InstanceId needed"); List resources = new List(); if (types.Count > 0) { resources = _myInfoMateDbContext.Resources.Where(r => r.InstanceId == instanceId && types.Contains(r.Type)).ToList(); //resources = _resourceService.GetAllByType(instanceId, types); } else { resources = _myInfoMateDbContext.Resources.Where(r => r.InstanceId == instanceId).ToList(); //resources = _resourceService.GetAll(instanceId); } List resourceDTOs = new List(); foreach(var resource in resources) { ResourceDTO resourceDTO = new ResourceDTO(); resourceDTO = resource.ToDTO(); resourceDTOs.Add(resourceDTO); } return new OkObjectResult(resourceDTOs.OrderByDescending(r => r.dateCreation)); } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Get a specific resource /// /// id resource [AllowAnonymous] [ProducesResponseType(typeof(ResourceDTO), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{id}/detail")] public ObjectResult GetDetail(string id) { try { Resource resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == id); //Resource resource = _resourceService.GetById(id); if (resource == null) throw new KeyNotFoundException("This resource was not found"); ResourceDTO resourceDTO = new ResourceDTO(); resourceDTO = resource.ToDTO(); /*if (resource.Type == ResourceType.ImageUrl) { var resourceData = _resourceDataService.GetByResourceId(resource.Id); resourceDTO.data = resourceData != null ? resourceData.Data : null; }*/ // RESIZE IMAGE /*byte[] imageBytes = Convert.FromBase64String(resourceData.Data); using (MemoryStream originalImageMemoryStream = new MemoryStream(imageBytes)) { using (Image image = Image.FromStream(originalImageMemoryStream)) { var width = image.Width; var height = image.Height; if (image.Width > MaxWidth || image.Height > MaxHeight) { Size newSize = ImageResizer.ResizeKeepAspect(image.Size, MaxWidth, MaxHeight); byte[] resizedImage = ImageResizer.ResizeImage(image, newSize.Width, newSize.Height, image.Width, image.Height); resourceData.Data = Convert.ToBase64String(resizedImage); ResourceData resourceModified = _resourceDataService.Update(resourceData.Id, resourceData); } } }*/ return new OkObjectResult(resourceDTO); } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Show a specific resource (as a picture or video stream) /// /// id resource [AllowAnonymous] [ProducesResponseType(typeof(FileResult), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{id}")] public ActionResult Show(string id) { try { Resource resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == id); //OldResource resource = _resourceService.GetById(id); if (resource == null) throw new KeyNotFoundException("This resource was not found"); //var file = Convert.FromBase64String(resourceData.Data); // RESIZE IMAGE /*using (MemoryStream originalImageMemoryStream = new MemoryStream(file)) { using (Image image = Image.FromStream(originalImageMemoryStream)) { var width = image.Width; var height = image.Height; if(image.Width > MaxWidth || image.Height > MaxHeight) { Size newSize = ImageResizer.ResizeKeepAspect(image.Size, MaxWidth, MaxHeight); byte[] resizedImage = ImageResizer.ResizeImage(image, newSize.Width, newSize.Height, image.Width, image.Height); resourceData.Data = Convert.ToBase64String(resizedImage); ResourceData resourceModified = _resourceDataService.Update(resourceData.Id, resourceData); } } }*/ /*if (resource.Type == ResourceType.Image) { return new FileContentResult(file, "image/png") { FileDownloadName = resource.Label + ".png" }; } if (resource.Type == ResourceType.Video || resource.Type == ResourceType.Audio) { return new FileContentResult(file, "application/octet-stream") { FileDownloadName = resource.Type == ResourceType.Audio ? resource.Label + ".mp3" : resource.Label + ".mp4", }; } return new FileContentResult(file, "image/png");*/ return new NotFoundObjectResult("No more supported") { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } // OLD VERSION /// /// Upload a specific resource (picture or video) /// [ProducesResponseType(typeof(string), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPost("upload"), DisableRequestSizeLimit] public IActionResult Upload([FromForm] string label, [FromForm] string type, [FromForm] string instanceId) // Create but with local //[FromBody] ResourceDetailDTO uploadResource { try { if (label == null || type == null || instanceId == null) throw new ArgumentNullException("One of resource params is null"); var resourceType = (ResourceType)Enum.Parse(typeof(ResourceType), type); List resources = new List(); foreach (var file in Request.Form.Files) { if (file.Length > 0) { var stringResult = ""; double fileSizeibMbs = (double) ((double)file.Length) / (1024*1024); if (fileSizeibMbs <= 1.5 || resourceType == ResourceType.Image) { using (var ms = new MemoryStream()) { file.CopyTo(ms); var fileBytes = ms.ToArray(); if (resourceType == ResourceType.Image) { bool isFort = instanceId == "633ee379d9405f32f166f047"; // If fort saint heribert, TODO add watermark in configuration and model if(isFort) // TODO We need to know for which purpose (mobile or tablet) { fileBytes = ImageHelper.ResizeAndAddWatermark(fileBytes, isFort, MaxWidth, MaxHeight); } } stringResult = Convert.ToBase64String(fileBytes); } } else { throw new FileLoadException(message: "Fichier inexistant ou trop volumineux (max 4Mb)"); } // Todo add some verification ? Resource resource = new Resource(); resource.Label = label; resource.Type = resourceType; resource.DateCreation = DateTime.Now.ToUniversalTime(); resource.InstanceId = instanceId; resource.Id = idService.GenerateHexId(); _myInfoMateDbContext.Add(resource); _myInfoMateDbContext.SaveChanges(); //Resource resourceCreated = _resourceService.Create(resource); resources.Add(resource); } } return Ok(resources.Select(r => r.ToDTO())); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (FileLoadException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (InvalidOperationException ex) { return new ConflictObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create a new resource /// /// New resource info [ProducesResponseType(typeof(ResourceDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] [HttpPost] public ObjectResult Create([FromBody] ResourceDTO newResource) { try { if (newResource == null) throw new ArgumentNullException("Resource param is null"); // Todo add some verification ? Resource resource = new Resource(); resource.InstanceId = newResource.instanceId; resource.Label = newResource.label; resource.Type = newResource.type; resource.Url = newResource.url; resource.DateCreation = DateTime.Now.ToUniversalTime(); //resource.Data = newResource.data; resource.InstanceId = newResource.instanceId; resource.Id = idService.GenerateHexId(); _myInfoMateDbContext.Add(resource); _myInfoMateDbContext.SaveChanges(); //OldResource resourceCreated = _resourceService.Create(resource); return new OkObjectResult(resource.ToDTO()); // WITHOUT DATA } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (InvalidOperationException ex) { return new ConflictObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Update a resource /// /// Resource to update [ProducesResponseType(typeof(ResourceDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut] public ObjectResult Update([FromBody] ResourceDTO updatedResource) { try { if (updatedResource == null) throw new ArgumentNullException("Resource param is null"); //OldResource resource = _resourceService.GetById(updatedResource.id); Resource resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == updatedResource.id); if (resource == null) throw new KeyNotFoundException("Resource does not exist"); // Todo add some verification ? resource.InstanceId = updatedResource.instanceId != null ? updatedResource.instanceId : resource.InstanceId; resource.Label = updatedResource.label != null ? updatedResource.label : resource.Label; resource.Type = updatedResource.type != null ? updatedResource.type : resource.Type; resource.Url = updatedResource.url != null ? updatedResource.url: resource.Url; //resource.Data = updatedResource.data; // NOT ALLOWED _myInfoMateDbContext.SaveChanges(); //OldResource resourceModified = _resourceService.Update(updatedResource.id, resource); return new OkObjectResult(resource.ToDTO()); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Delete a resource /// /// Id of resource to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("{id}")] public ObjectResult Delete(string id) { try { if (id == null) throw new ArgumentNullException("Resource param is null"); //var ressource = _resourceService.GetById(id); Resource resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == id); if (resource == null) throw new KeyNotFoundException("Resource does not exist"); List configurations = _myInfoMateDbContext.Configurations.Where(c => c.InstanceId == resource.InstanceId).ToList(); foreach (var configuration in configurations) { if (configuration.ImageId == id) { configuration.ImageId = null; configuration.ImageSource = null; } } List
sections = _myInfoMateDbContext.Sections.Where(s => s.InstanceId == resource.InstanceId).ToList(); // Delete all resource occurence foreach (var section in sections) { if (section.ImageId == id) { section.ImageId = null; section.ImageSource = null; } switch (section) { case SectionMap map: map.MapResourceId = map.MapResourceId == id ? null : map.MapResourceId; List geoPoints = _myInfoMateDbContext.GeoPoints.Where(s => s.SectionMapId == section.Id).ToList(); foreach (var point in geoPoints) { point.ImageResourceId = point.ImageResourceId == id ? null : point.ImageResourceId; foreach (var content in point.Contents) { if (content.resourceId == id) { content.resourceId = null; content.resource = null; _myInfoMateDbContext.Entry(point).Property(p => p.Contents).IsModified = true; } } } if (map.MapCategories != null) { foreach (var categorie in map.MapCategories) { if (categorie.resourceDTO.id == id) { categorie.resourceDTO = null; _myInfoMateDbContext.Entry(map).Property(p => p.MapCategories).IsModified = true; } } } break; case SectionSlider slider: foreach (var content in slider.SliderContents) { if (content.resourceId == id) { content.resource = null; content.resourceId = null; _myInfoMateDbContext.Entry(slider).Property(p => p.SliderContents).IsModified = true; } } break; case SectionQuiz quiz: //QuizDTO quizzDTO = JsonConvert.DeserializeObject(section.Data); List quizQuestions = _myInfoMateDbContext.QuizQuestions.Where(qq => qq.SectionQuizId == section.Id).ToList(); foreach (var question in quizQuestions) { if (question.Label != null) { foreach (var questionLabel in question.Label) { if (questionLabel.resourceId == id) { questionLabel.resource = null; questionLabel.resourceId = null; _myInfoMateDbContext.Entry(question).Property(p => p.Label).IsModified = true; } } } if (question.ResourceId == id) { question.ResourceId = null; question.Resource = null; } foreach (var response in question.Responses) { if (response.label != null) { foreach (var responseLabel in response.label) { if (responseLabel.resourceId == id) { responseLabel.resource = null; responseLabel.resourceId = null; _myInfoMateDbContext.Entry(response).Property(p => p.label).IsModified = true; } //responseLabel.resourceUrl = responseLabel.resourceId == id ? null : responseLabel.resourceUrl; //responseLabel.resourceId = responseLabel.resourceId == id ? null : responseLabel.resourceId; } } } } if (quiz.QuizBadLevel != null) { foreach (var quizBadLevel in quiz.QuizBadLevel) { if (quizBadLevel.resourceId == id) { quizBadLevel.resourceId = null; quizBadLevel.resource = null; _myInfoMateDbContext.Entry(quiz).Property(p => p.QuizBadLevel).IsModified = true; } } } if (quiz.QuizMediumLevel != null) { foreach (var quizMediumLevel in quiz.QuizMediumLevel) { if (quizMediumLevel.resourceId == id) { quizMediumLevel.resourceId = null; quizMediumLevel.resource = null; _myInfoMateDbContext.Entry(quiz).Property(p => p.QuizMediumLevel).IsModified = true; } } } if (quiz.QuizGoodLevel != null) { foreach (var quizGoodLevel in quiz.QuizGoodLevel) { if (quizGoodLevel.resourceId == id) { quizGoodLevel.resourceId = null; quizGoodLevel.resource = null; _myInfoMateDbContext.Entry(quiz).Property(p => p.QuizGoodLevel).IsModified = true; } } } if (quiz.QuizGreatLevel != null) { foreach (var quizGreatLevel in quiz.QuizGreatLevel) { if (quizGreatLevel.resourceId == id) { quizGreatLevel.resourceId = null; quizGreatLevel.resource = null; _myInfoMateDbContext.Entry(quiz).Property(p => p.QuizGreatLevel).IsModified = true; } } } break; case SectionArticle article: if (article.ArticleContents != null) { foreach (var content in article.ArticleContents) { if (content.resourceId == id) { content.resource = null; content.resourceId = null; _myInfoMateDbContext.Entry(article).Property(p => p.ArticleContents).IsModified = true; } } foreach (var audioId in article.ArticleAudioIds) { if (audioId.value == id) { audioId.value = null; _myInfoMateDbContext.Entry(article).Property(p => p.ArticleAudioIds).IsModified = true; } } } break; case SectionPdf pdf: if (pdf.PDFOrderedTranslationAndResources != null) { foreach (var orderedTranslationAndResource in pdf.PDFOrderedTranslationAndResources) { if (orderedTranslationAndResource.translationAndResourceDTOs != null) { foreach (var translationAndResource in orderedTranslationAndResource.translationAndResourceDTOs) { if (translationAndResource.value == id) { translationAndResource.value = null; _myInfoMateDbContext.Entry(pdf).Property(p => p.PDFOrderedTranslationAndResources).IsModified = true; } } } } } break; case SectionAgenda agenda: if (agenda.AgendaResourceIds != null) { foreach (var agendaResourceId in agenda.AgendaResourceIds) { if (agendaResourceId.value == id) { agendaResourceId.value = null; _myInfoMateDbContext.Entry(agenda).Property(p => p.AgendaResourceIds).IsModified = true; } } } break; case SectionPuzzle puzzle: if (puzzle.PuzzleMessageDebut != null) { foreach (var puzzleMessageDebut in puzzle.PuzzleMessageDebut) { if (puzzleMessageDebut.ResourceId == id) { puzzleMessageDebut.ResourceId = null; puzzleMessageDebut.Resource = null; _myInfoMateDbContext.Entry(puzzle).Property(p => p.PuzzleMessageDebut).IsModified = true; } } } if (puzzle.PuzzleMessageFin != null) { foreach (var puzzleMessageFin in puzzle.PuzzleMessageFin) { if (puzzleMessageFin.ResourceId == id) { puzzleMessageFin.ResourceId = null; puzzleMessageFin.Resource = null; _myInfoMateDbContext.Entry(puzzle).Property(p => p.PuzzleMessageFin).IsModified = true; } } } if (puzzle.PuzzleImageId == id) { puzzle.PuzzleImageId = null; puzzle.PuzzleImage = null; } break; case SectionVideo video: // TO BE TESTED .. if (resource.Url == video.VideoSource) { video.VideoSource = null; } break; } _myInfoMateDbContext.SaveChanges(); } _myInfoMateDbContext.Remove(resource); _myInfoMateDbContext.SaveChanges(); return new ObjectResult("The resource has been deleted") { StatusCode = 202 }; } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } } }