411 lines
18 KiB
C#
411 lines
18 KiB
C#
using AutoMapper;
|
|
using gehGassi.Core.Interfaces;
|
|
using gehGassi.Core.Services;
|
|
using gehGassi.Dto.News;
|
|
using gehGassi.Dto;
|
|
using gehGassi.Web.Helper;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using System;
|
|
using gehGassi.Dto.Dogs;
|
|
using gehGassi.Dto.Common;
|
|
using gehGassi.Dto.Messages;
|
|
using NuGet.Protocol.Plugins;
|
|
using Microsoft.AspNetCore.Http;
|
|
using System.IO;
|
|
using gehGassi.Domain.Dogs;
|
|
using gehGassi.Web.Auth;
|
|
using SixLabors.ImageSharp;
|
|
using SixLabors.ImageSharp.Advanced;
|
|
using SixLabors.ImageSharp.Processing;
|
|
using gehGassi.Web.Models;
|
|
using Asp.Versioning;
|
|
|
|
namespace gehGassi.Web.Controllers.Api
|
|
{
|
|
/// <summary>
|
|
/// Controller der Zugriff auf Hunde und Hunderassen via API ermöglicht
|
|
/// </summary>
|
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
|
[ApiController]
|
|
[ApiVersion(1)]
|
|
[Route("api/dogs")]
|
|
[Route("api/v{v:apiVersion}/dogs")]
|
|
public class ApiDogsController : ApiBaseController
|
|
{
|
|
private readonly ILogger<ApiDogsController> _logger;
|
|
private readonly IDogRaceService _dogRaceService;
|
|
private readonly IDogService _dogService;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="mapper">Instanz eines IMapper</param>
|
|
/// <param name="logger">Instanz eines ILogger</param>
|
|
/// <param name="localizationOptions">Instanz von LocalizationOptions</param>
|
|
/// <param name="appUserService">Instanz eines IAppUserService</param>
|
|
/// <param name="dogRaceService">Instanz eines IDogRaceService</param>
|
|
/// <param name="dogService">Instanz eines IDogService</param>
|
|
public ApiDogsController(IMapper mapper, ILogger<ApiDogsController> logger, IOptions<LocalizationOptions> localizationOptions, IAppUserService appUserService, IDogRaceService dogRaceService,
|
|
IDogService dogService) : base(mapper, localizationOptions, appUserService)
|
|
{
|
|
_logger = logger;
|
|
_dogRaceService = dogRaceService;
|
|
_dogService = dogService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von Hunderassen für die Synchronisierung mit der App zurück
|
|
/// </summary>
|
|
/// <param name="lastUpdate">Letztes Update oder null, wenn noch keines</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <returns>HTTP 200 wenn erfolgreich</returns>
|
|
[Route("GetRaces")]
|
|
[HttpGet]
|
|
public async Task<IActionResult> GetRaces(DateTimeOffset? lastUpdate, string language)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var races = await _dogRaceService.GetForSyncAsync(lastUpdate, language, LocalizationOptions.Value.DefaultCulture);
|
|
var racesDto = Mapper.Map<List<DogRaceDto>>(races);
|
|
|
|
return Ok(racesDto);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine eine Hunderassen zurück
|
|
/// </summary>
|
|
/// <param name="id">Id der hunderasse</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <returns>HTTP 200 wenn erfolgreich</returns>
|
|
[Route("GetRace")]
|
|
[HttpGet]
|
|
public async Task<IActionResult> GetRace(string id, string language)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var race = await _dogRaceService.GetWithNamesAsync(id, language, LocalizationOptions.Value.DefaultCulture);
|
|
var raceDto = Mapper.Map<DogRaceDto>(race);
|
|
|
|
return Ok(raceDto);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Abfrage der Hunde eines AppUsers
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des AppUsers</param>
|
|
/// <param name="lastUpdate">Letztes Update oder null, wenn noch keines</param>
|
|
/// <returns>Liste der Hunde</returns>
|
|
[HttpGet]
|
|
[Route("GetDogs")]
|
|
public async Task<IActionResult> GetDogs(string appUserId, DateTimeOffset? lastUpdate)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var dogs = await _dogService.GetDogsAsync(appUserId, lastUpdate);
|
|
var dogsDtoList = Mapper.Map<List<DogDto>>(dogs);
|
|
var baseAddress = GetBaseAddress();
|
|
foreach (var item in dogsDtoList)
|
|
{
|
|
item.Photo = !string.IsNullOrWhiteSpace(item.Photo) ? $"{baseAddress}/file/documents/thumbnails/{400}/{item.Photo}" : "";
|
|
}
|
|
|
|
return Ok(dogsDtoList);
|
|
}
|
|
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Abfrage der Hunde eines AppUsers als DogMinInfo
|
|
/// </summary>
|
|
/// <param name="dogOwnerId">Id des Hundebesitzers</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <returns>Liste der Hunde als MinInfo</returns>
|
|
[HttpGet]
|
|
[Route("GetDogsMin")]
|
|
public async Task<IActionResult> GetDogsMin(string dogOwnerId, string language)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var appUserId = User.AppUserId();
|
|
var locked = await AppUserService.IsLockedAsync(dogOwnerId);
|
|
var blocked = await AppUserService.IsBlockedAsync(appUserId, dogOwnerId);
|
|
|
|
var dogs = await _dogService.GetWithNamesOwnerAsync(dogOwnerId, language, LocalizationOptions.Value.DefaultCulture);
|
|
var dogsDtoList = Mapper.Map<List<DogMinInfoDto>>(dogs);
|
|
var baseAddress = GetBaseAddress();
|
|
foreach (var item in dogsDtoList)
|
|
{
|
|
item.Photo = !string.IsNullOrWhiteSpace(item.Photo) ? $"{baseAddress}/file/documents/thumbnails/{200}/{item.Photo}" : "";
|
|
item.Locked = locked;
|
|
item.Blocked = blocked;
|
|
}
|
|
|
|
return Ok(dogsDtoList);
|
|
}
|
|
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt einen hund zurück
|
|
/// </summary>
|
|
/// <param name="dogId">Id des Hundes</param>
|
|
/// <returns>Hunde</returns>
|
|
[HttpGet]
|
|
[Route("GetDog")]
|
|
public async Task<IActionResult> GetDog(string dogId)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var dog = await _dogService.GetAsync(dogId);
|
|
var dogDto = Mapper.Map<DogDto>(dog);
|
|
var baseAddress = GetBaseAddress();
|
|
dogDto.Photo = !string.IsNullOrWhiteSpace(dogDto.Photo) ? $"{baseAddress}/file/documents/thumbnails/{400}/{dogDto.Photo}" : "";
|
|
|
|
var appUserId = User.AppUserId();
|
|
dogDto.Locked = await AppUserService.IsLockedAsync(dog.AppUserId);
|
|
dogDto.Blocked = await AppUserService.IsBlockedAsync(appUserId, dog.AppUserId);
|
|
|
|
return Ok(dogDto);
|
|
}
|
|
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Anlegen eines Hundes
|
|
/// </summary>
|
|
/// <param name="model">DogDto</param>
|
|
/// <param name="photoUpdateFile">Optional Foto</param>
|
|
/// <returns>CreateResponseDto</returns>
|
|
[HttpPost]
|
|
[Route("Add")]
|
|
public async Task<IActionResult> Add([ModelBinder(BinderType = typeof(JsonModelBinder))] DogDto model, IFormFile photoUpdateFile)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
var result = new CreateResponseDto<DogDto>
|
|
{
|
|
Status = CreateStatusDto.Error,
|
|
Value = null
|
|
};
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var dog = await _dogService.GetAsync(model.Id);
|
|
if (dog == null)
|
|
{
|
|
dog = _dogService.Create();
|
|
|
|
Mapper.Map(model, dog);
|
|
dog.Id = model.Id; //Da die Id schon in der App generiert wurde
|
|
if (model.BirthDate.HasValue)
|
|
dog.BirthDate = new DateTimeOffset(model.BirthDate.Value.DateTime, TimeSpan.Zero);
|
|
dog.Number = await _dogService.GetNextNumberAsync();
|
|
|
|
try
|
|
{
|
|
if (photoUpdateFile != null && !string.IsNullOrEmpty(photoUpdateFile.FileName))
|
|
{
|
|
var extension = Path.GetExtension(photoUpdateFile.FileName);
|
|
var filenameToUse = FileServiceHelper.GetDogPath(dog.Id) + $"dog_{Guid.NewGuid():N}{extension}";
|
|
|
|
using var memoryStream = new MemoryStream();
|
|
|
|
await photoUpdateFile.CopyToAsync(memoryStream);
|
|
memoryStream.Position = 0;
|
|
|
|
using var img = await Image.LoadAsync(memoryStream);
|
|
|
|
img.Mutate(x => x.Resize(new ResizeOptions() { Mode = ResizeMode.Crop, Size = new Size(800) }));
|
|
var format = img.DetectEncoder(photoUpdateFile.FileName);
|
|
|
|
await using var memStream = new MemoryStream();
|
|
await img.SaveAsync(memStream, format);
|
|
memStream.Position = 0;
|
|
await FileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, memStream);
|
|
dog.Photo = filenameToUse;
|
|
|
|
//Thumbnails erstellten
|
|
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 400);
|
|
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 200);
|
|
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 100);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
|
|
_dogService.Add(dog);
|
|
await _dogService.CommitAsync(User.Identity.Name);
|
|
|
|
var dtoDog = Mapper.Map<DogDto>(dog);
|
|
|
|
result.Status = CreateStatusDto.Success;
|
|
result.Value = dtoDog;
|
|
|
|
return Ok(result);
|
|
}
|
|
|
|
result.Status = CreateStatusDto.Exists;
|
|
return Ok(result);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aktualisieren eines Hundes
|
|
/// </summary>
|
|
/// <param name="model">DogDto</param>
|
|
/// <param name="photoUpdateFile">Optional Foto</param>
|
|
/// <returns>200OK</returns>
|
|
[HttpPost]
|
|
[Route("Update")]
|
|
public async Task<IActionResult> Update([ModelBinder(BinderType = typeof(JsonModelBinder))] DogDto model, IFormFile photoUpdateFile)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var dog = await _dogService.GetAsync(model.Id);
|
|
if (dog != null)
|
|
{
|
|
if (model.UpdatedAt > dog.UpdatedAt)
|
|
{
|
|
var oldPhoto = dog.Photo;
|
|
Mapper.Map(model, dog);
|
|
|
|
if (string.IsNullOrWhiteSpace(model.Photo) || model.Photo.StartsWithHttp())
|
|
{
|
|
//Altes Foto behalten wenn eines als Link kommt
|
|
dog.Photo = oldPhoto;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (photoUpdateFile != null && !string.IsNullOrEmpty(photoUpdateFile.FileName))
|
|
{
|
|
//Wenn es ein altes Foto gibt, dieses löschen
|
|
if (!string.IsNullOrWhiteSpace(oldPhoto))
|
|
{
|
|
await FileService.DeleteAsync(FileServiceHelper.DocumentContainer, oldPhoto);
|
|
await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 400);
|
|
await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 200);
|
|
await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 100);
|
|
}
|
|
|
|
var extension = Path.GetExtension(photoUpdateFile.FileName);
|
|
var filenameToUse = FileServiceHelper.GetDogPath(dog.Id) + $"dog_{Guid.NewGuid():N}{extension}";
|
|
|
|
using var memoryStream = new MemoryStream();
|
|
|
|
await photoUpdateFile.CopyToAsync(memoryStream);
|
|
memoryStream.Position = 0;
|
|
|
|
using var img = await Image.LoadAsync(memoryStream);
|
|
|
|
img.Mutate(x => x.Resize(new ResizeOptions() { Mode = ResizeMode.Crop, Size = new Size(800) }));
|
|
var format = img.DetectEncoder(photoUpdateFile.FileName);
|
|
|
|
await using var memStream = new MemoryStream();
|
|
await img.SaveAsync(memStream, format);
|
|
memStream.Position = 0;
|
|
await FileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, memStream);
|
|
dog.Photo = filenameToUse;
|
|
|
|
//Thumbnails erstellten
|
|
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 400);
|
|
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 200);
|
|
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 100);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
|
|
await _dogService.CommitAsync(User.Identity.Name);
|
|
}
|
|
|
|
return Ok();
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Löschen eines Hundes
|
|
/// </summary>
|
|
/// <param name="model">DogDto</param>
|
|
/// <param name="appUserId">Id des App-Users</param>
|
|
/// <returns>200OK</returns>
|
|
[HttpPost]
|
|
[Route("Delete")]
|
|
public async Task<IActionResult> Delete([ModelBinder(BinderType = typeof(JsonModelBinder))] DogDto model, [FromQuery]string appUserId)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var dog = await _dogService.GetAsync(model.Id);
|
|
if (dog != null)
|
|
{
|
|
var appUser = await AppUserService.GetAsync(appUserId);
|
|
if (appUser != null)
|
|
{
|
|
if (dog.AppUserId == appUser.Id)
|
|
{
|
|
var postingPath = FileServiceHelper.GetDogPath(dog.Id);
|
|
await FileService.ClearDirectoryAsync(FileServiceHelper.DocumentContainer, postingPath);
|
|
await RemoveThumbnail(FileServiceHelper.DocumentContainer, dog.Photo, 400);
|
|
await RemoveThumbnail(FileServiceHelper.DocumentContainer, dog.Photo, 200);
|
|
await RemoveThumbnail(FileServiceHelper.DocumentContainer, dog.Photo, 100);
|
|
|
|
_dogService.Remove(dog);
|
|
await _dogService.CommitAsync(User.Identity.Name);
|
|
return Ok();
|
|
}
|
|
}
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
}
|
|
}
|