using System; using System.Drawing; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using RSecurityBackend.DbContext; using RSecurityBackend.Models.Auth.Db; using RSecurityBackend.Models.Generic; using RSecurityBackend.Models.Image; namespace RSecurityBackend.Services.Implementation { /// /// Image File Service /// public class ImageFileServiceEF : IImageFileService { /// /// Add Image File /// /// /// /// /// /// public async Task> Add(IFormFile file, Stream stream, string originalFileNameForStreams, string imageFolderName) { try { RServiceResult pictureFile = await ProcessImage ( file, new RImage() { DataTime = DateTime.Now, LastModified = DateTime.Now, FolderName = string.IsNullOrEmpty(imageFolderName) ? DateTime.Now.ToString("yyyy-MM") : imageFolderName }, stream, originalFileNameForStreams ); if (pictureFile == null) return new RServiceResult(null, pictureFile.ExceptionString); return new RServiceResult(pictureFile.Result); } catch (Exception exp) { return new RServiceResult(null, exp.ToString()); } } /// /// store added image /// /// /// public async Task> Store(RImage image) { try { _context.GeneralImages.Add(image); await _context.SaveChangesAsync(); return new RServiceResult(image); } catch (Exception exp) { return new RServiceResult(null, exp.ToString()); } } private async Task> ProcessImage(IFormFile uploadedImage, RImage pictureFile, Stream stream, string originalFileNameForStreams) { if (uploadedImage == null && stream == null) { return new RServiceResult(null, "ProcessImage: uploadedImage == null && stream == null"); } pictureFile.ContentType = uploadedImage == null ? "image/jpeg" : uploadedImage.ContentType; pictureFile.FileSizeInBytes = uploadedImage == null ? stream.Length : uploadedImage.Length; pictureFile.OriginalFileName = uploadedImage == null ? originalFileNameForStreams : uploadedImage.FileName; string fullDirStorePath = Path.Combine(ImageStoragePath, pictureFile.FolderName); if (!Directory.Exists(fullDirStorePath)) { try { Directory.CreateDirectory(fullDirStorePath); } catch { return new RServiceResult(null, $"ProcessImage: create dir failed {fullDirStorePath}"); } } string ext = uploadedImage == null ? ".jpg" : Path.GetExtension(uploadedImage.FileName); pictureFile.StoredFileName = Path.GetFileNameWithoutExtension(pictureFile.OriginalFileName) + ext; string originalFileStorePath = Path.Combine(fullDirStorePath, pictureFile.StoredFileName); while (File.Exists(originalFileStorePath)) { pictureFile.StoredFileName = Path.GetFileNameWithoutExtension(pictureFile.OriginalFileName) + "-" + Guid.NewGuid().ToString() + ext; originalFileStorePath = Path.Combine(fullDirStorePath, pictureFile.StoredFileName); } using (FileStream fsMain = new FileStream(originalFileStorePath, FileMode.Create)) { if (uploadedImage != null) await uploadedImage.CopyToAsync(fsMain); else await stream.CopyToAsync(fsMain); } using (MemoryStream ms = new MemoryStream()) { if (uploadedImage != null) await uploadedImage.CopyToAsync(ms); else { stream.Position = 0; await stream.CopyToAsync(ms); } using (Image img = Bitmap.FromStream(ms)) { pictureFile.ImageWidth = img.Width; pictureFile.ImageHeight = img.Height; } } return new RServiceResult(pictureFile); } /// /// returns image info /// /// /// public async Task> GetImage(Guid id) { try { return new RServiceResult( await _context.GeneralImages .Where(p => p.Id == id) .SingleOrDefaultAsync() ); } catch (Exception exp) { return new RServiceResult(null, exp.ToString()); } } /// /// delete image (from database and file system) /// /// /// public async Task> DeleteImage(Guid id) { try { RServiceResult img = await GetImage(id); if(!string.IsNullOrEmpty(img.ExceptionString)) return new RServiceResult(false, img.ExceptionString); if(img.Result == null) { return new RServiceResult(false, "image not found"); } File.Delete(GetImagePath(img.Result).Result); _context.GeneralImages.Remove(img.Result); await _context.SaveChangesAsync(); return new RServiceResult(true); } catch (Exception exp) { return new RServiceResult(false, exp.ToString()); } } /// /// Get Image Storage Path /// /// /// public RServiceResult GetImagePath(RImage image) { try { return new RServiceResult(Path.Combine(ImageStoragePath, image.FolderName, image.StoredFileName)); } catch (Exception exp) { return new RServiceResult(null, exp.ToString()); } } /// /// Image Storage Path /// public string ImageStoragePath { get { return $"{Configuration.GetSection("PictureFileService")["StoragePath"]}"; } } /// /// Database Contetxt /// protected readonly RSecurityDbContext _context; /// /// Configuration /// protected IConfiguration Configuration { get; } /// /// constructor /// /// /// public ImageFileServiceEF(RSecurityDbContext context, IConfiguration configuration) { _context = context; Configuration = configuration; } } }