Skip to content

Commit

Permalink
some more over here
Browse files Browse the repository at this point in the history
  • Loading branch information
mlapaglia committed Jul 1, 2021
1 parent 7a8b525 commit 5bcd9c7
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 45 deletions.
14 changes: 13 additions & 1 deletion OpenAlprWebhookProcessor/Alerts/AlertService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,20 @@ public class AlertService : IHostedService

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

private readonly IAlertClient _alertClient;

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

public void AddJob(AlertUpdateRequest request)
Expand Down Expand Up @@ -83,6 +87,14 @@ private async Task ProcessAlertsAsync()
{
_logger.LogInformation($"alerting for: {result.Id}");
await _processorHub.Clients.All.LicensePlateAlerted(result.Id.ToString());
await _alertClient.SendAlertAsync(new Alert()
{
Description = result.AlertDescription.ToString(),
Id = result.Id,
PlateNumber = result.BestNumber.ToString(),
},
result.Jpeg,
_cancellationTokenSource.Token);
}
}
}
Expand Down
39 changes: 32 additions & 7 deletions OpenAlprWebhookProcessor/Alerts/AlertsController.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,75 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OpenAlprWebhookProcessor.Alerts.Pushover;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAlprWebhookProcessor.Alerts
{
[Authorize]
[ApiController]
[Route("alerts")]
public class AlertsController : Controller
{
private readonly GetAlertsRequestHandler _getAlertsRequestHandler;

private readonly UpsertAlertsRequestHandler _upsertAlertsRequestHandler;

private readonly UpsertPushoverRequestHandler _upsertPushoverRequestHandler;
private readonly UpsertPushoverClientRequestHandler _upsertPushoverRequestHandler;

private readonly GetPushoverClientRequestHandler _getPushoverClientRequestHandler;

private readonly TestPushoverClientRequestHandler _testPushoverClientRequestHandler;

public AlertsController(
GetAlertsRequestHandler getAlertsRequestHandler,
UpsertAlertsRequestHandler upsertAlertsRequestHandler,
UpsertPushoverRequestHandler upsertPushoverRequestHandler)
UpsertPushoverClientRequestHandler upsertPushoverRequestHandler,
GetPushoverClientRequestHandler getPushoverClientRequestHandler,
TestPushoverClientRequestHandler testPushoverClientRequestHandler)
{
_getAlertsRequestHandler = getAlertsRequestHandler;
_upsertAlertsRequestHandler = upsertAlertsRequestHandler;
_upsertPushoverRequestHandler = upsertPushoverRequestHandler;
_getPushoverClientRequestHandler = getPushoverClientRequestHandler;
_testPushoverClientRequestHandler = testPushoverClientRequestHandler;
}

[HttpPost("alerts/add")]
[HttpPost("add")]
public async Task AddAlert([FromBody] Alert alert)
{
await _upsertAlertsRequestHandler.AddAlertAsync(alert);
}

[HttpPost("alerts")]
[HttpPost]
public async Task UpsertAlerts([FromBody] List<Alert> alerts)
{
await _upsertAlertsRequestHandler.UpsertAlertsAsync(alerts);
}

[HttpGet("alerts")]
[HttpGet]
public async Task<List<Alert>> GetAlerts(CancellationToken cancellationToken)
{
return await _getAlertsRequestHandler.HandleAsync(cancellationToken);
}

[HttpPost("pushover")]
public async Task UpsertPushover([FromBody] UpsertPushoverRequest request)
public async Task UpsertPushover([FromBody] PushoverRequest request)
{
await _upsertPushoverRequestHandler.HandleAsync(request);
}

[HttpPost("pushover/test")]
public async Task UpsertPushover(CancellationToken cancellationToken)
{
await _testPushoverClientRequestHandler.HandleAsync(cancellationToken);
}

[HttpGet("pushover")]
public async Task<PushoverRequest> GetPushover(CancellationToken cancellationToken)
{
return await _getPushoverClientRequestHandler.HandleAsync(cancellationToken);
}
}
}
8 changes: 6 additions & 2 deletions OpenAlprWebhookProcessor/Alerts/IAlertClient.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAlprWebhookProcessor.Alerts
{
public interface IAlertClient
{
Task SendAlertAsync(Alert alert);
Task SendAlertAsync(
Alert alert,
string base64PreviewJpeg,
CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore;
using OpenAlprWebhookProcessor.Data;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAlprWebhookProcessor.Alerts.Pushover
{
public class GetPushoverClientRequestHandler
{
private readonly ProcessorContext _processorContext;

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

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

if (client == null)
{
return new PushoverRequest();
}

return new PushoverRequest()
{
ApiToken = client.ApiToken,
IsEnabled = client.IsEnabled,
SendPlatePreviewEnabled = client.SendPlatePreview,
UserKey = client.UserKey,
};
}
}
}
61 changes: 54 additions & 7 deletions OpenAlprWebhookProcessor/Alerts/Pushover/PushoverClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
using System.Net.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using OpenAlprWebhookProcessor.Data;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAlprWebhookProcessor.Alerts.Pushover
Expand All @@ -9,18 +16,58 @@ public class PushoverClient : IAlertClient

private readonly HttpClient _httpClient;

private readonly PushoverConfiguration _pushoverConfiguration;
private readonly IServiceProvider _serviceProvider;

public PushoverClient(PushoverConfiguration pushoverConfiguration)
public PushoverClient(IServiceProvider serviceProvider)
{
_pushoverConfiguration = pushoverConfiguration;
_httpClient = new HttpClient();
_serviceProvider = serviceProvider;
}
public async Task SendAlertAsync(Alert alert)

public async Task SendAlertAsync(
Alert alert,
string base64PreviewJpeg,
CancellationToken cancellationToken)
{
var pushUrl = PushOverApiUrl + $"?token={_pushoverConfiguration.AppToken}&user={_pushoverConfiguration.UserKey}&message={alert.PlateNumber}";
using (var scope = _serviceProvider.CreateScope())
{
var processorContext = scope.ServiceProvider.GetRequiredService<ProcessorContext>();

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

var boundary = Guid.NewGuid().ToString();
using (var content = new MultipartFormDataContent(boundary))
{
content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary);

content.Add(new StringContent(clientSettings.UserKey), "user");
content.Add(new StringContent(clientSettings.ApiToken), "token");
content.Add(new StringContent(alert.PlateNumber + " " + alert.Description), "message");
content.Add(new StringContent("openalpr alert"), "title");

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

try
{
var response = await _httpClient.PostAsync(
PushOverApiUrl,
content,
cancellationToken);

await _httpClient.PostAsync(pushUrl, null);
if (!response.IsSuccessStatusCode)
{
throw new InvalidOperationException("failed");
}
}
catch (Exception ex)
{
throw new InvalidOperationException("failed");
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
namespace OpenAlprWebhookProcessor.Alerts.Pushover
{
public class UpsertPushoverRequest
public class PushoverRequest
{
public bool IsEnabled { get; set; }

public string UserKey { get; set; }

public string ApiToken { get; set; }

public bool SendPlatePreview { get; set; }
public bool SendPlatePreviewEnabled { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore;
using OpenAlprWebhookProcessor.Data;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAlprWebhookProcessor.Alerts.Pushover
{
public class TestPushoverClientRequestHandler
{
private readonly ProcessorContext _processorContext;

private readonly IAlertClient _alertClient;

public TestPushoverClientRequestHandler(ProcessorContext processorContext,
IAlertClient alertClient)
{
_processorContext = processorContext;
_alertClient = alertClient;
}

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

await _alertClient.SendAlertAsync(new Alert()
{
Description = "was seen on " + DateTimeOffset.Now.ToString("g"),
Id = testPlateGroup.Id,
PlateNumber = testPlateGroup.BestNumber,
StrictMatch = false,
},
testPlateGroup.Jpeg,
cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

namespace OpenAlprWebhookProcessor.Alerts.Pushover
{
public class UpsertPushoverRequestHandler
public class UpsertPushoverClientRequestHandler
{
private readonly ProcessorContext _processorContext;

public UpsertPushoverRequestHandler(ProcessorContext processorContext)
public UpsertPushoverClientRequestHandler(ProcessorContext processorContext)
{
_processorContext = processorContext;
}

public async Task HandleAsync(UpsertPushoverRequest request)
public async Task HandleAsync(PushoverRequest request)
{
var pushoverClient = await _processorContext.PushoverAlertClients.FirstOrDefaultAsync();

Expand All @@ -27,15 +27,15 @@ public async Task HandleAsync(UpsertPushoverRequest request)
{
ApiToken = request.ApiToken,
IsEnabled = request.IsEnabled,
SendPlatePreview = request.SendPlatePreview,
SendPlatePreview = request.SendPlatePreviewEnabled,
UserKey = request.UserKey,
};
}
else
{
pushoverClient.ApiToken = request.ApiToken;
pushoverClient.IsEnabled = request.IsEnabled;
pushoverClient.SendPlatePreview = request.SendPlatePreview;
pushoverClient.SendPlatePreview = request.SendPlatePreviewEnabled;
pushoverClient.UserKey = request.UserKey;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
<div style="margin:16px;" fxLayout="row wrap" fxLayout="row wrap" fxLayoutGap=20px>
<div style="margin:16px;" fxLayout="row wrap" fxLayout="row wrap" fxLayoutGap=20px *ngIf="client">
<mat-card>
<mat-card-header style="justify-content: space-between;">
<mat-card-title>Pushover</mat-card-title>
<mat-card-subtitle>https://pushover.net/</mat-card-subtitle>
<mat-slide-toggle
style="padding-top: 10px;"
[(ngModel)]="isEnabled"></mat-slide-toggle>
[(ngModel)]="client.isEnabled"></mat-slide-toggle>
</mat-card-header>
<mat-card-content *ngIf="isEnabled" [@inOutAnimation]>
<mat-card-content *ngIf="client.isEnabled" [@inOutAnimation]>
<div style="margin:16px;" fxLayout="row wrap" fxLayout="row wrap" fxLayoutGap=20px>
<mat-form-field fxFlex="80">
<mat-label>User Key</mat-label>
<input matInput [(ngModel)]="userKey">
<input matInput [(ngModel)]="client.userKey">
<mat-icon matTooltip="The pushover user key, found on the profile page" style="cursor:default" matSuffix>help_center</mat-icon>
</mat-form-field>
<mat-form-field fxFlex="80">
<mat-label>API Token</mat-label>
<input matInput [(ngModel)]="apiToken">
<input matInput [(ngModel)]="client.apiToken">
<mat-icon matTooltip="The pushover api token, found under 'Your Applications' on the profile page" style="cursor:default" matSuffix>help_center</mat-icon>
</mat-form-field>
<div>
<mat-checkbox [(ngModel)]="sendPlatePreviewEnabled">Send Plate Preview Image</mat-checkbox>
<mat-checkbox [(ngModel)]="client.sendPlatePreviewEnabled">Send Plate Preview Image</mat-checkbox>
</div>
</div>
</mat-card-content>
<mat-card-actions align="end" *ngIf="isEnabled" [@inOutAnimation]>
<button mat-button>Save</button>
<mat-card-actions align="end" *ngIf="client.isEnabled" [@inOutAnimation]>
<button mat-button (click)="testClient();" [disabled]="isTesting">Test</button>
<button mat-button (click)="saveClient();" [disabled]="isSaving">Save</button>
</mat-card-actions>
</mat-card>
</div>
Loading

0 comments on commit 5bcd9c7

Please sign in to comment.