From dc1026ab090416af784aaf442b8f919063c20c7c Mon Sep 17 00:00:00 2001 From: Matthew Grove Date: Sun, 25 Aug 2024 20:42:05 +0100 Subject: [PATCH 1/5] [FEAT] Allow matching empty/nil event Description and Location --- calendar.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/calendar.go b/calendar.go index 3d4dfa1..219b39f 100644 --- a/calendar.go +++ b/calendar.go @@ -142,10 +142,13 @@ func (filter Filter) matchesEvent(event ics.VEvent) bool { if filter.Match.Description.hasConditions() { eventDescription := event.GetProperty(ics.ComponentPropertyDescription) if eventDescription == nil { - slog.Debug("Event has no Description so cannot not match filter", "event_summary", eventSummary.Value, "filter", filter.Description) - return false // if VEvent has no description it cannot match filter + slog.Debug("Event has no Description, but continuing checking filters", "event_summary", eventSummary.Value, "filter", filter.Description) + eventDescriptionValue := "" + } else { + eventDescriptionValue := eventDescription.Value } - if !filter.Match.Description.matchesString(eventDescription.Value) { + + if !filter.Match.Description.matchesString(eventDescriptionValue) { slog.Debug("Event Description does not match filter conditions", "event_summary", eventSummary.Value, "filter", filter.Description) return false // event doesn't match } @@ -155,10 +158,12 @@ func (filter Filter) matchesEvent(event ics.VEvent) bool { if filter.Match.Location.hasConditions() { eventLocation := event.GetProperty(ics.ComponentPropertyLocation) if eventLocation == nil { - slog.Warn("Event has no Location so cannot match filter", "event_summary", eventSummary.Value, "filter", filter.Description) - return false // if VEvent has no location it cannot match filter + slog.Warn("Event has no Location, but continuing checking filters", "event_summary", eventSummary.Value, "filter", filter.Description) + eventLocationValue := "" + } else { + eventLocationValue := eventLocation.Value } - if !filter.Match.Location.matchesString(eventLocation.Value) { + if !filter.Match.Location.matchesString(eventLocationValue) { slog.Debug("Event Location does not match filter conditions", "event_summary", eventSummary.Value, "filter", filter.Description) return false // event doesn't match @@ -195,8 +200,13 @@ type EventMatchRules struct { Location StringMatchRule `yaml:"location"` } +type NullMatchRule struct { + Null bool `yaml:"empty"` +} + // StringMatchRule defines match rules for VEvent properties with string values type StringMatchRule struct { + NullMatchRule Contains string `yaml:"contains"` Prefix string `yaml:"prefix"` Suffix string `yaml:"suffix"` @@ -213,6 +223,10 @@ func (smr StringMatchRule) hasConditions() bool { // Returns true if a given string (data) matches ALL StringMatchRule conditions func (smr StringMatchRule) matchesString(data string) bool { + // check null if set and don't process further - this condition can only be met on its own + if smr.Null { + return data == "" + } // check contains if set if smr.Contains != "" { if data == "" || !strings.Contains(data, smr.Contains) { From 9408da406f4ce5e70727d25ee6b9ebc450c21d7c Mon Sep 17 00:00:00 2001 From: Matthew Grove Date: Sun, 25 Aug 2024 20:42:21 +0100 Subject: [PATCH 2/5] [DOCS] Add documentation for matching empty/nil event Description and Location --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 699beef..83e744c 100644 --- a/README.md +++ b/README.md @@ -113,11 +113,11 @@ calendars: match: summary: prefix: "Canceled: " - - description: "Remove optional events" + - description: "Remove events without descriptions" remove: true match: - summary: - prefix: "[Optional]" + description: + empty: true - description: "Remove public holidays" remove: true match: @@ -168,6 +168,7 @@ Each filter can specify match conditions against the following event properties: These match conditions are available for a string value: +* `empty` - if `true`, property must be absent or empty * `contains` - property must contain this value * `prefix` - property must start with this value * `suffix` - property must end with this value From cace852aaa2798b1f3b5268bf453bdbac560e38b Mon Sep 17 00:00:00 2001 From: Matthew Grove Date: Sun, 25 Aug 2024 20:56:23 +0100 Subject: [PATCH 3/5] Fix variable scopes for handling description & location values --- calendar.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/calendar.go b/calendar.go index 219b39f..24feb91 100644 --- a/calendar.go +++ b/calendar.go @@ -141,11 +141,12 @@ func (filter Filter) matchesEvent(event ics.VEvent) bool { // Check Description filters against VEvent if filter.Match.Description.hasConditions() { eventDescription := event.GetProperty(ics.ComponentPropertyDescription) + var eventDescriptionValue string if eventDescription == nil { slog.Debug("Event has no Description, but continuing checking filters", "event_summary", eventSummary.Value, "filter", filter.Description) - eventDescriptionValue := "" + eventDescriptionValue = "" } else { - eventDescriptionValue := eventDescription.Value + eventDescriptionValue = eventDescription.Value } if !filter.Match.Description.matchesString(eventDescriptionValue) { @@ -157,11 +158,12 @@ func (filter Filter) matchesEvent(event ics.VEvent) bool { // Check Description filters against VEvent if filter.Match.Location.hasConditions() { eventLocation := event.GetProperty(ics.ComponentPropertyLocation) + var eventLocationValue string if eventLocation == nil { slog.Warn("Event has no Location, but continuing checking filters", "event_summary", eventSummary.Value, "filter", filter.Description) - eventLocationValue := "" + eventLocationValue = "" } else { - eventLocationValue := eventLocation.Value + eventLocationValue = eventLocation.Value } if !filter.Match.Location.matchesString(eventLocationValue) { slog.Debug("Event Location does not match filter conditions", "event_summary", eventSummary.Value, "filter", filter.Description) From cd97da60e96012474ae4eabd6562c3ab238d4dee Mon Sep 17 00:00:00 2001 From: Matthew Grove Date: Sun, 25 Aug 2024 22:19:55 +0100 Subject: [PATCH 4/5] Fix string match rules for empty/nil values and ensure they get processed --- calendar.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/calendar.go b/calendar.go index 24feb91..9413465 100644 --- a/calendar.go +++ b/calendar.go @@ -154,7 +154,7 @@ func (filter Filter) matchesEvent(event ics.VEvent) bool { return false // event doesn't match } } - + // Check Description filters against VEvent if filter.Match.Location.hasConditions() { eventLocation := event.GetProperty(ics.ComponentPropertyLocation) @@ -202,13 +202,9 @@ type EventMatchRules struct { Location StringMatchRule `yaml:"location"` } -type NullMatchRule struct { - Null bool `yaml:"empty"` -} - // StringMatchRule defines match rules for VEvent properties with string values type StringMatchRule struct { - NullMatchRule + Null bool `yaml:"empty"` Contains string `yaml:"contains"` Prefix string `yaml:"prefix"` Suffix string `yaml:"suffix"` @@ -217,7 +213,8 @@ type StringMatchRule struct { // Returns true if StringMatchRule has any conditions func (smr StringMatchRule) hasConditions() bool { - return smr.Contains != "" || + return smr.Null || + smr.Contains != "" || smr.Prefix != "" || smr.Suffix != "" || smr.RegexMatch != "" From 1280c76532adc440b7e001d3e31a9ad6ebe73bd6 Mon Sep 17 00:00:00 2001 From: Matthew Grove Date: Sun, 25 Aug 2024 23:07:39 +0100 Subject: [PATCH 5/5] Remove unnecessary warnings when events have missing Description/Location fields --- calendar.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/calendar.go b/calendar.go index 9413465..edbf18b 100644 --- a/calendar.go +++ b/calendar.go @@ -143,7 +143,6 @@ func (filter Filter) matchesEvent(event ics.VEvent) bool { eventDescription := event.GetProperty(ics.ComponentPropertyDescription) var eventDescriptionValue string if eventDescription == nil { - slog.Debug("Event has no Description, but continuing checking filters", "event_summary", eventSummary.Value, "filter", filter.Description) eventDescriptionValue = "" } else { eventDescriptionValue = eventDescription.Value @@ -160,7 +159,6 @@ func (filter Filter) matchesEvent(event ics.VEvent) bool { eventLocation := event.GetProperty(ics.ComponentPropertyLocation) var eventLocationValue string if eventLocation == nil { - slog.Warn("Event has no Location, but continuing checking filters", "event_summary", eventSummary.Value, "filter", filter.Description) eventLocationValue = "" } else { eventLocationValue = eventLocation.Value