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 CountOffsets { get; set; } = new(); } }