Skip to content

Commit

Permalink
feat: add more method in file manager
Browse files Browse the repository at this point in the history
  • Loading branch information
jxnkwlp committed Sep 12, 2023
1 parent 9fb8d37 commit ac5e4a8
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 60 deletions.
2 changes: 1 addition & 1 deletion modules/file-management/src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Product>Passingwind.Abp.FileManagement</Product>
<Description>an abp module that provider file and file container management </Description>
<Version>0.1.0</Version>
<PackageVersion>0.1.7</PackageVersion>
<PackageVersion>0.1.8</PackageVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;

namespace Passingwind.Abp.FileManagement.Files;

[IntegrationService]
public interface IFileIntegrationAppService : IApplicationService
{
Task<FileContainerDto> GetContainerAsync(Guid id);

Task<FileDto> GetAsync(string containerName, Guid id);

Task<Stream?> GetStreamAsync(string containerName, Guid id);
Task<byte[]> GetBytesAsync(string containerName, Guid id);

Task<FileDto> CreateByStreamAsync(string containerName, FileCreateByStreamDto input);
Task<FileDto> CreateByBytesAsync(string containerName, FileCreateByBytesDto input);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//using System;
//using System.IO;
//using System.Threading.Tasks;

//namespace Passingwind.Abp.FileManagement.Files;

//public class FileIntegrationAppService : FileManagementAppService, IFileIntegrationAppService
//{
// public Task<FileDto> CreateByBytesAsync(string containerName, FileCreateByBytesDto input)
// {
// throw new NotImplementedException();
// }

// public Task<FileDto> CreateByStreamAsync(string containerName, FileCreateByStreamDto input)
// {
// throw new NotImplementedException();
// }

// public Task<FileDto> GetAsync(string containerName, Guid id)
// {
// throw new NotImplementedException();
// }

// public Task<byte[]> GetBytesAsync(string containerName, Guid id)
// {
// throw new NotImplementedException();
// }

// public Task<FileContainerDto> GetContainerAsync(Guid id)
// {
// throw new NotImplementedException();
// }

// public Task<Stream?> GetStreamAsync(string containerName, Guid id)
// {
// throw new NotImplementedException();
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class FileShareTokenCleanupBackgroundWorker : AsyncPeriodicBackgroundWork
{
public FileShareTokenCleanupBackgroundWorker(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory) : base(timer, serviceScopeFactory)
{
// 12h
Timer.Period = 12 * 60 * 60 * 1000;
// 6h
Timer.Period = 6 * 60 * 60 * 1000;
}

protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Passingwind.Abp.FileManagement.Options;
Expand All @@ -8,23 +9,33 @@ namespace Passingwind.Abp.FileManagement.Files;

public class FileContainerManager : DomainService
{
private readonly IFileContainerRepository _fileContainerRepository;
private readonly FileManagementOptions _options;
protected IFileContainerRepository FileContainerRepository { get; }
protected FileManagementOptions FileManagementOptions { get; }

public FileContainerManager(IFileContainerRepository fileContainerRepository, IOptions<FileManagementOptions> options)
{
_fileContainerRepository = fileContainerRepository;
_options = options.Value;
FileContainerRepository = fileContainerRepository;
FileManagementOptions = options.Value;
}

public virtual async Task<FileContainer> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
{
return await FileContainerRepository.GetAsync(id, cancellationToken: cancellationToken);
}

public virtual async Task<FileContainer> GetByNameAsync(string name, CancellationToken cancellationToken = default)
{
return await FileContainerRepository.GetByNameAsync(name, cancellationToken);
}

public virtual async Task<bool> IsExistsAsync(FileContainer fileContainer, CancellationToken cancellationToken = default)
{
return await _fileContainerRepository.CheckExistsAsync(fileContainer, cancellationToken);
return await FileContainerRepository.CheckExistsAsync(fileContainer, cancellationToken);
}

public virtual async Task CheckExistsAsync(string name, CancellationToken cancellationToken = default)
{
_ = await _fileContainerRepository.GetByNameAsync(name, cancellationToken);
_ = await FileContainerRepository.GetByNameAsync(name, cancellationToken);
}

public virtual Task<FileContainer> CreateAsync(
Expand All @@ -39,15 +50,15 @@ public virtual async Task CheckExistsAsync(string name, CancellationToken cancel
string? prohibitedFileExtensions = null,
bool? autoDeleteBlob = false)
{
var entity = new FileContainer(GuidGenerator.Create(), name, accessMode ?? _options.DefaultContainerAccessMode)
var entity = new FileContainer(GuidGenerator.Create(), name, accessMode ?? FileManagementOptions.DefaultContainerAccessMode)
{
Description = description,
MaximumEachFileSize = maximumEachFileSize ?? _options.DefaultMaximumFileSize,
MaximumFileQuantity = maximumFileQuantity ?? _options.DefaultContainerMaximumFileQuantity,
MaximumEachFileSize = maximumEachFileSize ?? FileManagementOptions.DefaultMaximumFileSize,
MaximumFileQuantity = maximumFileQuantity ?? FileManagementOptions.DefaultContainerMaximumFileQuantity,
AllowAnyFileExtension = allowAnyFileExtension ?? false,
AllowedFileExtensions = allowedFileExtensions ?? string.Join(",", _options.DefaultAllowedFileExtensions ?? new string[0]),
ProhibitedFileExtensions = prohibitedFileExtensions ?? string.Join(",", _options.DefaultProhibitedFileExtensions ?? new string[0]),
OverrideBehavior = overrideBehavior ?? _options.DefaultOverrideBehavior,
AllowedFileExtensions = allowedFileExtensions ?? string.Join(",", FileManagementOptions.DefaultAllowedFileExtensions ?? new string[0]),
ProhibitedFileExtensions = prohibitedFileExtensions ?? string.Join(",", FileManagementOptions.DefaultProhibitedFileExtensions ?? new string[0]),
OverrideBehavior = overrideBehavior ?? FileManagementOptions.DefaultOverrideBehavior,
AutoDeleteBlob = autoDeleteBlob ?? false,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ namespace Passingwind.Abp.FileManagement.Files;

public class FileManager : DomainService, IFileManager
{
private readonly IFileRepository _fileRepository;
private readonly IFileContainerRepository _fileContainerRepository;
private readonly IBlobContainerFactory _blobContainerFactor;
private readonly IFileBlobNameGenerator _fileBlobNameGenerator;
private readonly IFileHashCalculator _fileHashCalculator;
private readonly IFileMimeTypeProvider _fileMimeTypeProvider;
private readonly IFileUniqueIdGenerator _fileUniqueIdGenerator;
private readonly IFileBlobContainerProvider _fileBlobContainerProvider;
private readonly IFileDuplicateDetectionProvider _fileDuplicateDetectionProvider;
private readonly FileManagementOptions _options;
private IFileRepository FileRepository { get; }
private IFileContainerRepository FileContainerRepository { get; }
private IBlobContainerFactory BlobContainerFactor { get; }
private IFileBlobNameGenerator FileBlobNameGenerator { get; }
private IFileHashCalculator FileHashCalculator { get; }
private IFileMimeTypeProvider FileMimeTypeProvider { get; }
private IFileUniqueIdGenerator FileUniqueIdGenerator { get; }
private IFileBlobContainerProvider FileBlobContainerProvider { get; }
private IFileDuplicateDetectionProvider FileDuplicateDetectionProvider { get; }
private FileManagementOptions FileManagementOptions { get; }

public FileManager(
IFileRepository fileRepository,
Expand All @@ -38,19 +38,19 @@ public class FileManager : DomainService, IFileManager
IFileDuplicateDetectionProvider fileDuplicateDetectionProvider,
IOptions<FileManagementOptions> options)
{
_fileRepository = fileRepository;
_fileContainerRepository = fileContainerRepository;
_blobContainerFactor = blobContainerFactor;
_fileBlobNameGenerator = fileBlobNameGenerator;
_fileHashCalculator = fileHashCalculator;
_fileMimeTypeProvider = fileMimeTypeProvider;
_fileUniqueIdGenerator = fileUniqueIdGenerator;
_fileBlobContainerProvider = fileBlobContainerProvider;
_fileDuplicateDetectionProvider = fileDuplicateDetectionProvider;
_options = options.Value;
FileRepository = fileRepository;
FileContainerRepository = fileContainerRepository;
BlobContainerFactor = blobContainerFactor;
FileBlobNameGenerator = fileBlobNameGenerator;
FileHashCalculator = fileHashCalculator;
FileMimeTypeProvider = fileMimeTypeProvider;
FileUniqueIdGenerator = fileUniqueIdGenerator;
FileBlobContainerProvider = fileBlobContainerProvider;
FileDuplicateDetectionProvider = fileDuplicateDetectionProvider;
FileManagementOptions = options.Value;
}

public async Task<File> FindFileAsync(FileContainer container, string fileName, Guid? parentId, CancellationToken cancellationToken = default)
public virtual async Task<File> FindFileAsync(FileContainer container, string fileName, Guid? parentId, CancellationToken cancellationToken = default)
{
if (container is null)
{
Expand All @@ -62,7 +62,7 @@ public async Task<File> FindFileAsync(FileContainer container, string fileName,
throw new ArgumentException($"'{nameof(fileName)}' cannot be null or empty.", nameof(fileName));
}

return await _fileRepository.FirstOrDefaultAsync(x => x.FileName == fileName && x.ParentId == parentId && x.ContainerId == container.Id && !x.IsDirectory);
return await FileRepository.FirstOrDefaultAsync(x => x.FileName == fileName && x.ParentId == parentId && x.ContainerId == container.Id && !x.IsDirectory);
}

public virtual async Task<bool> IsFileExistsAsync(FileContainer container, File file, CancellationToken cancellationToken = default)
Expand All @@ -80,7 +80,7 @@ public virtual async Task<bool> IsFileExistsAsync(FileContainer container, File
if (file.IsDirectory)
throw new ArgumentException();

return await _fileDuplicateDetectionProvider.IsExistsAsync(container, file, cancellationToken);
return await FileDuplicateDetectionProvider.IsExistsAsync(container, file, cancellationToken);
}

public virtual async Task<bool> IsDirectoryExistsAsync(FileContainer container, File file, CancellationToken cancellationToken = default)
Expand All @@ -98,7 +98,7 @@ public virtual async Task<bool> IsDirectoryExistsAsync(FileContainer container,
if (!file.IsDirectory)
throw new ArgumentException();

return await _fileDuplicateDetectionProvider.IsExistsAsync(container, file, cancellationToken);
return await FileDuplicateDetectionProvider.IsExistsAsync(container, file, cancellationToken);
}

public virtual Task CheckFileExtensionAsync(FileContainer container, File file, CancellationToken cancellationToken = default)
Expand Down Expand Up @@ -180,7 +180,7 @@ public virtual async Task CheckFileExistsAsync(FileContainer container, File fil
}
}

public async Task CheckDirectoryExistsAsync(FileContainer container, File entity, CancellationToken cancellationToken = default)
public virtual async Task CheckDirectoryExistsAsync(FileContainer container, File entity, CancellationToken cancellationToken = default)
{
if (container is null)
{
Expand Down Expand Up @@ -221,11 +221,11 @@ public virtual async Task<File> CreateFileAsync(FileContainer container, string
throw new ArgumentNullException(nameof(bytes));
}

var hash = await _fileHashCalculator.GetAsync(bytes);
var hash = await FileHashCalculator.GetAsync(bytes);

var fileId = GuidGenerator.Create();
var uniqueId = await _fileUniqueIdGenerator.CreateAsync(container, fileId);
var blobName = await _fileBlobNameGenerator.CreateAsync(container.Id, fileId, uniqueId, fileName, mimeType, bytes.Length, hash);
var uniqueId = await FileUniqueIdGenerator.CreateAsync(container, fileId);
var blobName = await FileBlobNameGenerator.CreateAsync(container.Id, fileId, uniqueId, fileName, mimeType, bytes.Length, hash);

var file = new File(
fileId,
Expand All @@ -243,7 +243,7 @@ public virtual async Task<File> CreateFileAsync(FileContainer container, string
return file;
}

public async Task<File> CreateDirectoryAsync(FileContainer container, string name, Guid? parentId, CancellationToken cancellationToken = default)
public virtual async Task<File> CreateDirectoryAsync(FileContainer container, string name, Guid? parentId, CancellationToken cancellationToken = default)
{
if (container is null)
{
Expand All @@ -256,8 +256,8 @@ public async Task<File> CreateDirectoryAsync(FileContainer container, string nam
}

var fileId = GuidGenerator.Create();
var uniqueId = await _fileUniqueIdGenerator.CreateAsync(container, fileId);
var blobName = await _fileBlobNameGenerator.CreateAsync(container.Id, fileId, uniqueId, name, string.Empty, 0, string.Empty);
var uniqueId = await FileUniqueIdGenerator.CreateAsync(container, fileId);
var blobName = await FileBlobNameGenerator.CreateAsync(container.Id, fileId, uniqueId, name, string.Empty, 0, string.Empty);

var file = new File(
fileId,
Expand Down Expand Up @@ -309,7 +309,7 @@ public virtual async Task<byte[]> GetFileBytesAsync(FileContainer container, Fil
throw new ArgumentNullException(nameof(file));
}

var blobContainer = await _fileBlobContainerProvider.GetAsync(container);
var blobContainer = await FileBlobContainerProvider.GetAsync(container);

return await blobContainer.GetAllBytesOrNullAsync(file.BlobName, cancellationToken);
}
Expand All @@ -326,7 +326,7 @@ public virtual async Task<byte[]> GetFileBytesAsync(FileContainer container, Fil
throw new ArgumentNullException(nameof(file));
}

var blobContainer = await _fileBlobContainerProvider.GetAsync(container);
var blobContainer = await FileBlobContainerProvider.GetAsync(container);

return await blobContainer.GetOrNullAsync(file.BlobName, cancellationToken);
}
Expand All @@ -348,7 +348,7 @@ public virtual async Task SaveBlobAsync(FileContainer container, File file, Stre
throw new ArgumentNullException(nameof(stream));
}

var blobContainer = await _fileBlobContainerProvider.GetAsync(container);
var blobContainer = await FileBlobContainerProvider.GetAsync(container);

await blobContainer.SaveAsync(file.BlobName, stream, true, cancellationToken);
}
Expand All @@ -370,12 +370,12 @@ public virtual async Task SaveBlobAsync(FileContainer container, File file, byte
throw new ArgumentNullException(nameof(bytes));
}

var blobContainer = await _fileBlobContainerProvider.GetAsync(container);
var blobContainer = await FileBlobContainerProvider.GetAsync(container);

await blobContainer.SaveAsync(file.BlobName, bytes, true, cancellationToken);
}

public async Task<File> ChangeFileNameAsync(FileContainer container, File file, string newName, Guid? parentId, CancellationToken cancellationToken = default)
public virtual async Task<File> ChangeFileNameAsync(FileContainer container, File file, string newName, Guid? parentId, CancellationToken cancellationToken = default)
{
if (container == null)
throw new ArgumentNullException(nameof(container));
Expand All @@ -392,43 +392,62 @@ public async Task<File> ChangeFileNameAsync(FileContainer container, File file,
file.SetFileName(newName);

if (!file.IsDirectory)
file.UpdateMimeType(_fileMimeTypeProvider.Get(newName));
file.UpdateMimeType(FileMimeTypeProvider.Get(newName));

await CheckFileExtensionAsync(container, file);

return file;
}

[UnitOfWork]
public async Task DeleteAsync(FileContainer container, File file, CancellationToken cancellationToken = default)
public virtual async Task DeleteAsync(FileContainer container, File file, CancellationToken cancellationToken = default)
{
await _fileRepository.DeleteAsync(file);
await FileRepository.DeleteAsync(file);

if (container.AutoDeleteBlob && !file.IsDirectory)
{
var blobContainer = await _fileBlobContainerProvider.GetAsync(container, cancellationToken: cancellationToken);
var blobContainer = await FileBlobContainerProvider.GetAsync(container, cancellationToken: cancellationToken);

await blobContainer.DeleteAsync(file.BlobName, cancellationToken);
}
}

[UnitOfWork]
public async Task ClearContainerFilesAsync(FileContainer container, CancellationToken cancellationToken = default)
public virtual async Task ClearContainerFilesAsync(FileContainer container, CancellationToken cancellationToken = default)
{
// TODO: performance

var files = await _fileRepository.GetListAsync(containerId: container.Id, cancellationToken: cancellationToken);
var files = await FileRepository.GetListAsync(containerId: container.Id, cancellationToken: cancellationToken);

foreach (var file in files)
{
await _fileRepository.DeleteAsync(file);
await FileRepository.DeleteAsync(file);

if (container.AutoDeleteBlob && !file.IsDirectory)
{
var blobContainer = await _fileBlobContainerProvider.GetAsync(container, cancellationToken: cancellationToken);
var blobContainer = await FileBlobContainerProvider.GetAsync(container, cancellationToken: cancellationToken);

await blobContainer.DeleteAsync(file.BlobName, cancellationToken);
}
}
}

public async Task<byte[]> GetFileBytesByFileIdAsync(string containerName, Guid id, CancellationToken cancellationToken = default)
{
var container = await FileContainerRepository.GetByNameAsync(containerName, cancellationToken);
var file = await FileRepository.GetAsync(id, cancellationToken: cancellationToken);
return await GetFileBytesAsync(container, file, cancellationToken);
}

public async Task<Stream?> GetFileSteamByFileIdAsync(string containerName, Guid id, CancellationToken cancellationToken = default)
{
var container = await FileContainerRepository.GetByNameAsync(containerName, cancellationToken);
var file = await FileRepository.GetAsync(id, cancellationToken: cancellationToken);
return await GetFileSteamAsync(container, file, cancellationToken);
}

public async Task<File> GetByIdAsync(string containerName, Guid id, CancellationToken cancellationToken = default)
{
return await FileRepository.GetAsync(id, cancellationToken: cancellationToken);
}
}
Loading

0 comments on commit ac5e4a8

Please sign in to comment.