From 2d3b29176f4001e57dbeefae13a017e4079b0473 Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Tue, 6 Jan 2026 23:08:42 -0500 Subject: [PATCH] Enhance event occurrence parsing with detailed issue reporting and location configuration This commit introduces a new structure for handling parsing issues in the EventOccurrenceParser, allowing for detailed reporting of parsing problems such as unmatched lines, missing event definitions, and parsing failures for time, date, and location. A new ParsingIssue class has been added to encapsulate these details. Additionally, a LocationParsingConfiguration class has been implemented to support customizable location patterns, enhancing the flexibility of the parser. The EventOccurrenceParserService has been updated to utilize this configuration, and new tests have been added to ensure robust issue detection and reporting. Furthermore, the UI has been updated to display parsing issues, improving user feedback during the import process. --- Core/Core.csproj | 3 + Core/Models/EventOccurrenceParseResult.cs | 67 +++ Core/Models/LocationParsingConfiguration.cs | 31 ++ Core/Parsers/EventOccurrenceParser.cs | 230 +++++++-- Core/Services/EventOccurrenceParserService.cs | 31 +- .../EventOccurrenceParserIssues_Tests.cs | 474 ++++++++++++++++++ .../EventOccurrenceParserTestHelpers.cs | 58 +++ Tests/Parsers/EventOccurrenceParser_Tests.cs | 10 +- .../Components/Features/Calendar/Import.razor | 65 ++- .../Calendar/LocationParsingSettings.razor | 233 +++++++++ WebApp/Program.cs | 12 +- WebApp/appsettings.json | 15 + 12 files changed, 1189 insertions(+), 40 deletions(-) create mode 100644 Core/Models/LocationParsingConfiguration.cs create mode 100644 Tests/Parsers/EventOccurrenceParserIssues_Tests.cs create mode 100644 Tests/Parsers/EventOccurrenceParserTestHelpers.cs create mode 100644 WebApp/Components/Features/Calendar/LocationParsingSettings.razor diff --git a/Core/Core.csproj b/Core/Core.csproj index 66a477a..12f20cd 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -10,5 +10,8 @@ + + + \ No newline at end of file diff --git a/Core/Models/EventOccurrenceParseResult.cs b/Core/Models/EventOccurrenceParseResult.cs index f8661e2..4ebbbd2 100644 --- a/Core/Models/EventOccurrenceParseResult.cs +++ b/Core/Models/EventOccurrenceParseResult.cs @@ -25,6 +25,11 @@ public class EventOccurrenceParseResult /// public List Warnings { get; set; } = new(); + /// + /// List of detailed parsing issues with line numbers and specific problem descriptions. + /// + public List Issues { get; set; } = new(); + /// /// Total number of event occurrences successfully parsed. /// @@ -36,3 +41,65 @@ public class EventOccurrenceParseResult public bool IsSuccess => Errors.Count == 0; } +/// +/// Represents a detailed parsing issue encountered during event occurrence parsing. +/// +public class ParsingIssue +{ + /// + /// The line number where the issue occurred (1-based). + /// + public int LineNumber { get; set; } + + /// + /// The actual line content where the issue occurred. + /// + public string LineContent { get; set; } = string.Empty; + + /// + /// The type of parsing issue. + /// + public ParsingIssueType IssueType { get; set; } + + /// + /// Human-readable description of the issue. + /// + public string Message { get; set; } = string.Empty; +} + +/// +/// Types of parsing issues that can occur during event occurrence parsing. +/// +public enum ParsingIssueType +{ + /// + /// Line doesn't match the expected format pattern. + /// + UnmatchedLine, + + /// + /// Line matches format but event definition cannot be determined. + /// + MissingEventDefinition, + + /// + /// Time parsing failed (regex doesn't match or parse errors). + /// + TimeParseFailure, + + /// + /// Date parsing failed (invalid day of month, etc.). + /// + DateParseFailure, + + /// + /// Invalid format or other parsing issue. + /// + InvalidFormat, + + /// + /// Location parsing failed (no matching pattern found). + /// + LocationParseFailure +} + diff --git a/Core/Models/LocationParsingConfiguration.cs b/Core/Models/LocationParsingConfiguration.cs new file mode 100644 index 0000000..7f7b20e --- /dev/null +++ b/Core/Models/LocationParsingConfiguration.cs @@ -0,0 +1,31 @@ +namespace Core.Models; + +/// +/// Configuration for location parsing patterns used in event occurrence parsing. +/// Supports venue-specific room naming conventions. +/// +public class LocationParsingConfiguration +{ + /// + /// List of location prefix patterns (e.g., ["Room *", "Hall *", "Conference Room *"]). + /// Patterns use "*" as wildcard to match any text after the prefix. + /// + public List LocationPatterns { get; set; } = new(); + + /// + /// Default location parsing configuration with common patterns. + /// + public static LocationParsingConfiguration Default => new() + { + LocationPatterns = new List + { + "Room *", + "Hall *", + "Conference Room *", + "Building *", + "Auditorium *" + } + }; +} + + diff --git a/Core/Parsers/EventOccurrenceParser.cs b/Core/Parsers/EventOccurrenceParser.cs index 111eaba..9f9a2cc 100644 --- a/Core/Parsers/EventOccurrenceParser.cs +++ b/Core/Parsers/EventOccurrenceParser.cs @@ -1,18 +1,30 @@ using System.Text.RegularExpressions; using Core.Entities; +using Core.Models; using FuzzySharp; namespace Core.Parsers; +/// +/// Result of parsing event occurrence file, containing both occurrences and parsing issues. +/// +public class EventOccurrenceParserResult +{ + public IDictionary> Occurrences { get; set; } = new Dictionary>(); + public List Issues { get; set; } = new(); +} + public class EventOccurrenceParser { private FileSystemInfo _txtFile; private ICollection _events; + private LocationParsingConfiguration? _locationConfig; - public EventOccurrenceParser(FileSystemInfo txtFile, ICollection events) + public EventOccurrenceParser(FileSystemInfo txtFile, ICollection events, LocationParsingConfiguration? locationConfig = null) { _events = events; _txtFile = txtFile; + _locationConfig = locationConfig; } private Regex _re = @@ -26,40 +38,74 @@ public class EventOccurrenceParser private readonly Regex _timeRe = new(@"(?\d{1,2}):?(?\d{2})?\s?(?(?:a|p)\.?m\.?)"); - private readonly Regex _timeLocationRegex = new(@"(?