using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Asp.Versioning; using AutoMapper; using gehGassi.Common.Data; using gehGassi.Core.Interfaces; using gehGassi.Domain.Common; using gehGassi.Domain.News; using gehGassi.Dto; using gehGassi.Dto.Common; using gehGassi.Dto.News; using gehGassi.Web.Auth; using gehGassi.Web.Helper; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.TagHelpers.Cache; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NuGet.Protocol; using NuGet.Protocol.Plugins; namespace gehGassi.Web.Controllers.Api { /// /// Controller der Zugriff auf News via API ermöglicht /// [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [ApiController] [ApiVersion(1)] [Route("api/news")] [Route("api/v{v:apiVersion}/news")] public class ApiNewsController : ApiBaseController { private readonly ILogger _logger; private readonly INewsCategoryService _newsCategoryService; private readonly INewsService _newsService; private readonly IGeoLocationService _geoLocationService; /// /// Erstellt eine Instanz /// /// Instanz eines IMapper /// Instanz eines ILogger /// Instanz von LocalizationOptions /// Instanz eines INewsCategoryService /// Instanz eines INewsService /// Instanz eines IDogOwnerService /// Instanz eines IGeoLocationService public ApiNewsController(IMapper mapper, ILogger logger, IOptions localizationOptions, INewsCategoryService newsCategoryService, INewsService newsService, IAppUserService appUserService, IGeoLocationService geoLocationService) : base(mapper, localizationOptions, appUserService) { _logger = logger; _newsCategoryService = newsCategoryService; _newsService = newsService; _geoLocationService = geoLocationService; } /// /// Gibt eine Liste von News-Kategorien für die Synchronisierung mit der App zurück /// /// Letztes Update oder null, wenn noch keines /// Gewünschte Sprache /// HTTP 200 wenn erfolgreich [Route("GetCategories")] [HttpGet] public async Task GetCategories(DateTimeOffset? lastUpdate, string language) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var categories = await _newsCategoryService.GetForSyncAsync(lastUpdate, language, LocalizationOptions.Value.DefaultCulture); var categoriesDto = Mapper.Map>(categories); foreach (var newsCategoryDto in categoriesDto) { newsCategoryDto.Language = language; } return Ok(categoriesDto); } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Gibt eine Liste von News-Meldungen zurück /// /// Abfragemodel /// HTTP 200 wenn erfolgreich [Route("GetNews")] [HttpPost] public async Task GetNews(NewsQueryDto model) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var response = new ListResponseDto(); //Geodaten holen. //Entweder wurde lat und lng geliefert, oder wir müssen über den benutzer und den app-mode entscheiden var (country, state) = await GetGeoDataAsync(model); //Wir müssen nach Geomode der News vorgehen. Zuerst alle ohne Geo-Beschränkung, dann jene mit Land, dann jene mit Land und Bundesland und dann jene mit Lat & Lng var visibility = model.AppMode == AppModeDto.DogOwner ? NewsVisibility.DogOwners : NewsVisibility.DogWalkers; var queryResult = await _newsService.GetForAppAsync(visibility, model.CategoryId, country, state, model.Location.Lat, model.Location.Lng, model.Language, LocalizationOptions.Value.DefaultCulture, model.Skip, model.Take); response.Total = queryResult.total; var dtoList = Mapper.Map>(queryResult.list); var baseAddress = GetBaseAddress(); foreach (var newsDto in dtoList) { newsDto.Headline = newsDto.Headline.Ellipsis(97); if (!string.IsNullOrWhiteSpace(newsDto.Image)) newsDto.Image = $"{baseAddress}/file/documents/thumbnails/{200}/{newsDto.Image}"; newsDto.Url = $"{baseAddress}/{LocalizationOptions.Value.DefaultCulture}/News/show?nid={newsDto.Id}"; } response.List = dtoList; response.Take = model.Take; response.Skip = model.Skip; return Ok(response); } return NotFound(CommunicationErrors.Common_NotFound); } } }