Skip to content

Commit

Permalink
angular, dotnet upgrades, db speed improvements (#109)
Browse files Browse the repository at this point in the history
* no tracking

(cherry picked from commit 3b2d903)

* package upgrades

(cherry picked from commit 95a69b2)

* improve stats query

* remove debug

* rename front end app

* rename app

* correct dist folder

* fix logging out

* icons aligned, mobile response

* this too

* hook searching back up

* handle slow internet better

* try tracking

* downgrade ef

* image compression

* set temp folder to config folder

* optimize filters query

* upgraded to dotnet7, reworked statistics query

* fix windows build, fix migrate

* get rid of rest of fx styling

* more mobile responsive

* move images to another table

* fix logger

* add cleanup vacuum

* outside transaction

* fix images in queries

* loading icon styling

* added pwa

* add push notifications

* generate keys on startup if missing

* turn service worker off locally
  • Loading branch information
mlapaglia authored Nov 7, 2023
1 parent a331007 commit 6081aad
Show file tree
Hide file tree
Showing 281 changed files with 7,595 additions and 692 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/.angular
**/config
LICENSE
README.md
2 changes: 1 addition & 1 deletion .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Setup Buildx
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
dotnet-version: '7.x'
include-prerelease: true

- name: Build Artifact
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -356,4 +356,4 @@ dist/
**/log*.txt
*db-shm
*db-wal
OpenAlprWebhookProcessor/ClientApp/.angular/*
OpenAlprWebhookProcessor/angularapp/.angular/*
38 changes: 22 additions & 16 deletions OpenAlprWebhookProcessor/Alerts/AlertService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using OpenAlprWebhookProcessor.Data;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -24,20 +25,20 @@ public class AlertService : IHostedService

private readonly IHubContext<ProcessorHub.ProcessorHub, ProcessorHub.IProcessorHub> _processorHub;

private readonly IAlertClient _alertClient;
private readonly IEnumerable<IAlertClient> _alertClients;

public AlertService(
IServiceProvider serviceProvider,
ILogger<AlertService> logger,
IHubContext<ProcessorHub.ProcessorHub, ProcessorHub.IProcessorHub> processorHub,
IAlertClient alertClient)
IEnumerable<IAlertClient> alertClients)
{
_logger = logger;
_serviceProvider = serviceProvider;
_cancellationTokenSource = new CancellationTokenSource();
_alertsToProcess = new BlockingCollection<AlertUpdateRequest>();
_processorHub = processorHub;
_alertClient = alertClient;
_alertClients = alertClients;
}

public void AddJob(AlertUpdateRequest request)
Expand Down Expand Up @@ -81,27 +82,32 @@ private async Task ProcessAlertsAsync()
plateGroups = plateGroups.Where(x => x.Id == job.LicensePlateId);
}

var result = await plateGroups.FirstOrDefaultAsync(_cancellationTokenSource.Token);
var result = await plateGroups
.Include(x => x.PlateImage)
.FirstOrDefaultAsync(_cancellationTokenSource.Token);

if (result != null)
{
_logger.LogInformation("alerting for: {alertId}", result.Id);
await _processorHub.Clients.All.LicensePlateAlerted(result.Id.ToString());

try
foreach (var alertClient in _alertClients)
{
await _alertClient.SendAlertAsync(new Alert()
try
{
Description = job.Description,
Id = result.Id,
PlateNumber = result.BestNumber,
},
result.PlatePreviewJpeg,
_cancellationTokenSource.Token);
}
catch (Exception ex)
{
_logger.LogError(ex, $"failed to send alert to {nameof(_alertClient)}");
await alertClient.SendAlertAsync(new Alert()
{
Description = job.Description,
Id = result.Id,
PlateNumber = result.BestNumber,
},
result.PlateImage.Jpeg,
_cancellationTokenSource.Token);
}
catch (Exception ex)
{
_logger.LogError(ex, $"failed to send alert to {nameof(alertClient)}");
}
}
}
}
Expand Down
33 changes: 32 additions & 1 deletion OpenAlprWebhookProcessor/Alerts/AlertsController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OpenAlprWebhookProcessor.Alerts.Pushover;
using OpenAlprWebhookProcessor.Alerts.WebPush;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -22,18 +23,30 @@ public class AlertsController : Controller

private readonly TestPushoverClientRequestHandler _testPushoverClientRequestHandler;

private readonly UpsertWebPushClientRequestHandler _upsertWebPushRequestHandler;

private readonly GetWebPushClientRequestHandler _getWebPushClientRequestHandler;

private readonly TestWebPushClientRequestHandler _testWebPushClientRequestHandler;

public AlertsController(
GetAlertsRequestHandler getAlertsRequestHandler,
UpsertAlertsRequestHandler upsertAlertsRequestHandler,
UpsertPushoverClientRequestHandler upsertPushoverRequestHandler,
GetPushoverClientRequestHandler getPushoverClientRequestHandler,
TestPushoverClientRequestHandler testPushoverClientRequestHandler)
TestPushoverClientRequestHandler testPushoverClientRequestHandler,
UpsertWebPushClientRequestHandler upsertWebPushRequestHandler,
GetWebPushClientRequestHandler getWebPushClientRequestHandler,
TestWebPushClientRequestHandler testWebPushClientRequestHandler)
{
_getAlertsRequestHandler = getAlertsRequestHandler;
_upsertAlertsRequestHandler = upsertAlertsRequestHandler;
_upsertPushoverRequestHandler = upsertPushoverRequestHandler;
_getPushoverClientRequestHandler = getPushoverClientRequestHandler;
_testPushoverClientRequestHandler = testPushoverClientRequestHandler;
_upsertWebPushRequestHandler = upsertWebPushRequestHandler;
_getWebPushClientRequestHandler = getWebPushClientRequestHandler;
_testWebPushClientRequestHandler = testWebPushClientRequestHandler;
}

[HttpPost("add")]
Expand Down Expand Up @@ -71,5 +84,23 @@ public async Task<PushoverRequest> GetPushover(CancellationToken cancellationTok
{
return await _getPushoverClientRequestHandler.HandleAsync(cancellationToken);
}

[HttpPost("webpush")]
public async Task UpsertWebpush([FromBody] WebPushRequest request)
{
await _upsertWebPushRequestHandler.HandleAsync(request);
}

[HttpPost("webpush/test")]
public async Task UpsertWebpush(CancellationToken cancellationToken)
{
await _testWebPushClientRequestHandler.HandleAsync(cancellationToken);
}

[HttpGet("webpush")]
public async Task<WebPushRequest> GetWebpush(CancellationToken cancellationToken)
{
return await _getWebPushClientRequestHandler.HandleAsync(cancellationToken);
}
}
}
5 changes: 3 additions & 2 deletions OpenAlprWebhookProcessor/Alerts/IAlertClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAlprWebhookProcessor.Alerts
Expand All @@ -7,7 +8,7 @@ public interface IAlertClient
{
Task SendAlertAsync(
Alert alert,
string base64PreviewJpeg,
byte[] plateJpeg,
CancellationToken cancellationToken);

Task VerifyCredentialsAsync(
Expand Down
26 changes: 15 additions & 11 deletions OpenAlprWebhookProcessor/Alerts/Pushover/PushoverClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public PushoverClient(IServiceProvider serviceProvider)

public async Task SendAlertAsync(
Alert alert,
string base64PreviewJpeg,
byte[] plateJpeg,
CancellationToken cancellationToken)
{
using (var scope = _serviceProvider.CreateScope())
Expand All @@ -39,7 +39,9 @@ public async Task SendAlertAsync(

var processorContext = scope.ServiceProvider.GetRequiredService<ProcessorContext>();

var clientSettings = await processorContext.PushoverAlertClients.FirstOrDefaultAsync(cancellationToken);
var clientSettings = await processorContext.PushoverAlertClients
.AsNoTracking()
.FirstOrDefaultAsync(cancellationToken);

var boundary = Guid.NewGuid().ToString();
using (var content = new MultipartFormDataContent(boundary))
Expand All @@ -51,9 +53,9 @@ public async Task SendAlertAsync(
content.Add(new StringContent(alert.PlateNumber + " " + alert.Description), "message");
content.Add(new StringContent("openalpr alert"), "title");

if (clientSettings.SendPlatePreview)
if (clientSettings.SendPlatePreview && plateJpeg != null)
{
content.Add(new ByteArrayContent(Convert.FromBase64String(base64PreviewJpeg)), "attachment", "attachment.jpg");
content.Add(new ByteArrayContent(plateJpeg), "attachment", "attachment.jpg");
}

try
Expand All @@ -67,15 +69,15 @@ public async Task SendAlertAsync(
{
var result = await response.Content.ReadAsStringAsync(cancellationToken);

logger.LogError("Failed to send alert via Pushover: " + result);
logger.LogError("Failed to send alert via Pushover: {result}", result);
throw new InvalidOperationException("failed");
}

logger.LogInformation("Alert sent via Pushover.");
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to send alert via Pushover: " + ex.Message);
logger.LogError(ex, "Failed to send alert via Pushover: {exception}", ex.Message);
throw new InvalidOperationException("failed");
}
}
Expand All @@ -92,27 +94,29 @@ public async Task VerifyCredentialsAsync(CancellationToken cancellationToken)

var processorContext = scope.ServiceProvider.GetRequiredService<ProcessorContext>();

var clientSettings = await processorContext.PushoverAlertClients.FirstOrDefaultAsync(cancellationToken);
var clientSettings = await processorContext.PushoverAlertClients
.AsNoTracking()
.FirstOrDefaultAsync(cancellationToken);

try
{
var result = await _httpClient.PostAsync(VerifyCredentialsUrl
.Replace("{0}", clientSettings.ApiToken)
.Replace("{1}", clientSettings.UserKey),
.Replace("{0}", clientSettings.ApiToken)
.Replace("{1}", clientSettings.UserKey),
null,
cancellationToken);

if (!result.IsSuccessStatusCode)
{
var message = await result.Content.ReadAsStringAsync(cancellationToken);
logger.LogError("Pushover credential check failed: " + message);
logger.LogError("Pushover credential check failed: {message}", message);
}

logger.LogInformation("Pushover credentials are valid.");
}
catch (Exception ex)
{
logger.LogError(ex, "Pushover credential check failed: " + ex.Message);
logger.LogError(ex, "Pushover credential check failed: {exception}", ex.Message);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Microsoft.EntityFrameworkCore;
using OpenAlprWebhookProcessor.Data;
using OpenAlprWebhookProcessor.WebPushSubscriptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -14,16 +16,17 @@ public class TestPushoverClientRequestHandler
private readonly IAlertClient _alertClient;

public TestPushoverClientRequestHandler(ProcessorContext processorContext,
IAlertClient alertClient)
IEnumerable<IAlertClient> alertClients)
{
_processorContext = processorContext;
_alertClient = alertClient;
_alertClient = alertClients.First(x => x is WebPushNotificationProducer);
}

public async Task HandleAsync(CancellationToken cancellationToken)
{
var testPlateGroup = await _processorContext.PlateGroups
.Where(x => x.PlatePreviewJpeg != null)
.Include(x => x.PlateImage)
.Where(x => x.PlateImage != null)
.FirstOrDefaultAsync(cancellationToken);

await _alertClient.VerifyCredentialsAsync(cancellationToken);
Expand All @@ -35,7 +38,7 @@ await _alertClient.SendAlertAsync(new Alert()
PlateNumber = testPlateGroup.BestNumber,
StrictMatch = false,
},
testPlateGroup.PlatePreviewJpeg,
testPlateGroup.PlateImage.Jpeg,
cancellationToken);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using OpenAlprWebhookProcessor.Data;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.EntityFrameworkCore;
using OpenAlprWebhookProcessor.WebPushSubscriptions.VapidKeys;

namespace OpenAlprWebhookProcessor.Alerts.WebPush
{
public class GetWebPushClientRequestHandler
{
private readonly ProcessorContext _processorContext;

public GetWebPushClientRequestHandler(ProcessorContext processorContext)
{
_processorContext = processorContext;
}

public async Task<WebPushRequest> HandleAsync(CancellationToken cancellationToken)
{
var client = await _processorContext.WebPushSettings.FirstOrDefaultAsync(cancellationToken);

if (client == null)
{
client = VapidKeyHelper.AddVapidKeys(_processorContext);
}

return new WebPushRequest()
{
IsEnabled = client.IsEnabled,
EmailAddress = client.Subject,
PublicKey = client.PublicKey,
PrivateKey = client.PrivateKey,
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Microsoft.EntityFrameworkCore;
using OpenAlprWebhookProcessor.Data;
using OpenAlprWebhookProcessor.WebPushSubscriptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAlprWebhookProcessor.Alerts.WebPush
{
public class TestWebPushClientRequestHandler
{
private readonly ProcessorContext _processorContext;

private readonly IAlertClient _alertClient;

public TestWebPushClientRequestHandler(ProcessorContext processorContext,
IEnumerable<IAlertClient> alertClients)
{
_processorContext = processorContext;
_alertClient = alertClients.First(x => x is WebPushNotificationProducer);
}

public async Task HandleAsync(CancellationToken cancellationToken)
{
var testPlateGroup = await _processorContext.PlateGroups
.Include(x => x.PlateImage)
.Where(x => x.PlateImage != null)
.FirstOrDefaultAsync(cancellationToken);

await _alertClient.VerifyCredentialsAsync(cancellationToken);

await _alertClient.SendAlertAsync(new Alert()
{
Description = "was seen on " + DateTimeOffset.Now.ToString("g"),
Id = testPlateGroup.Id,
PlateNumber = testPlateGroup.BestNumber,
StrictMatch = false,
},
testPlateGroup.PlateImage.Jpeg,
cancellationToken);
}
}
}
Loading

0 comments on commit 6081aad

Please sign in to comment.