2026-06-23 19:03:31 +01:00

176 lines
5.3 KiB
C#

using System.ComponentModel;
using Microsoft.AspNetCore.Mvc;
using Solicitors.CacheBuild;
using Solicitors.Core;
using Solicitors.Core.Misc;
using Solicitors.Core.Models;
using Solicitors.Data;
using Solicitors.Data.RepositorySetup.Sqlite;
using Solicitors.HtmlParsing;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
builder.Services.AddCore();
builder.Services.AddData(new SqliteDbSetupOptions("demo"));
builder.Services.AddCacheBuild();
builder.Services.AddHtmlParsing();
builder.Services.AddHttpClient();
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseCors();
app.MapGet(
"/conveyancors",
(
[FromServices] IReadOnlySolicitorService solicitorService,
CancellationToken cancellationToken,
[FromQuery] uint pageNumber = 1,
[FromQuery] uint pageSize = 20,
[FromQuery] string? nameFilter = null,
[FromQuery] decimal minRating = 0,
[FromQuery] string[]? cities = null,
[FromQuery] string ratingsProvider = "Solicitors.com",
[FromQuery] string? orderingType = null) =>
{
IFilter<Solicitor>? filter = null;
if (!string.IsNullOrEmpty(nameFilter))
filter = new WrapperFilter<Solicitor>(filter, solicitor => solicitor.Name.Contains(nameFilter));
if (cities is not null && cities.Length > 0)
filter = new WrapperFilter<Solicitor>(filter, solicitor => cities.Any(city => solicitor.Cities.Any(solCity => solCity.Name == city)));
if (minRating > 0)
filter = new WrapperFilter<Solicitor>(
filter,
solicitor => solicitor.Ratings.Any(rating => (rating.Provider == ratingsProvider) && (rating.Value / rating.Maximum >= minRating / 5.0m)));
IComparer<Solicitor>? ordering = orderingType switch
{
"rating-asc" => new RatingComparer(ratingsProvider, true),
"rating-desc" => new RatingComparer(ratingsProvider, false),
"alphabet-asc" => new NameComparer(true),
"alphabet-desc" => new NameComparer(false),
_ => null
};
return solicitorService.GetSolicitorSummariesAsync(
new Pagination(pageNumber, pageSize),
ratingsProvider,
filter,
ordering,
cancellationToken: cancellationToken);
}
);
app.MapGet(
"/cities",
(
[FromServices] IReadOnlyCitiesService citiesService,
CancellationToken cancellationToken) =>
{
return citiesService.GetAllCitiesAsync(cancellationToken);
}
);
app.MapGet(
"/conveyancors/{id}",
(
[FromServices] IReadOnlySolicitorService solicitorService,
[FromRoute] Guid id,
CancellationToken cancellationToken
) => solicitorService.GetSolicitorInfoByIdAsync(id, cancellationToken)
);
app.MapGet(
"/ratingsProviders",
(
[FromServices] IRatingsProviderService service,
CancellationToken cancellationToken
) =>
{
return service.GetRatingsProvidersAsync(cancellationToken);
}
);
using (var scope = app.Services.CreateScope())
{
var solicitors = scope.ServiceProvider.GetRequiredService<ISolicitorService>();
var first = await solicitors
.GetSolicitorSummariesAsync(
new Pagination(1, 1),
"Solicitors.com",
cancellationToken: CancellationToken.None);
if (first.Data.Length == 0)
await scope.ServiceProvider
.GetRequiredService<ISolicitorImporter>()
.RunFullImport(CancellationToken.None);
}
app.Run();
public class RatingComparer(string ratingsProvider, bool ascending) : IComparer<Solicitor>
{
public int Compare(Solicitor? x, Solicitor? y)
{
var xRating = x?.Ratings?.FirstOrDefault(r => r.Provider == ratingsProvider);
var yRating = y?.Ratings?.FirstOrDefault(r => r.Provider == ratingsProvider);
decimal compare;
if (xRating is null)
compare = yRating is null ? 0 : 1;
else if (yRating is null)
compare = -1;
else
{
compare = (xRating.Value / xRating.Maximum) - (yRating.Value / yRating.Maximum);
if (!ascending)
compare *= -1;
}
if (compare >= 0)
return (int)Math.Ceiling(compare);
else
return (int)Math.Floor(compare);
}
}
public class NameComparer(bool ascending) : IComparer<Solicitor>
{
public int Compare(Solicitor? x, Solicitor? y)
{
int compare;
if (ReferenceEquals(x, y))
compare = 0;
else if (y is null)
compare = 1;
else if (x is null)
compare = -1;
else
{
compare = string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
if (!ascending)
compare *= -1;
}
return compare;
}
}