diff --git a/API/API.Client.Test/App.config b/API/API.Client.Test/App.config index bf54cdd..51bf85b 100644 --- a/API/API.Client.Test/App.config +++ b/API/API.Client.Test/App.config @@ -1,8 +1,8 @@  - - + + \ No newline at end of file diff --git a/API/API/API.csproj b/API/API/API.csproj index ceb5fe8..8c21058 100644 --- a/API/API/API.csproj +++ b/API/API/API.csproj @@ -154,6 +154,7 @@ + diff --git a/API/API/App_Start/DependencyInjectionConfig.cs b/API/API/App_Start/DependencyInjectionConfig.cs index cea1932..6d9e122 100644 --- a/API/API/App_Start/DependencyInjectionConfig.cs +++ b/API/API/App_Start/DependencyInjectionConfig.cs @@ -33,6 +33,7 @@ namespace API.App_Start { builder.RegisterType(); builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As(); } private static void RegisterDataProvider(this ContainerBuilder builder) { diff --git a/API/API/Controllers/FilesController.cs b/API/API/Controllers/FilesController.cs index 8152d50..1e809cd 100644 --- a/API/API/Controllers/FilesController.cs +++ b/API/API/Controllers/FilesController.cs @@ -12,15 +12,17 @@ namespace API.Controllers { public class FilesController : ApiController { private readonly DataContext dataContext; private readonly IFileService fileService; + private readonly IFileGarbageCollectionService fileGarbageCollectionService; private readonly string dataPath; public FilesController( DataContext dataContext, - IFileService fileService + IFileService fileService, + IFileGarbageCollectionService fileGarbageCollectionService ) { this.dataContext = dataContext; this.fileService = fileService; - + this.fileGarbageCollectionService = fileGarbageCollectionService; dataPath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data"); } @@ -28,6 +30,7 @@ namespace API.Controllers { [Route("api/songs/{songId}/files/{fileId}")] public HttpResponseMessage Get(long songId, long fileId) { var response = new HttpResponseMessage(HttpStatusCode.OK); + fileGarbageCollectionService.Collect(dataPath); var file = dataContext.Files.Find(fileId); if (file == null || file.Song.ID != songId) return new HttpResponseMessage(HttpStatusCode.NotFound); @@ -46,6 +49,8 @@ namespace API.Controllers { // POST: api/Files [Route("api/songs/{songId}/files")] public async Task Post(long songId, CancellationToken c) { + fileGarbageCollectionService.Collect(dataPath); + // get file from network input var files = HttpContext.Current.Request.Files; if (files.Count != 1) return new HttpResponseMessage(HttpStatusCode.BadRequest); diff --git a/API/API/Services/FileGarbageCollectionService.cs b/API/API/Services/FileGarbageCollectionService.cs new file mode 100644 index 0000000..4476731 --- /dev/null +++ b/API/API/Services/FileGarbageCollectionService.cs @@ -0,0 +1,34 @@ +using API.Database; +using System.Linq; + +namespace API.Services { + public interface IFileGarbageCollectionService { + void Collect(string path); + } + public class FileGarbageCollectionService : IFileGarbageCollectionService { + private readonly IFileService fileService; + private readonly DataContext dataContext; + private readonly string[] fileExcludes; + + public FileGarbageCollectionService( + IFileService fileService, + DataContext dataContext + ) { + this.fileService = fileService; + this.dataContext = dataContext; + fileExcludes = new[] { "environment.json" }; + } + + public void Collect(string path) { + var filesInStoreage = fileService.ListFiles(path); + var filesInDatabase = dataContext.Files.Select(_ => _.ReferenceFile.ToString()); + var filesWithoutReference = filesInStoreage + .Except(filesInDatabase) + .Except(fileExcludes); + + foreach (var file in filesWithoutReference) { + fileService.Delete(path, file); + } + } + } +} \ No newline at end of file diff --git a/API/API/Services/FileService.cs b/API/API/Services/FileService.cs index 43c4f11..8319537 100644 --- a/API/API/Services/FileService.cs +++ b/API/API/Services/FileService.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -7,6 +9,8 @@ namespace API.Services { public interface IFileService { Task Save(Stream file, string path, CancellationToken c); Stream Load(string path, string filename); + void Delete(string path, string filename); + IEnumerable ListFiles(string path); } public class FileService : IFileService { @@ -21,12 +25,24 @@ namespace API.Services { return filename; } - + public Stream Load(string path, string filename) { var fullPath = Path.Combine(path, filename.ToString()); var fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize, true); return fileStream; } + public void Delete(string path, string filename) { + var fullPath = Path.Combine(path, filename.ToString()); + File.Delete(fullPath); + } + + public IEnumerable ListFiles(string path) { + var directoryInfo = new DirectoryInfo(path); + var files = directoryInfo.GetFiles(); + var fileNames = files.Select(_ => _.Name); + return fileNames; + } + } } \ No newline at end of file diff --git a/API/API/Web.config b/API/API/Web.config index a569aec..0b6a427 100644 --- a/API/API/Web.config +++ b/API/API/Web.config @@ -19,7 +19,7 @@ - +