using Netina.Domain.Dtos.SmallDtos; using Netina.Domain.Enums; namespace Netina.Infrastructure.Services; public class StorageService(IOptionsSnapshot snapshot) : IStorageService { private IAmazonS3? _s3Client; private readonly string _bucketName = snapshot.Value.StorageSetting.BucketKey; private readonly string _accessKey = snapshot.Value.StorageSetting.AccessKey; private readonly string _secretKey = snapshot.Value.StorageSetting.SecretKey; private IAmazonS3 GetClientAsync() { var awsCredentials = new Amazon.Runtime.BasicAWSCredentials(secretKey: _secretKey, accessKey: _accessKey); var config = new AmazonS3Config { ServiceURL = "https://s3.ir-thr-at1.arvanstorage.ir" }; _s3Client = new AmazonS3Client(awsCredentials, config); return _s3Client; } public async Task UploadObjectFromFileAsync(string fileName, string filePath, string contentType, byte[] fileBytes, bool fixName = true) { using var memorySteam = new MemoryStream(fileBytes); var client = GetClientAsync(); if (fixName) { var fileEx = fileName.Split('.').Last(); fileName = fileName.Split('.').First(); fileName = fileName + "_" + StringExtensions.GetId(5) + "_" + DateTime.Today.ToString("yyyy-MM-dd-HH-mm-ss") + "." + fileEx; } var putRequest = new PutObjectRequest { BucketName = _bucketName, Key = Path.Combine(filePath, fileName), ContentType = contentType, InputStream = memorySteam, CannedACL = S3CannedACL.PublicRead, }; putRequest.Metadata.Add("x-amz-meta-title", fileName); PutObjectResponse response = await client.PutObjectAsync(putRequest); return fileName; } public async Task UploadObjectFromFileAsync(string fileName, string filePath, string contentType, Stream fileStream , bool fixName = true) { var client = GetClientAsync(); if (fixName) { var fileEx = fileName.Split('.').Last(); fileName = fileName.Split('.').First(); fileName = fileName + "_" + StringExtensions.GetId(5) + "_" + DateTimeExtensions.DateTimeToUnixTimeStamp(DateTime.Now) + "." + fileEx; } var putRequest = new PutObjectRequest { BucketName = _bucketName, Key = Path.Combine(filePath, fileName), ContentType = contentType, InputStream = fileStream, CannedACL = S3CannedACL.PublicRead }; //putRequest.Metadata.Add("x-amz-meta-title", fileName); PutObjectResponse response = await client.PutObjectAsync(putRequest); return fileName; } public async Task> GetStorageFiles(StorageFileType fileType) { var client = GetClientAsync(); ListObjectsV2Request request = new() { BucketName = _bucketName, MaxKeys = 3000 }; switch (fileType) { case StorageFileType.Image: request.Prefix = "Images/Med"; break; case StorageFileType.Video: request.Prefix = "Videos"; break; default: break; } var pagination = client.Paginators.ListObjectsV2(request); var s3Files = new List(); await foreach (var listObjectsV2Response in pagination.Responses) { s3Files.AddRange(listObjectsV2Response.S3Objects); } var files = s3Files .OrderByDescending(s => s.LastModified) .Take(100) .Select(s => new StorageFileSDto { FileLocation = s.Key, FileName = s.Key.Split('/').Last() }).ToList(); return files.ToList(); } }