diff options
Diffstat (limited to 'Pages/JobCounter')
| -rw-r--r-- | Pages/JobCounter/Index.cshtml | 17 | ||||
| -rw-r--r-- | Pages/JobCounter/Index.cshtml.cs | 74 | ||||
| -rw-r--r-- | Pages/JobCounter/Index.cshtml.css | 14 |
3 files changed, 105 insertions, 0 deletions
diff --git a/Pages/JobCounter/Index.cshtml b/Pages/JobCounter/Index.cshtml new file mode 100644 index 0000000..22f3a95 --- /dev/null +++ b/Pages/JobCounter/Index.cshtml @@ -0,0 +1,17 @@ +@page "{PageDestination}" +@model IndexModel + +<link rel="stylesheet" type="text/css" href="@(nameof(PagerParser)).styles.css"/> + +<script type="text/javascript"> + window.onload = () => { + var refreshInterval = @Html.Raw(Model.RefreshInterval); + if(refreshInterval != 0) { + setTimeout(() => window.location.reload(), refreshInterval * 1000); + } + } +</script> + +<div> + <h1>@Model.TotalJobs</h1> +</div> diff --git a/Pages/JobCounter/Index.cshtml.cs b/Pages/JobCounter/Index.cshtml.cs new file mode 100644 index 0000000..cec36fa --- /dev/null +++ b/Pages/JobCounter/Index.cshtml.cs @@ -0,0 +1,74 @@ +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.RazorPages; +using System.Text.RegularExpressions; + +namespace PagerParser.Pages; + +public class IndexModel : PageModel { + private readonly PagerContext db; + private readonly JobCounterConfiguration config = new(); + + private string pageDestination; + + public IndexModel(PagerContext db, IConfiguration config) { + this.db = db; + + config.Bind("PagerParser:JobCounter", this.config); + } + + public int RefreshInterval => config.RefreshInterval ?? 0; + public string MessageFilter => + $"^@@ALERT.*\\[{Regex.Escape(pageDestination)}\\]$"; + + public int TotalJobs { + get { + // Attempt to calculate the number of jobs attended based on the + // number of distinct FIRS report numbers for successfully-parsed + // pager messages plus the number of unparsed, but matched alert + // messages. We attempt to scale the number of unparsed messages + // based on the ratio of duplicate FIRS report numbers that appear + // in the parsed messages, to best predict and compensate for + // re-paged jobs, before they are added to the tally. + + // TODO: filter parsed messages based on page destination + + var date = new DateTime(DateTime.UtcNow.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc); + var matchedMessages = db.PagerMessages + .Where(m => m.Timestamp >= date) + .Where(m => Regex.IsMatch(m.Message, MessageFilter)); + var parsedMessages = matchedMessages + .Where(m => m.ParsedMessage != null) + .Select(m => m.ParsedMessage!); + + var matchedMessageCount = matchedMessages.Count(); + var parsedMessageCount = parsedMessages.Count(); + + var jobNumberCount = parsedMessages + .Select(pm => pm.FirecomJobNo) + .Distinct() + .Count(); + + double uniqueJobRate = + (double) jobNumberCount / (double) parsedMessageCount; + + // Scale the number of unparsed messages and add + // them to the tally of distinct FIRS job numbers + jobNumberCount += + (int) Math.Round((matchedMessageCount - parsedMessageCount) * uniqueJobRate); + + // Apply the manually-entered offset if needed + if(config.CountOffsets.TryGetValue(pageDestination, out int offset)) + jobNumberCount += offset; + + return jobNumberCount; + } + } + + public override void OnPageHandlerExecuting(PageHandlerExecutingContext context) => + pageDestination = (string) RouteData.Values["PageDestination"]!; + + private record JobCounterConfiguration { + public int? RefreshInterval { get; set; } = 300; + public Dictionary<string, int> CountOffsets { get; set; } = new(); + } +} diff --git a/Pages/JobCounter/Index.cshtml.css b/Pages/JobCounter/Index.cshtml.css new file mode 100644 index 0000000..5b191c1 --- /dev/null +++ b/Pages/JobCounter/Index.cshtml.css @@ -0,0 +1,14 @@ +div { + align-items: center; + display: flex; + flex-direction: column; + left: 50%; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); +} + +h1 { + font-family: 'Arial'; + font-size: 28pt; +} |
