diff --git a/Tsi1.Api/Tsi1.Api/Controllers/CourseController.cs b/Tsi1.Api/Tsi1.Api/Controllers/CourseController.cs index cb90fae29fb465e9298dddbe750edfbf5e5677c3..70011e2bd59fa3628dc95f441532effc308e8db7 100644 --- a/Tsi1.Api/Tsi1.Api/Controllers/CourseController.cs +++ b/Tsi1.Api/Tsi1.Api/Controllers/CourseController.cs @@ -49,7 +49,6 @@ namespace Tsi1.Api.Controllers public async Task<IActionResult> Create(CourseCreateDto newCourse) { var tenantId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "TenantId").Value); - newCourse.TenantId = tenantId; var result = await _courseService.Create(newCourse); @@ -58,10 +57,6 @@ namespace Tsi1.Api.Controllers return BadRequest(result.Message); } - var path = Path.Combine(tenantId.ToString(), result.Data.Id.ToString()); - - _fileService.CreateFolder(path); - return Ok(); } @@ -213,10 +208,6 @@ namespace Tsi1.Api.Controllers return NotFound(result.Message); } - var path = Path.Combine(result.Data.TenantId.ToString(), result.Data.Id.ToString()); - - _fileService.DeleteFolder(path); - return Ok(); } diff --git a/Tsi1.Api/Tsi1.Api/Controllers/FileController.cs b/Tsi1.Api/Tsi1.Api/Controllers/FileController.cs index 144a8298f82892a2caafe88b4957da0c01b96b24..fb7296dfe4acc041f55513ebeb4dd8b42bc18489 100644 --- a/Tsi1.Api/Tsi1.Api/Controllers/FileController.cs +++ b/Tsi1.Api/Tsi1.Api/Controllers/FileController.cs @@ -22,13 +22,12 @@ namespace Tsi1.Api.Controllers } [Authorize(Roles = UserTypes.Professor)] - [HttpPost("Create/{courseId}")] - public async Task<IActionResult> Create(IFormFile file, int courseId) + [HttpPost("Upload/{courseId}")] + public async Task<IActionResult> Upload(IFormFile file, int courseId) { - var tenantId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "TenantId").Value); - - var result = await _fileService.Create(file, tenantId, courseId); + var tenantId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "TenantId").Value; + var result = await _fileService.Create(file, tenantId, courseId.ToString()); if (result.HasError) { return BadRequest(result.Message); diff --git a/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs b/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs index 92a0665ffad2a0892a1365f1b16fbbf9730a92e6..9b597317ccc3eadd4638d7e5e46a72232ed7abc3 100644 --- a/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs +++ b/Tsi1.Api/Tsi1.Api/Controllers/TenantController.cs @@ -50,8 +50,6 @@ namespace Tsi1.Api.Controllers return BadRequest(result.Message); } - _fileService.CreateFolder(result.Data.Id.ToString()); - return Ok(result.Data); } @@ -90,8 +88,6 @@ namespace Tsi1.Api.Controllers return NotFound(result.Message); } - _fileService.DeleteFolder(tenantId.ToString()); - return Ok(); } diff --git a/Tsi1.Api/Tsi1.Api/Startup.cs b/Tsi1.Api/Tsi1.Api/Startup.cs index 71f448fa6e8dd7b5592552cd95561982da8d3a0a..55f7de4a151c1a5658bba8cda2ba0f6c569f4dd8 100644 --- a/Tsi1.Api/Tsi1.Api/Startup.cs +++ b/Tsi1.Api/Tsi1.Api/Startup.cs @@ -24,6 +24,7 @@ using Microsoft.OpenApi.Models; using Tsi1.Api.Infrastructure; using Tsi1.Api.SignalR; using Tsi1.BusinessLayer.Helpers; +using Tsi1.BusinessLayer.HostedServices; using Tsi1.BusinessLayer.Interfaces; using Tsi1.BusinessLayer.Services; using Tsi1.DataLayer; @@ -67,7 +68,7 @@ namespace Tsi1.Api services.AddSingleton<IJwtAuthManager, JwtAuthManager>(); services.AddHostedService<JwtRefreshTokenCache>(); services.AddHostedService<JwtVerificationCodeCache>(); - + services.AddHostedService<FileCleanerService>(); services.AddSingleton<IMessageService, MessageService>(); diff --git a/Tsi1.Api/Tsi1.BusinessLayer/HostedServices/FileCleanerService.cs b/Tsi1.Api/Tsi1.BusinessLayer/HostedServices/FileCleanerService.cs new file mode 100644 index 0000000000000000000000000000000000000000..0a95d33dacd68f459f355c1ad2a75c12e0caa878 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/HostedServices/FileCleanerService.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tsi1.BusinessLayer.Interfaces; + +namespace Tsi1.BusinessLayer.HostedServices +{ + public class FileCleanerService : IHostedService, IDisposable + { + private Timer _timer; + private readonly IFileService _fileService; + + public FileCleanerService(IFileService fileService) + { + _fileService = fileService; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + private void DoWork(object state) + { + + } + + public Task StopAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + _timer?.Dispose(); + } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IFileService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IFileService.cs index ced47caca7d35ce35dd360ff9049df6c77a02cde..d5651e0dd6a367e823c4e831b462879e01b3b1ff 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IFileService.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IFileService.cs @@ -10,9 +10,8 @@ namespace Tsi1.BusinessLayer.Interfaces { public interface IFileService { - Task<ServiceResult<FileDto>> Create(IFormFile file, int tenantId, int courseId); - void CreateFolder(string folderPath); - void DeleteFolder(string folderPath); + Task<ServiceResult<string>> Create(IFormFile file, string tenantId, string courseId); + ServiceResult<bool> DeleteFile(string filePath); bool ExistFile(string relativePath); } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs index 937a3343bb58e01399059b949471cbfc54b3b264..6a2f58803e877501bbef063effa082a2e6fd292e 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/FileService.cs @@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Threading.Tasks; using Tsi1.BusinessLayer.Dtos; @@ -27,13 +28,12 @@ namespace Tsi1.BusinessLayer.Services { _context = context; _mapper = mapper; - _path = hostingEnvironment.ContentRootPath + "/StaticFiles"; + _path = Path.Combine(hostingEnvironment.ContentRootPath, "StaticFiles"); } public async Task<ServiceResult<string>> SaveFile(IFormFile file, string filePath) { var result = new ServiceResult<string>(); - var fileStream = new FileStream(filePath, FileMode.Create); try @@ -54,57 +54,37 @@ namespace Tsi1.BusinessLayer.Services return result; } - - - public async Task<ServiceResult<FileDto>> Create(IFormFile file, int tenantId, int courseId) + public async Task<ServiceResult<string>> Create(IFormFile file, string tenantId, string courseId) { - var result = new ServiceResult<FileDto>(); - - var tenant = await _context.Tenants - .FirstOrDefaultAsync(x => x.Id == tenantId); + var result = new ServiceResult<string>(); - var course = await _context.Courses - .FirstOrDefaultAsync(x => x.Id == courseId); + var path = Path.Combine(_path, tenantId, courseId); + Directory.CreateDirectory(path); - var filePath = Path.Combine(_path, tenant.Name, course.Name, file.FileName); + var fileName = GenerateFileName(file); + var filePath = Path.Combine(path, fileName); + var fileStream = new FileStream(filePath, FileMode.Create); - var existingFile = await _context.Files.FirstOrDefaultAsync(x => x.Path == filePath); - if (existingFile != null) + try { - result.HasError = true; - result.Message = string.Format(ErrorMessages.DuplicateFile, filePath); - return result; + await file.CopyToAsync(fileStream); } - - var newFile = new DataLayer.Entities.File - { - Name = file.FileName, - Path = filePath.Replace(_path, ""), - }; - - _context.Add(newFile); - await _context.SaveChangesAsync(); - - var resultSaveFile = await this.SaveFile(file, filePath); - if (resultSaveFile.HasError) + catch (Exception) { result.HasError = true; - result.Message = resultSaveFile.Message; - - _context.Remove(newFile); - await _context.SaveChangesAsync(); - + result.Message = string.Format(ErrorMessages.ErrorSavingFile, filePath); return result; } + finally + { + fileStream.Close(); + } - var fileDto = _mapper.Map<FileDto>(newFile); - result.Data = fileDto; - + result.Data = filePath.Replace(_path, string.Empty); return result; } - - public async Task<ServiceResult<bool>> DeleteFile(string filePath) + public ServiceResult<bool> DeleteFile(string filePath) { var result = new ServiceResult<bool>(); @@ -122,24 +102,18 @@ namespace Tsi1.BusinessLayer.Services return result; } - public void CreateFolder(string folderPath) + public bool ExistFile(string relativePath) { - var path = Path.Combine(_path, folderPath); - - Directory.CreateDirectory(path); + var path = Path.Combine(_path, relativePath); + return System.IO.File.Exists(path); } - public void DeleteFolder(string folderPath) + private string GenerateFileName(IFormFile file) { - var path = Path.Combine(_path, folderPath); - - Directory.Delete(path); - } + var ext = file.FileName.Split(".").Last(); + var fileName = Guid.NewGuid().ToString(); - public bool ExistFile(string relativePath) - { - var path = Path.Combine(_path, relativePath); - return System.IO.File.Exists(path); + return fileName + "." + ext; } } }