mirror of
https://github.com/collinbarrett/FilterLists.git
synced 2026-03-11 09:04:27 +00:00
Squashed commit of the following:
commit 5624d5049d0efa99dbb2d7c8453c0c756eb283aa
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Fri Sep 21 19:48:36 2018 -0500
move index to new endpoint for testing
ref #505
commit e49f3b6312372078f9e57a451cfae4df06145597
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Fri Sep 21 19:40:29 2018 -0500
restore camelCase
commit 94fa3c5f4ef1e47c80108c0648a5f3597d305ba7
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Fri Sep 21 19:20:38 2018 -0500
ignore nulls and empties from json
commit 5bc704ffad168ae90cbe232161d3b205d8855b07
Author: collinbarrett <collinbarrett@users.noreply.github.com>
Date: Fri Sep 21 12:40:25 2018 -0500
add maintainers
commit 68bab5bb1c3394e960ec2695c6f51f5adace1cec
Merge: 106edf5 71a3d75
Author: collinbarrett <collinbarrett@users.noreply.github.com>
Date: Fri Sep 21 10:35:43 2018 -0500
Merge branch 'master' into refactor-api
commit 106edf5b96d4d2296374ef60c8d31923316199d2
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Thu Sep 20 06:15:49 2018 -0500
wip
commit 1387ef5836165f716b59df19ca6fca5959c65ee8
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Thu Sep 20 05:54:16 2018 -0500
wip
commit fcebd19ecb583dd76112c0c4d2c1d9b1c2f0d766
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Wed Sep 19 21:11:47 2018 -0500
wip
commit e9d78450e85120a0002d5a4f528aca6992d63646
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Wed Sep 19 18:23:08 2018 -0500
wip
commit bb915dcfe605278a941e5ac0cfc50c363d744c41
Author: collinbarrett <collinbarrett@users.noreply.github.com>
Date: Wed Sep 19 15:49:12 2018 -0500
RuleCount wip
commit 8e1c0fffed9af0485dec07f33ee130d6b9ecb305
Author: collinbarrett <collinbarrett@users.noreply.github.com>
Date: Wed Sep 19 15:17:28 2018 -0500
use IReadOnlyCollection
per https://stackoverflow.com/questions/52368567/optimization-of-correlated-subqueries-with-automapper?noredirect=1#comment91770378_52368567
commit 6362d5891c728cf83bf2e3bdbb4b244c56aafdc9
Author: Collin Barrett <collinbarrett@users.noreply.github.com>
Date: Wed Sep 19 05:38:54 2018 -0500
wip
This commit is contained in:
parent
96480cf1d8
commit
96f8c014f1
8 changed files with 141 additions and 6 deletions
|
|
@ -6,6 +6,7 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using Newtonsoft.Json;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
|
||||
namespace FilterLists.Api.DependencyInjection.Extensions
|
||||
|
|
@ -32,7 +33,13 @@ private static void ConfigureCookiePolicy(this IServiceCollection services) =>
|
|||
});
|
||||
|
||||
private static void AddMvcCustom(this IServiceCollection services) =>
|
||||
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
||||
services.AddMvc()
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
|
||||
.AddJsonOptions(opts =>
|
||||
{
|
||||
opts.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||
opts.SerializerSettings.ContractResolver = new SkipEmptyContractResolver();
|
||||
});
|
||||
|
||||
private static void AddRoutingCustom(this IServiceCollection services) =>
|
||||
services.AddRouting(opts => opts.LowercaseUrls = true);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.5.1" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.4.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.4" />
|
||||
|
|
|
|||
35
src/FilterLists.Api/SkipEmptyContractResolver.cs
Normal file
35
src/FilterLists.Api/SkipEmptyContractResolver.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using Humanizer;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace FilterLists.Api
|
||||
{
|
||||
// REF: https://stackoverflow.com/a/18486790/2343739
|
||||
public class SkipEmptyContractResolver : DefaultContractResolver
|
||||
{
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
var property = base.CreateProperty(member, memberSerialization);
|
||||
property.PropertyName = property.PropertyName.Camelize();
|
||||
var isDefaultValueIgnored =
|
||||
((property.DefaultValueHandling ?? DefaultValueHandling.Ignore) & DefaultValueHandling.Ignore) != 0;
|
||||
if (!isDefaultValueIgnored || typeof(string).IsAssignableFrom(property.PropertyType) ||
|
||||
!typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
|
||||
return property;
|
||||
|
||||
bool NewShouldSerialize(object obj)
|
||||
{
|
||||
return !(property.ValueProvider.GetValue(obj) is ICollection collection) || collection.Count != 0;
|
||||
}
|
||||
|
||||
var oldShouldSerialize = property.ShouldSerialize;
|
||||
property.ShouldSerialize = oldShouldSerialize != null
|
||||
? o => oldShouldSerialize(o) && NewShouldSerialize(o)
|
||||
: (Predicate<object>)NewShouldSerialize;
|
||||
return property;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace FilterLists.Api.V1.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1")]
|
||||
//TODO: use versioning without needing to manually specify in swagger-ui (https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/370)
|
||||
[Route("v{version:apiVersion}/[controller]")]
|
||||
[ResponseCache(Duration = 86400)]
|
||||
|
|
|
|||
|
|
@ -23,9 +23,20 @@ public async Task<IActionResult> Index() =>
|
|||
return filterListService.GetAllSummariesAsync();
|
||||
}));
|
||||
|
||||
/// <summary>
|
||||
/// in development for https://github.com/collinbarrett/FilterLists/issues/505
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[Route("alpha")]
|
||||
public async Task<IActionResult> Alpha() =>
|
||||
Json(await MemoryCache.GetOrCreate("ListsController_Alpha", entry =>
|
||||
{
|
||||
entry.AbsoluteExpirationRelativeToNow = MemoryCacheExpirationDefault;
|
||||
return filterListService.GetIndexAsync();
|
||||
}));
|
||||
|
||||
[HttpGet]
|
||||
[Route("{id}")]
|
||||
//TODO: respond with appropriate exception if negative id queried
|
||||
public async Task<IActionResult> GetById(int id) =>
|
||||
Json(await MemoryCache.GetOrCreate("ListsController_GetById_" + id, entry =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@
|
|||
using AutoMapper.QueryableExtensions;
|
||||
using FilterLists.Data;
|
||||
using FilterLists.Services.FilterList.Models;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace FilterLists.Services.FilterList
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class FilterListService : Service
|
||||
{
|
||||
public FilterListService(FilterListsDbContext dbContext, IConfigurationProvider mapConfig)
|
||||
|
|
@ -19,7 +17,16 @@ public FilterListService(FilterListsDbContext dbContext, IConfigurationProvider
|
|||
}
|
||||
|
||||
public async Task<IEnumerable<ListSummaryDto>> GetAllSummariesAsync() =>
|
||||
await DbContext.FilterLists.OrderBy(l => l.Name).ProjectTo<ListSummaryDto>(MapConfig).ToListAsync();
|
||||
await DbContext.FilterLists
|
||||
.OrderBy(l => l.Name)
|
||||
.ProjectTo<ListSummaryDto>(MapConfig)
|
||||
.ToListAsync();
|
||||
|
||||
public async Task<IEnumerable<ListIndexRecord>> GetIndexAsync() =>
|
||||
await DbContext.FilterLists
|
||||
.OrderBy(l => l.Name)
|
||||
.ProjectTo<ListIndexRecord>(MapConfig)
|
||||
.ToListAsync();
|
||||
|
||||
public async Task<ListDetailsDto> GetDetailsAsync(uint id) =>
|
||||
await DbContext.FilterLists.ProjectTo<ListDetailsDto>(MapConfig)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using FilterLists.Services.FilterList.Models;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace FilterLists.Services.FilterList.MappingProfiles
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class ListIndexRecordMappingProfile : Profile
|
||||
{
|
||||
public ListIndexRecordMappingProfile() =>
|
||||
CreateMap<Data.Entities.FilterList, ListIndexRecord>()
|
||||
.ForMember(r => r.Id,
|
||||
o => o.MapFrom(l =>
|
||||
(int)l.Id))
|
||||
.ForMember(r => r.LanguageIds,
|
||||
o => o.MapFrom(l =>
|
||||
l.FilterListLanguages.Select(ll => (int)ll.LanguageId)))
|
||||
.ForMember(r => r.MaintainerIds,
|
||||
o => o.MapFrom(l =>
|
||||
l.FilterListMaintainers.Select(ll => (int)ll.MaintainerId)))
|
||||
.ForMember(r => r.RuleCount,
|
||||
o => o.MapFrom(l =>
|
||||
l.Snapshots
|
||||
.Where(s => s.WasSuccessful)
|
||||
.Select(s => (int?)s.SnapshotRules.Count)
|
||||
.FirstOrDefault()))
|
||||
.ForMember(r => r.SyntaxId,
|
||||
o => o.MapFrom(l =>
|
||||
(int)l.SyntaxId))
|
||||
.ForMember(r => r.TagIds,
|
||||
o => o.MapFrom(l =>
|
||||
l.FilterListTags.Select(lt => (int)lt.TagId)))
|
||||
.ForMember(r => r.UpdatedDate,
|
||||
o => o.MapFrom(l =>
|
||||
l.Snapshots
|
||||
.Count(s => s.WasSuccessful && s.WasUpdated) >= 2
|
||||
? l.Snapshots
|
||||
.Where(s => s.WasSuccessful && s.WasUpdated)
|
||||
.Select(s => s.CreatedDateUtc)
|
||||
.OrderByDescending(c => c)
|
||||
.FirstOrDefault()
|
||||
: null))
|
||||
.ForMember(r => r.ViewUrlMirrors,
|
||||
o => o.MapFrom(l =>
|
||||
l.ViewUrlMirror1 != null
|
||||
? l.ViewUrlMirror2 != null
|
||||
? new List<string> {l.ViewUrlMirror1, l.ViewUrlMirror2}
|
||||
: new List<string> {l.ViewUrlMirror1}
|
||||
: null));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace FilterLists.Services.FilterList.Models
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class ListIndexRecord
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public List<int> LanguageIds { get; set; }
|
||||
public List<int> MaintainerIds { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int? RuleCount { get; set; }
|
||||
public int? SyntaxId { get; set; }
|
||||
public List<int> TagIds { get; set; }
|
||||
public DateTime? UpdatedDate { get; set; }
|
||||
public string ViewUrl { get; set; }
|
||||
public List<string> ViewUrlMirrors { get; set; }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue