-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
525 additions
and
44 deletions.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
backend/SoftwareEngineering2/Controllers/ImagesController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using SoftwareEngineering2.DTO; | ||
using Swashbuckle.AspNetCore.Annotations; | ||
using SoftwareEngineering2.Interfaces; | ||
|
||
namespace SoftwareEngineering2.Controllers { | ||
[Route("api/images")] | ||
[ApiController] | ||
public class ImagesController : ControllerBase { | ||
private readonly IImageService _imageService; | ||
|
||
public ImagesController(IImageService imageService, IProductService productService) { | ||
_imageService = imageService; | ||
} | ||
|
||
// POST: api/images | ||
[HttpPost] | ||
[SwaggerOperation(Summary = "Upload new image")] | ||
[SwaggerResponse(401, "Unauthorised")] | ||
[SwaggerResponse(201, "Created")] | ||
[Authorize(Roles = Roles.Employee)] | ||
public async Task<ActionResult<ImageDTO>> UploadImage([FromForm] NewImageDTO image) { | ||
var result = await _imageService.UploadImageAsync(image); | ||
return CreatedAtAction(nameof(UploadImage), new {id = result.ImageId}, result); | ||
} | ||
|
||
// GET: api/images/5 | ||
[HttpGet("{imageId:int}")] | ||
[SwaggerOperation(Summary = "Fetch a specific image")] | ||
[SwaggerResponse(200, "Returns an image", typeof(ImageDTO))] | ||
[SwaggerResponse(404, "Image not found")] | ||
public async Task<IActionResult> GetImageById(int imageId) { | ||
var image = await _imageService.GetImageByIdAsync(imageId); | ||
return image != null ? | ||
Ok(image) : | ||
NotFound(new { message = $"No image found with id {imageId}" }); | ||
} | ||
|
||
// DELETE: api/images/5 | ||
[HttpDelete("{imageId:int}")] | ||
[SwaggerOperation(Summary = "Delete a specific image")] | ||
[SwaggerResponse(204, "No Content")] | ||
[SwaggerResponse(404, "Image not found")] | ||
[Authorize(Roles = Roles.Employee)] | ||
public async Task<IActionResult> DeleteImage(int imageId) { | ||
try { | ||
await _imageService.DeleteImageAsync(imageId); | ||
} | ||
catch (KeyNotFoundException e) { | ||
return NotFound(new { message = $"No image found with id {imageId}" }); | ||
} | ||
|
||
return NoContent(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace SoftwareEngineering2.DTO; | ||
|
||
public record ImageDTO() { | ||
public int ImageId { get; init; } | ||
|
||
public Uri ImageUri { get; init; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
namespace SoftwareEngineering2.DTO; | ||
|
||
public record NewImageDTO() { | ||
public IFormFile Image { get; init; } | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
backend/SoftwareEngineering2/Interfaces/IImageRepository.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using SoftwareEngineering2.Models; | ||
|
||
namespace SoftwareEngineering2.Interfaces; | ||
|
||
public interface IImageRepository { | ||
public Task AddAsync(ImageModel image); | ||
|
||
Task<ImageModel?> GetByIdAsync(int id); | ||
|
||
void Delete(ImageModel image); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using SoftwareEngineering2.DTO; | ||
|
||
namespace SoftwareEngineering2.Interfaces; | ||
|
||
public interface IImageService { | ||
Task<ImageDTO> UploadImageAsync(NewImageDTO image); | ||
|
||
Task<ImageDTO?> GetImageByIdAsync(int imageId); | ||
|
||
Task DeleteImageAsync(int imageId); | ||
} |
12 changes: 12 additions & 0 deletions
12
backend/SoftwareEngineering2/ModelEntityTypeConfiguration/ImageModelEntityConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.EntityFrameworkCore.Metadata.Builders; | ||
using SoftwareEngineering2.Models; | ||
|
||
namespace SoftwareEngineering2.ModelEntityTypeConfiguration; | ||
|
||
public class ImageModelEntityConfiguration : IEntityTypeConfiguration<ImageModel> { | ||
public void Configure(EntityTypeBuilder<ImageModel> builder) { | ||
builder.HasKey(x => x.ImageId); | ||
builder.Property(x => x.ImageUri).IsRequired(); | ||
} | ||
} |
3 changes: 2 additions & 1 deletion
3
backend/SoftwareEngineering2/ModelEntityTypeConfiguration/ProductModelEntityConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace SoftwareEngineering2.Models; | ||
|
||
public class ImageModel { | ||
public int ImageId { get; set; } | ||
|
||
public Uri ImageUri { get; set; } | ||
|
||
public List<ProductModel> Products { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
backend/SoftwareEngineering2/Repositories/ImageRepository.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using Microsoft.EntityFrameworkCore; | ||
using SoftwareEngineering2.Interfaces; | ||
using SoftwareEngineering2.Models; | ||
|
||
namespace SoftwareEngineering2.Repositories; | ||
|
||
public class ImageRepository : IImageRepository { | ||
private readonly FlowerShopContext _context; | ||
|
||
public ImageRepository(FlowerShopContext context) { | ||
_context = context; | ||
} | ||
|
||
public async Task AddAsync(ImageModel image) { | ||
await _context.ImageModels.AddAsync(image); | ||
} | ||
|
||
public async Task<ImageModel?> GetByIdAsync(int id) { | ||
return await _context.ImageModels | ||
.FirstOrDefaultAsync(image => image.ImageId == id); | ||
} | ||
|
||
public void Delete(ImageModel image) { | ||
_context.ImageModels.Remove(image); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using Amazon; | ||
using Amazon.S3; | ||
using Amazon.S3.Model; | ||
using AutoMapper; | ||
using SoftwareEngineering2.DTO; | ||
using SoftwareEngineering2.Interfaces; | ||
using SoftwareEngineering2.Models; | ||
|
||
namespace SoftwareEngineering2.Services; | ||
|
||
public class ImageService : IImageService { | ||
private readonly IUnitOfWork _unitOfWork; | ||
private readonly IImageRepository _imageRepository; | ||
private IAmazonS3 _s3Client; | ||
private readonly string _bucketName; | ||
private readonly IMapper _mapper; | ||
|
||
public ImageService( | ||
IUnitOfWork unitOfWork, | ||
IImageRepository imageRepository, | ||
string bucketName, | ||
RegionEndpoint regionEndpoint, | ||
IMapper mapper) { | ||
_unitOfWork = unitOfWork; | ||
_imageRepository = imageRepository; | ||
_bucketName = bucketName; | ||
_s3Client = new AmazonS3Client(regionEndpoint); | ||
_mapper = mapper; | ||
} | ||
|
||
public async Task<ImageDTO> UploadImageAsync(NewImageDTO image) { | ||
var datatype = image.Image.FileName.Split('.').Last(); | ||
if (datatype != "png" && datatype != "jpg" && datatype != "jpeg") { | ||
throw new Exception("Invalid image type"); | ||
} | ||
|
||
var filename = Guid.NewGuid().ToString() + "." + datatype; | ||
var path = Path.Combine(Path.GetTempPath(), filename); | ||
await using (var stream = new FileStream(path, FileMode.Create)) { | ||
await image.Image.CopyToAsync(stream); | ||
} | ||
|
||
var uploadRequest = new PutObjectRequest() { | ||
BucketName = _bucketName, | ||
Key = filename, | ||
ContentType = "image/" + datatype, | ||
FilePath = path | ||
}; | ||
|
||
var response = await _s3Client.PutObjectAsync(uploadRequest); | ||
if (response.HttpStatusCode != System.Net.HttpStatusCode.OK) { | ||
throw new Exception("Failed to upload image"); | ||
} | ||
|
||
var model = new ImageModel() { | ||
ImageUri = new Uri($"https://{_bucketName}.s3.amazonaws.com/{uploadRequest.Key}") | ||
}; | ||
|
||
await _imageRepository.AddAsync(model); | ||
await _unitOfWork.SaveChangesAsync(); | ||
return _mapper.Map<ImageDTO>(model); | ||
} | ||
|
||
public async Task<ImageDTO?> GetImageByIdAsync(int imageId) { | ||
var result = await _imageRepository.GetByIdAsync(imageId); | ||
return result != null ? | ||
_mapper.Map<ImageDTO>(result) : | ||
null; | ||
} | ||
|
||
public async Task DeleteImageAsync(int imageId) { | ||
var image = await _imageRepository.GetByIdAsync(imageId) ?? throw new KeyNotFoundException("Image not found"); | ||
var objectName = image.ImageUri.Segments.Last(); | ||
|
||
var request = new DeleteObjectRequest { | ||
BucketName = _bucketName, | ||
Key = objectName | ||
}; | ||
|
||
var response = await _s3Client.DeleteObjectAsync(request); | ||
if (response.HttpStatusCode != System.Net.HttpStatusCode.Accepted && response.HttpStatusCode != System.Net.HttpStatusCode.NoContent) { | ||
throw new Exception("Failed to delete image"); | ||
} | ||
|
||
_imageRepository.Delete(image); | ||
await _unitOfWork.SaveChangesAsync(); | ||
} | ||
} |
Oops, something went wrong.