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;
}
}
}