diff --git a/pkg/processors/add_property.go b/pkg/processors/add_property.go new file mode 100644 index 0000000..6bf26c8 --- /dev/null +++ b/pkg/processors/add_property.go @@ -0,0 +1,52 @@ +package processors + +import ( + "github.com/akamensky/argparse" + "github.com/emersion/go-ical" + "strings" +) + +type AddPropertyProcessor struct { + propertyName *string + propertyValue *string + overwrite *bool + toolbox Toolbox +} + +func (a *AddPropertyProcessor) Initialize(parser *argparse.Parser) (*argparse.Command, error) { + c := parser.NewCommand("addProperty", "Adds a new property to each selected event") + a.propertyName = c.String("N", "name", &argparse.Options{ + Help: "Name of the new property", + Required: true, + }) + a.propertyValue = c.String("V", "value", &argparse.Options{ + Help: "Value of the new property (only text values allowed)", + Required: true, + }) + a.overwrite = c.Flag("O", "overwrite", &argparse.Options{ + Help: "Overwrite property if it exists", + Required: false, + Default: true, + }) + return c, nil +} + +func (a *AddPropertyProcessor) SetToolbox(toolbox Toolbox) { + a.toolbox = toolbox +} + +func (a *AddPropertyProcessor) Process(input ical.Calendar, output *ical.Calendar) error { + n := strings.ToUpper(*a.propertyName) + for _, event := range input.Events() { + if a.toolbox.EventMatchesSelector(event) { + if event.Props.Get(n) != nil && *a.overwrite { + event.Props.Del(n) + } + if event.Props.Get(n) == nil { + event.Props.SetText(n, *a.propertyValue) + } + } + output.Children = append(output.Children, event.Component) + } + return nil +} diff --git a/pkg/processors/add_property_test.go b/pkg/processors/add_property_test.go new file mode 100644 index 0000000..1ee3f24 --- /dev/null +++ b/pkg/processors/add_property_test.go @@ -0,0 +1,64 @@ +package processors + +import ( + "github.com/emersion/go-ical" + "github.com/stretchr/testify/assert" + "icarus/internal" + "testing" +) + +func TestAddPropertyProcessor_Process(t *testing.T) { + event1 := ical.NewEvent() + event1.Props.SetText(ical.PropSummary, "test") + input := ical.NewCalendar() + input.Children = append(input.Children, event1.Component) + subject := AddPropertyProcessor{} + subject.SetToolbox(NewToolbox()) + subject.propertyName = internal.StringAddr("X-TEST") + subject.propertyValue = internal.StringAddr("test") + subject.overwrite = internal.BoolAddr(false) + output := ical.NewCalendar() + err := subject.Process(*input, output) + assert.NoError(t, err, "Process got an error") + assert.Len(t, output.Children, 1, "Invalid number of events") + assert.NotNil(t, output.Children[0].Props.Get("X-TEST"), "Test property does not exists") + assert.Equal(t, "test", output.Children[0].Props.Get("X-TEST").Value, "Test property has wrong value") +} + +func TestAddPropertyProcessor_NotOverwrite(t *testing.T) { + event1 := ical.NewEvent() + event1.Props.SetText(ical.PropSummary, "test") + event1.Props.SetText("X-TEST", "test") + input := ical.NewCalendar() + input.Children = append(input.Children, event1.Component) + subject := AddPropertyProcessor{} + subject.SetToolbox(NewToolbox()) + subject.propertyName = internal.StringAddr("X-TEST") + subject.propertyValue = internal.StringAddr("test2") + subject.overwrite = internal.BoolAddr(false) + output := ical.NewCalendar() + err := subject.Process(*input, output) + assert.NoError(t, err, "Process got an error") + assert.Len(t, output.Children, 1, "Invalid number of events") + assert.NotNil(t, output.Children[0].Props.Get("X-TEST"), "Test property does not exists") + assert.Equal(t, "test", output.Children[0].Props.Get("X-TEST").Value, "Test property has wrong value") +} + +func TestAddPropertyProcessor_Overwrite(t *testing.T) { + event1 := ical.NewEvent() + event1.Props.SetText(ical.PropSummary, "test") + event1.Props.SetText("X-TEST", "test") + input := ical.NewCalendar() + input.Children = append(input.Children, event1.Component) + subject := AddPropertyProcessor{} + subject.SetToolbox(NewToolbox()) + subject.propertyName = internal.StringAddr("X-TEST") + subject.propertyValue = internal.StringAddr("test2") + subject.overwrite = internal.BoolAddr(true) + output := ical.NewCalendar() + err := subject.Process(*input, output) + assert.NoError(t, err, "Process got an error") + assert.Len(t, output.Children, 1, "Invalid number of events") + assert.NotNil(t, output.Children[0].Props.Get("X-TEST"), "Test property does not exists") + assert.Equal(t, "test2", output.Children[0].Props.Get("X-TEST").Value, "Test property has wrong value") +} diff --git a/pkg/processors/delete_property.go b/pkg/processors/delete_property.go new file mode 100644 index 0000000..617d013 --- /dev/null +++ b/pkg/processors/delete_property.go @@ -0,0 +1,37 @@ +package processors + +import ( + "github.com/akamensky/argparse" + "github.com/emersion/go-ical" + "strings" +) + +type DeletePropertyProcessor struct { + propertyName *string + toolbox Toolbox +} + +func (d *DeletePropertyProcessor) Initialize(parser *argparse.Parser) (*argparse.Command, error) { + c := parser.NewCommand("deleteProperty", "Deletes a property from all selected events") + d.propertyName = c.String("P", "property", &argparse.Options{ + Help: "Property to delete (e.g. X-SPECIAL-PROP, CATEGORIES)", + Required: true, + }) + return c, nil +} + +func (d *DeletePropertyProcessor) SetToolbox(toolbox Toolbox) { + d.toolbox = toolbox +} + +func (d *DeletePropertyProcessor) Process(input ical.Calendar, output *ical.Calendar) error { + for _, event := range input.Events() { + if d.toolbox.EventMatchesSelector(event) { + if event.Props.Get(strings.ToUpper(*d.propertyName)) != nil { + event.Props.Del(strings.ToUpper(*d.propertyName)) + } + } + output.Children = append(output.Children, event.Component) + } + return nil +} diff --git a/pkg/processors/delete_property_test.go b/pkg/processors/delete_property_test.go new file mode 100644 index 0000000..e3d3389 --- /dev/null +++ b/pkg/processors/delete_property_test.go @@ -0,0 +1,25 @@ +package processors + +import ( + "github.com/emersion/go-ical" + "github.com/stretchr/testify/assert" + "icarus/internal" + "testing" +) + +func TestDeleteFieldProcessor_Process(t *testing.T) { + event1 := ical.NewEvent() + event1.Props.SetText(ical.PropSummary, "test") + event1.Props.SetText("X-TEST", "test") + assert.NotNil(t, event1.Props.Get("X-TEST"), "Test property was not set") + input := ical.NewCalendar() + input.Children = append(input.Children, event1.Component) + subject := DeletePropertyProcessor{} + subject.SetToolbox(NewToolbox()) + subject.propertyName = internal.StringAddr("X-TEST") + output := ical.NewCalendar() + err := subject.Process(*input, output) + assert.NoError(t, err, "Process got an error") + assert.Len(t, output.Children, 1, "Invalid number of events") + assert.Nil(t, output.Children[0].Props.Get("X-TEST"), "Test property still exists") +} diff --git a/pkg/processors/processors.go b/pkg/processors/processors.go index 7a03224..04ff0c2 100644 --- a/pkg/processors/processors.go +++ b/pkg/processors/processors.go @@ -22,5 +22,7 @@ func GetProcessors() []BaseProcessor { &ConvertAllDayProcessor{}, &AddDTStampProcessor{}, &AddAlarmProcessor{}, + &AddPropertyProcessor{}, + &DeletePropertyProcessor{}, } }