diff --git a/internal/domain/pln.go b/internal/domain/pln.go index f96aa21..285284c 100644 --- a/internal/domain/pln.go +++ b/internal/domain/pln.go @@ -3,13 +3,15 @@ package domain import "fmt" type FlightSchedule struct { + Index string `json:"index,omitempty"` + // Date of the flight schedule. // Example: "30OCT" Date string `json:"date"` // Category of the flight schedule. It could represent different categories based on the airline or flight type. // Example: "H/G" - Category string `json:"category,omitempty"` + Task string `json:"task,omitempty"` // Flight number of the flight schedule. This is a unique identifier for the flight. // Example: "CA1014" diff --git a/internal/parsers/aviation_parser.go b/internal/parsers/aviation_parser.go index f5d4772..c70224f 100644 --- a/internal/parsers/aviation_parser.go +++ b/internal/parsers/aviation_parser.go @@ -51,6 +51,7 @@ const ( PerformanceCategory = "per" RerouteInformation = "rif" Remarks = "remark" + Index = "idx" ) var ( @@ -105,8 +106,11 @@ func (bp *BodyParser) Parse() (string, interface{}, error) { if patternConfig, exists := bp.bodyPatterns[category]; exists && patternConfig.Patterns != nil { for _, p := range patternConfig.Patterns { - if match := p.Expression.FindStringSubmatch(bp.body); match != nil { - data := extractData(match, p.Expression) + // if match := p.Expression.FindStringSubmatch(bp.body); match != nil { + // data := extractData(match, p.Expression) + // return bp.createBodyData(data) + // } + if data := parse(bp.body, p.Expression); data != nil { return bp.createBodyData(data) } } @@ -125,6 +129,14 @@ func findCategory(body string) string { return "" } +func parse(data string, exp *regexp.Regexp) map[string]string { + match := exp.FindStringSubmatch(data) + if len(match) > 0 { + return extractData(match, exp) + } + return nil +} + func extractData(match []string, re *regexp.Regexp) map[string]string { data := make(map[string]string) for i, name := range re.SubexpNames() { diff --git a/internal/parsers/schedule_parser.go b/internal/parsers/schedule_parser.go index 919a03d..c594c92 100644 --- a/internal/parsers/schedule_parser.go +++ b/internal/parsers/schedule_parser.go @@ -1,17 +1,41 @@ package parsers -import "regexp" +import ( + "caatsm/internal/domain" + "regexp" + "strings" +) const ( // DepartureCode = "dep" // DepartureTime = "dep_time" // ArrivalCode = "arr" - AirportCode = "airport" - WaypointPattern = `(?P\d{4}(\(\d{2}\w{3}\))?)(?P\w{3})\/?(?P\d{4}(\(\d{2}\w{3}\))?)` + AirportCode = "airport" + Date = "date" + Task = "task" + IndexPattern = `(?P\(?L?\d+\)?\.?)` + DatePattern = `\s?(?P\d{2}\w{3})` + TaskPattern = `\s?(?P[A-Z]\/[A-Z])` + WaypointPattern = `\s?(?P\d{4}(\(\d{2}\w{3}\))?)\/?(?P\w{3})\/?(?P\d{4}(\(\d{2}\w{3}\))?)` + FlightNumberPattern = `\s?(?P[0-9A-Z][A-Z]\d{3,5})` + RegisterPattern = `\s?(?PB\d{4})` ) var ( - WaypointExpression = regexp.MustCompile(WaypointPattern) + IndexExpression = regexp.MustCompile(IndexPattern) + TaskExpression = regexp.MustCompile(TaskPattern) + DateExpression = regexp.MustCompile(DatePattern) + WaypointExpression = regexp.MustCompile(WaypointPattern) + FlightNumberExpression = regexp.MustCompile(FlightNumberPattern) + RegisterExpression = regexp.MustCompile(RegisterPattern) + + parserMap = map[string]*regexp.Regexp{ + Index: IndexExpression, + Task: TaskExpression, + Date: DateExpression, + FlightNumber: FlightNumberExpression, + Register: RegisterExpression, + } ) func FindWaypoints(message string) map[string]string { @@ -29,3 +53,53 @@ func FindWaypoints(message string) map[string]string { return result } + +func ParseLine(line string) *domain.FlightSchedule { + cleanLine := strings.TrimSpace(line) + words := strings.Split(cleanLine, " ") + var flightSchedule = &domain.FlightSchedule{} + // var err error + var data map[string]string + + // Define the parsing strategy + parseStrategy := []string{ + Index, + Task, + Date, + FlightNumber, + Register, + } + + // Track parsed fields to avoid re-parsing + parsed := make(map[string]bool) + + for i, word := range words { + if i > 0 { + parsed[Index] = true + } + for _, name := range parseStrategy { + if parsed[name] { + continue + } + if data = parse(word, parserMap[name]); data != nil { + + switch name { + case Index: + flightSchedule.Index = data[Index] + case Task: + flightSchedule.Task = data[Task] + case Date: + flightSchedule.Date = data[Date] + case FlightNumber: + flightSchedule.FlightNumber = data[FlightNumber] + case Register: + flightSchedule.AircraftReg = data[Register] + } + parsed[name] = true + break + } + } + } + + return flightSchedule +} diff --git a/internal/parsers/schedule_parser_test.go b/internal/parsers/schedule_parser_test.go index 5a7946f..2db8531 100644 --- a/internal/parsers/schedule_parser_test.go +++ b/internal/parsers/schedule_parser_test.go @@ -23,4 +23,25 @@ var _ = Describe("Schedule Parser", func() { Expect(waypoints).To(BeNil()) }) }) + + Describe("Parsing one line of schedule", func() { + Context("parse : W/Z FM9134 B2688 1/1ILS (00) TSN0100 SHA", func() { + lineText := "W/Z FM9134 B2688 1/1ILS (00) TSN0100 SHA" + schedule := ParseLine(lineText) + It("should return a valid schedule", func() { + Expect(schedule).NotTo(BeNil()) + Expect(schedule.Task).To(Equal("W/Z")) + // Expect(schedule.Date).To(Equal("TSN0100")) + // Expect(schedule.Task).To(Equal("1/1")) + Expect(schedule.FlightNumber).To(Equal("FM9134")) + Expect(schedule.AircraftReg).To(Equal("B2688")) + // Expect(schedule.PassengerConfig).To(Equal("1/1")) + // Expect(schedule.ILS).To(Equal("ILS (00)")) + // Expect(schedule.DepartureAirport).To(Equal("TSN")) + // Expect(schedule.DepartureTime).To(Equal("0100")) + // Expect(schedule.ScheduleInfo).To(Equal("SHA")) + }) + + }) + }) })