tidying up some syntax

This commit is contained in:
Collin Barrett 2018-06-05 19:44:05 -05:00
parent 15c5ddb32f
commit 55e19b1589
50 changed files with 278 additions and 289 deletions

View file

@ -1,12 +1,16 @@
using Microsoft.AspNetCore.Mvc;
using FilterLists.Services.Seed;
using Microsoft.AspNetCore.Mvc;
namespace FilterLists.Api.V1.Controllers
{
[ApiVersion("1.0")]
public class BaseController : Controller
{
protected BaseController()
protected readonly SeedService SeedService;
protected BaseController(SeedService seedService)
{
SeedService = seedService;
}
}
}

View file

@ -8,19 +8,12 @@ namespace FilterLists.Api.V1.Controllers
{
public class ForksController : BaseController
{
private readonly SeedService seedService;
public ForksController(SeedService seedService)
public ForksController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<Fork, ForkSeedDto>(
typeof(Fork).GetProperty("UpstreamFilterListId"),
typeof(Fork).GetProperty("ForkFilterListId")));
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<Fork, ForkSeedDto>(
typeof(Fork).GetProperty("UpstreamFilterListId"), typeof(Fork).GetProperty("ForkFilterListId")));
}
}

View file

@ -8,17 +8,11 @@ namespace FilterLists.Api.V1.Controllers
{
public class LanguagesController : BaseController
{
private readonly SeedService seedService;
public LanguagesController(SeedService seedService)
public LanguagesController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<Language, LanguageSeedDto>());
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<Language, LanguageSeedDto>());
}
}

View file

@ -8,17 +8,11 @@ namespace FilterLists.Api.V1.Controllers
{
public class LicensesController : BaseController
{
private readonly SeedService seedService;
public LicensesController(SeedService seedService)
public LicensesController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<License, LicenseSeedDto>());
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<License, LicenseSeedDto>());
}
}

View file

@ -9,31 +9,20 @@ namespace FilterLists.Api.V1.Controllers
{
public class ListsController : BaseController
{
private readonly FilterListService filterListService;
private readonly SeedService seedService;
private readonly FilterListService _filterListService;
public ListsController(SeedService seedService, FilterListService filterListService)
public ListsController(SeedService seedService, FilterListService filterListService) : base(seedService)
{
this.seedService = seedService;
this.filterListService = filterListService;
_filterListService = filterListService;
}
[HttpGet]
public async Task<IActionResult> Index()
{
return Json(await filterListService.GetAllSummariesAsync());
}
public async Task<IActionResult> Index() => Json(await _filterListService.GetAllSummariesAsync());
[HttpGet]
public async Task<IActionResult> GetById(int id)
{
return Json(await filterListService.GetDetailsAsync(id));
}
public async Task<IActionResult> GetById(int id) => Json(await _filterListService.GetDetailsAsync(id));
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<FilterList, FilterListSeedDto>());
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<FilterList, FilterListSeedDto>());
}
}

View file

@ -8,19 +8,14 @@ namespace FilterLists.Api.V1.Controllers
{
public class ListsLanguagesController : BaseController
{
private readonly SeedService seedService;
public ListsLanguagesController(SeedService seedService)
public ListsLanguagesController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<FilterListLanguage, FilterListLanguageSeedDto>(
public async Task<IActionResult> Seed() =>
Json(await SeedService.GetAllAsync<FilterListLanguage, FilterListLanguageSeedDto>(
typeof(FilterListLanguage).GetProperty("FilterListId"),
typeof(FilterListLanguage).GetProperty("LanguageId")));
}
}
}

View file

@ -8,19 +8,14 @@ namespace FilterLists.Api.V1.Controllers
{
public class ListsMaintainersController : BaseController
{
private readonly SeedService seedService;
public ListsMaintainersController(SeedService seedService)
public ListsMaintainersController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<FilterListMaintainer, FilterListMaintainerSeedDto>(
public async Task<IActionResult> Seed() => Json(
await SeedService.GetAllAsync<FilterListMaintainer, FilterListMaintainerSeedDto>(
typeof(FilterListMaintainer).GetProperty("MaintainerId"),
typeof(FilterListMaintainer).GetProperty("FilterListId")));
}
}
}

View file

@ -8,17 +8,11 @@ namespace FilterLists.Api.V1.Controllers
{
public class MaintainersController : BaseController
{
private readonly SeedService seedService;
public MaintainersController(SeedService seedService)
public MaintainersController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<Maintainer, MaintainerSeedDto>());
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<Maintainer, MaintainerSeedDto>());
}
}

View file

@ -8,19 +8,12 @@ namespace FilterLists.Api.V1.Controllers
{
public class MergesController : BaseController
{
private readonly SeedService seedService;
public MergesController(SeedService seedService)
public MergesController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<Merge, MergeSeedDto>(
typeof(Merge).GetProperty("MergeFilterListId"),
typeof(Merge).GetProperty("UpstreamFilterListId")));
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<Merge, MergeSeedDto>(
typeof(Merge).GetProperty("MergeFilterListId"), typeof(Merge).GetProperty("UpstreamFilterListId")));
}
}

View file

@ -8,17 +8,11 @@ namespace FilterLists.Api.V1.Controllers
{
public class SoftwareController : BaseController
{
private readonly SeedService seedService;
public SoftwareController(SeedService seedService)
public SoftwareController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<Software, SoftwareSeedDto>());
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<Software, SoftwareSeedDto>());
}
}

View file

@ -8,19 +8,13 @@ namespace FilterLists.Api.V1.Controllers
{
public class SoftwareSyntaxesController : BaseController
{
private readonly SeedService seedService;
public SoftwareSyntaxesController(SeedService seedService)
public SoftwareSyntaxesController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<SoftwareSyntax, SoftwareSyntaxSeedDto>(
typeof(SoftwareSyntax).GetProperty("SyntaxId"),
typeof(SoftwareSyntax).GetProperty("SoftwareId")));
}
public async Task<IActionResult> Seed() =>
Json(await SeedService.GetAllAsync<SoftwareSyntax, SoftwareSyntaxSeedDto>(
typeof(SoftwareSyntax).GetProperty("SyntaxId"), typeof(SoftwareSyntax).GetProperty("SoftwareId")));
}
}

View file

@ -8,17 +8,11 @@ namespace FilterLists.Api.V1.Controllers
{
public class SyntaxesController : BaseController
{
private readonly SeedService seedService;
public SyntaxesController(SeedService seedService)
public SyntaxesController(SeedService seedService) : base(seedService)
{
this.seedService = seedService;
}
[HttpGet]
public async Task<IActionResult> Seed()
{
return Json(await seedService.GetAllAsync<Syntax, SyntaxSeedDto>());
}
public async Task<IActionResult> Seed() => Json(await SeedService.GetAllAsync<Syntax, SyntaxSeedDto>());
}
}

View file

@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using FilterLists.Data.Entities.Junctions;
using JetBrains.Annotations;
namespace FilterLists.Data.Entities
{
[UsedImplicitly]
public class FilterList : BaseEntity
{
public string ChatUrl { get; set; }

View file

@ -1,8 +1,10 @@
using System.Collections.Generic;
using FilterLists.Data.Entities.Junctions;
using JetBrains.Annotations;
namespace FilterLists.Data.Entities
{
[UsedImplicitly]
public class Language : BaseEntity
{
public ICollection<FilterListLanguage> FilterListLanguages { get; set; }

View file

@ -1,7 +1,9 @@
using System.Collections.Generic;
using JetBrains.Annotations;
namespace FilterLists.Data.Entities
{
[UsedImplicitly]
public class License : BaseEntity
{
public string DescriptionUrl { get; set; }

View file

@ -1,8 +1,10 @@
using System.Collections.Generic;
using FilterLists.Data.Entities.Junctions;
using JetBrains.Annotations;
namespace FilterLists.Data.Entities
{
[UsedImplicitly]
public class Maintainer : BaseEntity
{
public string EmailAddress { get; set; }

View file

@ -1,8 +1,10 @@
using System.Collections.Generic;
using FilterLists.Data.Entities.Junctions;
using JetBrains.Annotations;
namespace FilterLists.Data.Entities
{
[UsedImplicitly]
public class Software : BaseEntity
{
public string DownloadUrl { get; set; }

View file

@ -1,8 +1,10 @@
using System.Collections.Generic;
using FilterLists.Data.Entities.Junctions;
using JetBrains.Annotations;
namespace FilterLists.Data.Entities
{
[UsedImplicitly]
public class Syntax : BaseEntity
{
public string DefinitionUrl { get; set; }

View file

@ -6,6 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="11.1.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.3.0" />
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.0" />

View file

@ -46,13 +46,7 @@ private static List<IProperty> GetPropertiesLessValueGeneratedTimestamps(IEntity
{
//TODO: get seed properties dynamically from JSON
return entityType.GetProperties()
.Where(x =>
!new List<string>
{
"CreatedDateUtc",
"ModifiedDateUtc"
}
.Contains(x.Name))
.Where(x => !new List<string> {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name))
.ToList();
}
@ -60,8 +54,7 @@ private static string CreateValues<TEntityType>(IReadOnlyCollection<IProperty> p
{
return GetSeedRows<TEntityType>(dataPath)
.Select(row => CreateRowValues(properties, row))
.Aggregate("",
(current, rowValues) => current == "" ? rowValues : current + ", " + rowValues);
.Aggregate("", (current, rowValues) => current == "" ? rowValues : current + ", " + rowValues);
}
private static List<TEntityType> GetSeedRows<TEntityType>(string dataPath)
@ -81,7 +74,7 @@ private static List<TEntityType> GetSeedRows<TEntityType>(string dataPath)
private static string CreateRowValues<TEntityType>(IEnumerable<IProperty> properties, TEntityType row)
{
return (from property in properties
let value = row.GetType().GetProperty(property.Name).GetValue(row)
let value = row.GetType().GetProperty(property.Name)?.GetValue(row)
select FormatDataForMySql(property, value)).Aggregate("",
(rowValues, value) => rowValues == "" ? "(" + value : rowValues + ", " + value) + ")";
}
@ -94,7 +87,7 @@ private static object FormatDataForMySql(IProperty property, object value)
if (property.ClrType == typeof(bool))
return Convert.ToInt32(value);
if (property.ClrType == typeof(DateTime?))
return "'" + ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss") + "'";
return "'" + ((DateTime) value).ToString("yyyy-MM-dd HH:mm:ss") + "'";
return value;
}

View file

@ -1,5 +1,8 @@
using AutoMapper;
using FilterLists.Data;
using FilterLists.Services.FilterList;
using FilterLists.Services.Seed;
using FilterLists.Services.Snapshot;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@ -17,9 +20,9 @@ public static void AddFilterListsServices(this IServiceCollection services, ICon
options.UseMySql(configuration.GetConnectionString("FilterListsConnection"),
b => b.MigrationsAssembly("FilterLists.Api"))
.EnableSensitiveDataLogging());
services.TryAddScoped<FilterList.FilterListService>();
services.TryAddScoped<Seed.SeedService>();
services.TryAddScoped<Snapshot.SnapshotService>();
services.TryAddScoped<FilterListService>();
services.TryAddScoped<SeedService>();
services.TryAddScoped<SnapshotService>();
services.AddAutoMapper();
}
}

View file

@ -3,35 +3,35 @@
using System.Threading.Tasks;
using AutoMapper.QueryableExtensions;
using FilterLists.Data;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class FilterListService
{
private readonly FilterListsDbContext filterListsDbContext;
private readonly FilterListsDbContext _filterListsDbContext;
public FilterListService(FilterListsDbContext filterListsDbContext)
{
this.filterListsDbContext = filterListsDbContext;
_filterListsDbContext = filterListsDbContext;
}
public async Task<IEnumerable<ListSummaryDto>> GetAllSummariesAsync()
{
return await filterListsDbContext.FilterLists
.AsNoTracking()
.OrderBy(x => x.Name)
.ProjectTo<ListSummaryDto>()
.ToListAsync();
return await _filterListsDbContext.FilterLists.AsNoTracking()
.OrderBy(x => x.Name)
.ProjectTo<ListSummaryDto>()
.ToListAsync();
}
public async Task<ListDetailsDto> GetDetailsAsync(int id)
{
return await filterListsDbContext.FilterLists
.AsNoTracking()
.ProjectTo<ListDetailsDto>()
.FirstAsync(x => x.Id == id)
.FilterParentListFromMaintainerAdditionalLists();
return await _filterListsDbContext.FilterLists.AsNoTracking()
.ProjectTo<ListDetailsDto>()
.FirstAsync(x => x.Id == id)
.FilterParentListFromMaintainerAdditionalLists();
}
}
}

View file

@ -9,10 +9,10 @@ public static async Task<ListDetailsDto> FilterParentListFromMaintainerAdditiona
this Task<ListDetailsDto> listDetailsDtos)
{
foreach (var maintainer in listDetailsDtos.Result.Maintainers)
maintainer.AdditionalLists = maintainer.AdditionalLists
.Where(additionalList =>
additionalList.Id != listDetailsDtos.Result.Id)
.ToList();
maintainer.AdditionalLists = maintainer
.AdditionalLists.Where(additionalList =>
additionalList.Id != listDetailsDtos.Result.Id)
.ToList();
return await listDetailsDtos;
}
}

View file

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class ListDetailsDto
{
public int Id { get; set; }
@ -25,39 +27,4 @@ public class ListDetailsDto
public ListSyntaxDto Syntax { get; set; }
public string ViewUrl { get; set; }
}
public class ListMaintainerDto
{
public int Id { get; set; }
public string EmailAddress { get; set; }
public string HomeUrl { get; set; }
public string Name { get; set; }
public string TwitterHandle { get; set; }
public IEnumerable<MaintainerAdditionalListsDto> AdditionalLists { get; set; }
}
public class MaintainerAdditionalListsDto
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ListLicenseDto
{
public string DescriptionUrl { get; set; }
public string Name { get; set; }
}
public class ListSyntaxDto
{
public string DefinitionUrl { get; set; }
public string Name { get; set; }
public IEnumerable<SyntaxSupportedSoftwareDto> SupportedSoftware { get; set; }
}
public class SyntaxSupportedSoftwareDto
{
public string HomeUrl { get; set; }
public string Name { get; set; }
}
}

View file

@ -0,0 +1,11 @@
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class ListLanguagesDto
{
public string Name { get; set; }
public string Iso6391 { get; set; }
}
}

View file

@ -0,0 +1,11 @@
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class ListLicenseDto
{
public string DescriptionUrl { get; set; }
public string Name { get; set; }
}
}

View file

@ -0,0 +1,16 @@
using System.Collections.Generic;
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class ListMaintainerDto
{
public int Id { get; set; }
public string EmailAddress { get; set; }
public string HomeUrl { get; set; }
public string Name { get; set; }
public string TwitterHandle { get; set; }
public IEnumerable<MaintainerAdditionalListsDto> AdditionalLists { get; set; }
}
}

View file

@ -1,7 +1,9 @@
using System.Collections.Generic;
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class ListSummaryDto
{
public int Id { get; set; }
@ -9,10 +11,4 @@ public class ListSummaryDto
public string Name { get; set; }
public string ViewUrl { get; set; }
}
public class ListLanguagesDto
{
public string Name { get; set; }
public string Iso6391 { get; set; }
}
}

View file

@ -0,0 +1,13 @@
using System.Collections.Generic;
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class ListSyntaxDto
{
public string DefinitionUrl { get; set; }
public string Name { get; set; }
public IEnumerable<SyntaxSupportedSoftwareDto> SupportedSoftware { get; set; }
}
}

View file

@ -0,0 +1,11 @@
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class MaintainerAdditionalListsDto
{
public int Id { get; set; }
public string Name { get; set; }
}
}

View file

@ -10,26 +10,20 @@ public MappingProfiles()
{
CreateMap<Data.Entities.FilterList, ListSummaryDto>()
.ForMember(dto => dto.Languages,
conf => conf.MapFrom(list =>
list.FilterListLanguages.Select(listLangs => listLangs.Language)));
conf => conf.MapFrom(list => list.FilterListLanguages.Select(listLangs => listLangs.Language)));
CreateMap<Data.Entities.FilterList, ListDetailsDto>()
.ForMember(dto => dto.Languages,
conf => conf.MapFrom(list =>
list.FilterListLanguages.Select(listLangs => listLangs.Language.Name)))
conf => conf.MapFrom(list => list.FilterListLanguages.Select(listLangs => listLangs.Language.Name)))
.ForMember(dto => dto.Maintainers,
conf => conf.MapFrom(list =>
list.FilterListMaintainers.Select(listMaints => listMaints.Maintainer)));
CreateMap<Maintainer, ListMaintainerDto>()
.ForMember(dto => dto.AdditionalLists,
conf => conf.MapFrom(maint =>
maint.FilterListMaintainers.Select(listMaints => listMaints.FilterList)));
CreateMap<Syntax, ListSyntaxDto>()
.ForMember(dto => dto.SupportedSoftware,
conf => conf.MapFrom(syntax =>
syntax.SoftwareSyntaxes.Select(softSyn => softSyn.Software)));
conf => conf.MapFrom(syntax => syntax.SoftwareSyntaxes.Select(softSyn => softSyn.Software)));
}
}
}

View file

@ -0,0 +1,11 @@
using JetBrains.Annotations;
namespace FilterLists.Services.FilterList
{
[UsedImplicitly]
public class SyntaxSupportedSoftwareDto
{
public string HomeUrl { get; set; }
public string Name { get; set; }
}
}

View file

@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="7.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="4.0.0" />
<PackageReference Include="JetBrains.Annotations" Version="11.1.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.3.0" />
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.2.12-alpha" />
</ItemGroup>

View file

@ -1,7 +1,9 @@
using System;
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models
{
[UsedImplicitly]
public class FilterListSeedDto
{
public int Id { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models.Junctions
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models.Junctions
{
[UsedImplicitly]
public class FilterListLanguageSeedDto
{
public int FilterListId { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models.Junctions
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models.Junctions
{
[UsedImplicitly]
public class FilterListMaintainerSeedDto
{
public int FilterListId { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models.Junctions
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models.Junctions
{
[UsedImplicitly]
public class ForkSeedDto
{
public int ForkFilterListId { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models.Junctions
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models.Junctions
{
[UsedImplicitly]
public class MergeSeedDto
{
public int MergeFilterListId { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models.Junctions
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models.Junctions
{
[UsedImplicitly]
public class SoftwareSyntaxSeedDto
{
public int SoftwareId { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models
{
[UsedImplicitly]
public class LanguageSeedDto
{
public int Id { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models
{
[UsedImplicitly]
public class LicenseSeedDto
{
public int Id { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models
{
[UsedImplicitly]
public class MaintainerSeedDto
{
public int Id { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models
{
[UsedImplicitly]
public class SoftwareSeedDto
{
public int Id { get; set; }

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Seed.Models
using JetBrains.Annotations;
namespace FilterLists.Services.Seed.Models
{
[UsedImplicitly]
public class SyntaxSeedDto
{
public int Id { get; set; }

View file

@ -4,46 +4,43 @@
using System.Threading.Tasks;
using AutoMapper.QueryableExtensions;
using FilterLists.Data;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
namespace FilterLists.Services.Seed
{
[UsedImplicitly]
public class SeedService
{
private readonly FilterListsDbContext filterListsDbContext;
private readonly FilterListsDbContext _filterListsDbContext;
public SeedService(FilterListsDbContext filterListsDbContext)
{
this.filterListsDbContext = filterListsDbContext;
_filterListsDbContext = filterListsDbContext;
}
public async Task<IEnumerable<TSeedDto>> GetAllAsync<TEntity, TSeedDto>() where TEntity : class
{
return await filterListsDbContext.Set<TEntity>()
.AsNoTracking()
.ProjectTo<TSeedDto>()
.ToArrayAsync();
}
public async Task<IEnumerable<TSeedDto>> GetAllAsync<TEntity, TSeedDto>() where TEntity : class =>
await _filterListsDbContext.Set<TEntity>().AsNoTracking().ProjectTo<TSeedDto>().ToArrayAsync();
public async Task<IEnumerable<TSeedDto>> GetAllAsync<TEntity, TSeedDto>(PropertyInfo primarySort)
where TEntity : class
{
return await filterListsDbContext.Set<TEntity>()
.OrderBy(x => primarySort.GetValue(x, null))
.AsNoTracking()
.ProjectTo<TSeedDto>()
.ToArrayAsync();
return await _filterListsDbContext.Set<TEntity>()
.OrderBy(x => primarySort.GetValue(x, null))
.AsNoTracking()
.ProjectTo<TSeedDto>()
.ToArrayAsync();
}
public async Task<IEnumerable<TSeedDto>> GetAllAsync<TEntity, TSeedDto>(PropertyInfo primarySort,
PropertyInfo secondarySort) where TEntity : class
{
return await filterListsDbContext.Set<TEntity>()
.OrderBy(x => primarySort.GetValue(x, null))
.ThenBy(x => secondarySort.GetValue(x, null))
.AsNoTracking()
.ProjectTo<TSeedDto>()
.ToArrayAsync();
return await _filterListsDbContext.Set<TEntity>()
.OrderBy(x => primarySort.GetValue(x, null))
.ThenBy(x => secondarySort.GetValue(x, null))
.AsNoTracking()
.ProjectTo<TSeedDto>()
.ToArrayAsync();
}
}
}

View file

@ -1,5 +1,8 @@
namespace FilterLists.Services.Snapshot
using JetBrains.Annotations;
namespace FilterLists.Services.Snapshot
{
[UsedImplicitly]
public class FilterListViewUrlDto
{
public int Id { get; set; }

View file

@ -19,29 +19,17 @@ private static string TrimLeadingAndTrailingWhitespace(this string rule)
return rule.Trim(charsToTrim);
}
private static string DropIfEmpty(this string rule)
{
return rule == "" ? null : rule;
}
private static string DropIfEmpty(this string rule) => rule == "" ? null : rule;
private static string DropIfComment(this string rule)
{
return rule.StartsWith(@"!") && !rule.StartsWith(@"!#") || rule.StartsWith(@"!##") ? null : rule;
}
private static string DropIfComment(this string rule) =>
rule.StartsWith(@"!") && !rule.StartsWith(@"!#") || rule.StartsWith(@"!##") ? null : rule;
private static string DropIfTooLong(this string rule)
{
return rule.Length > 8192 ? null : rule;
}
private static string DropIfTooLong(this string rule) => rule.Length > 8192 ? null : rule;
private static string DropIfContainsBackslashSingleQuote(this string rule)
{
return rule.Contains(@"\'") ? null : rule;
}
private static string DropIfContainsBackslashSingleQuote(this string rule) =>
rule.Contains(@"\'") ? null : rule;
private static string TrimSingleBackslashFromEnd(this string rule)
{
return rule.EndsWith(@"\") && !rule.EndsWith(@"\\") ? rule.Remove(rule.Length - 1) : rule;
}
private static string TrimSingleBackslashFromEnd(this string rule) =>
rule.EndsWith(@"\") && !rule.EndsWith(@"\\") ? rule.Remove(rule.Length - 1) : rule;
}
}

View file

@ -10,42 +10,43 @@ namespace FilterLists.Services.Snapshot
{
public class SnapshotBatchDe
{
private readonly FilterListsDbContext dbContext;
private readonly IEnumerable<string> rawRules;
private readonly Data.Entities.Snapshot snapshot;
private IQueryable<Rule> rules;
private readonly FilterListsDbContext _dbContext;
private readonly IEnumerable<string> _rawRules;
private readonly Data.Entities.Snapshot _snapshot;
private IQueryable<Rule> _rules;
public SnapshotBatchDe(FilterListsDbContext dbContext, Data.Entities.Snapshot snapshot, IEnumerable<string> rawRules)
public SnapshotBatchDe(FilterListsDbContext dbContext, Data.Entities.Snapshot snapshot,
IEnumerable<string> rawRules)
{
this.dbContext = dbContext;
this.snapshot = snapshot;
this.rawRules = rawRules;
_dbContext = dbContext;
_snapshot = snapshot;
_rawRules = rawRules;
}
public async Task SaveSnapshotBatchAsync()
{
AddRules();
AddSnapshotRules();
await dbContext.SaveChangesAsync();
await _dbContext.SaveChangesAsync();
}
private void AddRules()
{
var existingRules = dbContext.Rules.Where(rule => rawRules.Contains(rule.Raw));
var newRawRules = rawRules.Except(existingRules.Select(r => r.Raw));
var existingRules = _dbContext.Rules.Where(rule => _rawRules.Contains(rule.Raw));
var newRawRules = _rawRules.Except(existingRules.Select(r => r.Raw));
var newRules = newRawRules.Select(newRawRule => new Rule {Raw = newRawRule}).ToList();
dbContext.Rules.AddRange(newRules);
rules = existingRules.Concat(newRules);
_dbContext.Rules.AddRange(newRules);
_rules = existingRules.Concat(newRules);
}
private void AddSnapshotRules()
{
var snapshotRules = new List<SnapshotRule>();
foreach (var rule in rules)
foreach (var rule in _rules)
snapshotRules.Add(new SnapshotRule {Rule = rule});
if (snapshot.AddedSnapshotRules == null)
snapshot.AddedSnapshotRules = new List<SnapshotRule>();
snapshot.AddedSnapshotRules.AddRange(snapshotRules);
if (_snapshot.AddedSnapshotRules == null)
_snapshot.AddedSnapshotRules = new List<SnapshotRule>();
_snapshot.AddedSnapshotRules.AddRange(snapshotRules);
}
}
}

View file

@ -5,7 +5,6 @@
using System.Net.Http;
using System.Threading.Tasks;
using FilterLists.Data;
using FilterLists.Data.Entities;
using FilterLists.Data.Entities.Junctions;
using FilterLists.Services.Extensions;
@ -13,19 +12,18 @@ namespace FilterLists.Services.Snapshot
{
public class SnapshotDe
{
private const int BatchSize = 1000;
private const string UserAgentString =
@"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
private readonly FilterListsDbContext dbContext;
private readonly FilterListViewUrlDto list;
private Data.Entities.Snapshot snapshot;
private const int BatchSize = 1000;
private readonly FilterListsDbContext _dbContext;
private readonly FilterListViewUrlDto _list;
private Data.Entities.Snapshot _snapshot;
public SnapshotDe(FilterListsDbContext dbContext, FilterListViewUrlDto list)
{
this.dbContext = dbContext;
this.list = list;
_dbContext = dbContext;
_list = list;
}
public async Task SaveSnapshotAsync()
@ -44,14 +42,14 @@ private async Task<string> CaptureSnapshot()
{
await AddSnapshot();
var content = await TryGetContent();
await dbContext.SaveChangesAsync();
await _dbContext.SaveChangesAsync();
return content;
}
private async Task AddSnapshot()
{
snapshot = new Data.Entities.Snapshot {FilterListId = list.Id};
await dbContext.Snapshots.AddAsync(snapshot);
_snapshot = new Data.Entities.Snapshot {FilterListId = _list.Id};
await _dbContext.Snapshots.AddAsync(_snapshot);
}
private async Task<string> TryGetContent()
@ -62,13 +60,13 @@ private async Task<string> TryGetContent()
}
catch (WebException we)
{
snapshot.HttpStatusCode = ((int)((HttpWebResponse)we.Response).StatusCode).ToString();
_snapshot.HttpStatusCode = ((int) ((HttpWebResponse) we.Response).StatusCode).ToString();
return null;
}
catch (Exception)
{
//TODO: log exception (#148)
snapshot.HttpStatusCode = null;
_snapshot.HttpStatusCode = null;
return null;
}
}
@ -78,9 +76,9 @@ private async Task<string> GetContent()
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(UserAgentString);
using (var httpResponseMessage = await httpClient.GetAsync(list.ViewUrl))
using (var httpResponseMessage = await httpClient.GetAsync(_list.ViewUrl))
{
snapshot.HttpStatusCode = ((int)httpResponseMessage.StatusCode).ToString();
_snapshot.HttpStatusCode = ((int) httpResponseMessage.StatusCode).ToString();
if (httpResponseMessage.IsSuccessStatusCode)
return await httpResponseMessage.Content.ReadAsStringAsync();
}
@ -107,7 +105,7 @@ private static IEnumerable<string> GetRawRules(string content)
private IEnumerable<SnapshotBatchDe> GetSnapshotBatches(IEnumerable<string> rawRules)
{
return rawRules.Batch(BatchSize)
.Select(rawRuleBatch => new SnapshotBatchDe(dbContext, snapshot, rawRuleBatch));
.Select(rawRuleBatch => new SnapshotBatchDe(_dbContext, _snapshot, rawRuleBatch));
}
private static async Task SaveSnapshotBatches(IEnumerable<SnapshotBatchDe> snapshotBatches)
@ -121,37 +119,36 @@ private async Task DedupSnapshotRules()
var existingSnapshotRules = GetExistingSnapshotRules();
UpdateRemovedSnapshotRules(existingSnapshotRules);
RemoveDuplicateSnapshotRules(existingSnapshotRules);
await dbContext.SaveChangesAsync();
await _dbContext.SaveChangesAsync();
}
private IQueryable<SnapshotRule> GetExistingSnapshotRules()
{
return dbContext.SnapshotRules.Where(sr =>
sr.AddedBySnapshot.FilterListId == list.Id &&
sr.AddedBySnapshot != snapshot &&
return _dbContext.SnapshotRules.Where(sr =>
sr.AddedBySnapshot.FilterListId == _list.Id && sr.AddedBySnapshot != _snapshot &&
sr.RemovedBySnapshot == null);
}
private void UpdateRemovedSnapshotRules(IQueryable<SnapshotRule> existingSnapshotRules)
{
var newSnapshotRules = dbContext.SnapshotRules.Where(sr => sr.AddedBySnapshot == snapshot);
var newSnapshotRules = _dbContext.SnapshotRules.Where(sr => sr.AddedBySnapshot == _snapshot);
var removedSnapshotRules =
existingSnapshotRules.Where(sr => !newSnapshotRules.Any(nsr => nsr.Rule == sr.Rule));
removedSnapshotRules.ToList().ForEach(sr => sr.RemovedBySnapshot = snapshot);
removedSnapshotRules.ToList().ForEach(sr => sr.RemovedBySnapshot = _snapshot);
}
private void RemoveDuplicateSnapshotRules(IQueryable<SnapshotRule> existingSnapshotRules)
{
var duplicateSnapshotRules = dbContext.SnapshotRules.Where(sr =>
sr.AddedBySnapshot == snapshot &&
var duplicateSnapshotRules = _dbContext.SnapshotRules.Where(sr =>
sr.AddedBySnapshot == _snapshot &&
existingSnapshotRules.Any(esr => esr.Rule == sr.Rule));
dbContext.SnapshotRules.RemoveRange(duplicateSnapshotRules);
_dbContext.SnapshotRules.RemoveRange(duplicateSnapshotRules);
}
private async Task SetCompleted()
{
snapshot.IsCompleted = true;
await dbContext.SaveChangesAsync();
_snapshot.IsCompleted = true;
await _dbContext.SaveChangesAsync();
}
}
}

View file

@ -4,16 +4,17 @@
using System.Threading.Tasks;
using AutoMapper.QueryableExtensions;
using FilterLists.Data;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
namespace FilterLists.Services.Snapshot
{
[UsedImplicitly]
public class SnapshotService
{
private readonly FilterListsDbContext dbContext;
//TODO: update algorithm to support non-standard list sizes and formats (#200, #201)
private readonly List<int> ignoreLists = new List<int> {48, 149, 173, 185, 186, 187, 188, 189, 352};
private readonly List<int> _ignoreLists = new List<int> {48, 149, 173, 185, 186, 187, 188, 189, 352};
private readonly FilterListsDbContext dbContext;
public SnapshotService(FilterListsDbContext dbContext)
{
@ -41,15 +42,12 @@ private async Task<IEnumerable<FilterListViewUrlDto>> GetListsToCapture(int batc
.FilterLists
.Where(list =>
(!list.Snapshots.Any() ||
list.Snapshots
.Select(ss => ss.CreatedDateUtc)
list.Snapshots.Select(ss => ss.CreatedDateUtc)
.OrderByDescending(sscd => sscd)
.FirstOrDefault() < DateTime.UtcNow.AddDays(-1)) &&
!ignoreLists.Contains(list.Id))
.FirstOrDefault() < DateTime.UtcNow.AddDays(-1)) && !_ignoreLists.Contains(list.Id))
.OrderBy(list => list.Snapshots.Any())
.ThenBy(list =>
list.Snapshots
.Select(ss => ss.CreatedDateUtc)
list.Snapshots.Select(ss => ss.CreatedDateUtc)
.OrderByDescending(sscd => sscd)
.FirstOrDefault())
.Take(batchSize)