-
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.
Merge pull request #26 from quizer-app/develop
Add image service
- Loading branch information
Showing
18 changed files
with
275 additions
and
13 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,4 +1,5 @@ | ||
**/.vs | ||
**/bin | ||
**/obj | ||
**/logs | ||
**/logs | ||
**/wwwroot |
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
Binary file not shown.
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,27 @@ | ||
#!/bin/bash | ||
|
||
# Set the source and destination directories | ||
source_dir="/src/images" | ||
destination_dir="/files/wwwroot/images" | ||
|
||
# Create the destination directory if it doesn't exist | ||
mkdir -p "$destination_dir" | ||
|
||
# Loop through .webp files in the source directory | ||
for webp_file in "$source_dir"/*.webp; do | ||
if [ -f "$webp_file" ]; then | ||
# Extract the name (without extension) from the file | ||
name_without_extension=$(basename "$webp_file" .webp) | ||
|
||
# Create a subdirectory for each file in the destination directory | ||
subdestination_dir="$destination_dir/$name_without_extension" | ||
mkdir -p "$subdestination_dir" | ||
|
||
# Move the .webp file to the subdirectory with the name "default.webp" | ||
mv "$webp_file" "$subdestination_dir/default.webp" | ||
|
||
echo "File '$webp_file' moved to '$subdestination_dir/default.webp'" | ||
fi | ||
done | ||
|
||
echo "Files moved successfully." |
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
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
7 changes: 3 additions & 4 deletions
7
src/Quizer.Application/Quizes/Commands/UpdateQuiz/UpdateQuizCommandHandler.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
10 changes: 10 additions & 0 deletions
10
src/Quizer.Application/Quizes/Commands/UpdateQuizImage/UpdateQuizImageCommand.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,10 @@ | ||
using ErrorOr; | ||
using MediatR; | ||
using Microsoft.AspNetCore.Http; | ||
using Quizer.Domain.QuizAggregate; | ||
|
||
namespace Quizer.Application.Quizes.Commands.UpdateQuizImage; | ||
|
||
public record UpdateQuizImageCommand( | ||
Guid QuizId, | ||
IFormFile File) : IRequest<ErrorOr<QuizId>>; |
69 changes: 69 additions & 0 deletions
69
src/Quizer.Application/Quizes/Commands/UpdateQuizImage/UpdateQuizImageCommandHandler.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,69 @@ | ||
using ErrorOr; | ||
using MediatR; | ||
using Microsoft.AspNetCore.Http; | ||
using Quizer.Application.Services.Image; | ||
using Quizer.Domain.Common.Errors; | ||
using Quizer.Domain.QuizAggregate; | ||
|
||
namespace Quizer.Application.Quizes.Commands.UpdateQuizImage; | ||
|
||
public class UpdateQuizImageCommandHandler : IRequestHandler<UpdateQuizImageCommand, ErrorOr<QuizId>> | ||
{ | ||
private readonly IImageService _imageService; | ||
|
||
public UpdateQuizImageCommandHandler(IImageService imageService) | ||
{ | ||
_imageService = imageService; | ||
} | ||
|
||
public async Task<ErrorOr<QuizId>> Handle(UpdateQuizImageCommand request, CancellationToken cancellationToken) | ||
{ | ||
string[] correctExtensions = { ".jpg", ".jpeg", ".png", ".webp" }; | ||
|
||
if (!IsCorrectExtension(request.File.FileName, correctExtensions)) | ||
return Errors.Image.WrongFormat(correctExtensions); | ||
|
||
var id = QuizId.Create(request.QuizId); | ||
|
||
string tempFilePath = await SaveTempFile(request.File); | ||
|
||
string imageDir = _imageService.GetImageDir("quiz"); | ||
|
||
var imageProcessResult = ProcessImage(tempFilePath, imageDir, id.Value); | ||
if (imageProcessResult.IsError) | ||
return imageProcessResult.Errors; | ||
|
||
return id; | ||
} | ||
|
||
private ErrorOr<string> ProcessImage(string tempFilePath, string imageDir, Guid id) | ||
{ | ||
string? imagePath = _imageService.FormatAndMove(tempFilePath, imageDir, id); | ||
if (imagePath is null) | ||
return Errors.Image.CannotUpload; | ||
|
||
bool resized = _imageService.Resize(imagePath, 512, 288); | ||
if (!resized) | ||
return Errors.Image.CannotUpload; | ||
|
||
return imagePath; | ||
} | ||
|
||
private bool IsCorrectExtension(string fileName, string[] correctExtensions) | ||
{ | ||
string extension = Path.GetExtension(fileName); | ||
|
||
return correctExtensions.Contains(extension); | ||
} | ||
|
||
private async Task<string> SaveTempFile(IFormFile file) | ||
{ | ||
string tempFilePath = Path.GetTempFileName(); | ||
using (var stream = new FileStream(tempFilePath, FileMode.Create)) | ||
{ | ||
await file.CopyToAsync(stream); | ||
} | ||
|
||
return tempFilePath; | ||
} | ||
} |
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,12 @@ | ||
| ||
namespace Quizer.Application.Services.Image | ||
{ | ||
public interface IImageService | ||
{ | ||
string? FormatAndMove(string filePathIn, string dirPathOut, Guid id); | ||
bool Optimize(string filePath); | ||
bool Resize(string filePath, int width, int height); | ||
string GetImageDir(string imageType); | ||
string GetImagePath(string imageType, Guid id); | ||
} | ||
} |
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,89 @@ | ||
using ImageMagick; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Quizer.Application.Services.Image; | ||
|
||
public class ImageService : IImageService | ||
{ | ||
private readonly ILogger<ImageService> _logger; | ||
private readonly ImageOptimizer _optimizer; | ||
|
||
public ImageService(ILogger<ImageService> logger) | ||
{ | ||
_optimizer = new ImageOptimizer(); | ||
_logger = logger; | ||
} | ||
|
||
public string? FormatAndMove(string filePathIn, string dirPathOut, Guid id) | ||
{ | ||
try | ||
{ | ||
string fileName = $"{id}.webp"; | ||
string filePathOut = Path.Combine(dirPathOut, fileName); | ||
|
||
using var image = new MagickImage(filePathIn); | ||
image.Format = MagickFormat.WebP; | ||
|
||
image.Write(filePathOut); | ||
|
||
return filePathOut; | ||
} | ||
catch (Exception ex) | ||
{ | ||
_logger.LogError("Error occured during image format: {@Exception}", ex); | ||
return null; | ||
} | ||
} | ||
|
||
public bool Resize(string filePath, int width, int height) | ||
{ | ||
try | ||
{ | ||
using var image = new MagickImage(filePath); | ||
image.Resize(width, height); | ||
image.Write(filePath); | ||
} | ||
catch (Exception ex) | ||
{ | ||
_logger.LogError("Error occured during image resize: {@Exception}", ex); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
public bool Optimize(string filePath) | ||
{ | ||
try | ||
{ | ||
var fileInfo = new FileInfo(filePath); | ||
_optimizer.LosslessCompress(fileInfo); | ||
} | ||
catch (Exception ex) | ||
{ | ||
_logger.LogError("Error occured during image optimize: {@Exception}", ex); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
public string GetImageDir(string imageType) | ||
{ | ||
string imageDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images", imageType); | ||
if (!Directory.Exists(imageDir)) | ||
Directory.CreateDirectory(imageDir); | ||
|
||
return imageDir; | ||
} | ||
|
||
public string GetImagePath(string imageType, Guid id) | ||
{ | ||
string imageDir = GetImageDir(imageType); | ||
string filePath = Path.Combine(imageDir, $"{id}.webp"); | ||
if (!File.Exists(filePath)) | ||
{ | ||
filePath = Path.Combine(imageDir, $"default.webp"); | ||
} | ||
|
||
return filePath; | ||
} | ||
} |
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,17 @@ | ||
using ErrorOr; | ||
|
||
namespace Quizer.Domain.Common.Errors; | ||
|
||
public static partial class Errors | ||
{ | ||
public static class Image | ||
{ | ||
public static Error CannotUpload => Error.Failure( | ||
code: "Image.CannotUpload", | ||
description: "There was an error during image upload"); | ||
|
||
public static Error WrongFormat(string[] formats) => Error.Validation( | ||
code: "Image.WrongFormat", | ||
description: $"Image has wrong format. Accepted formats: {string.Join(", ", formats)}"); | ||
} | ||
} |
Oops, something went wrong.