Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2-beta2 => v2 #158

Merged
merged 23 commits into from
Feb 18, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
change event action
CubicrootXYZ committed Jan 28, 2024
commit 36f5ef08af423706d5fbf376d7461fda7733ca98
121 changes: 121 additions & 0 deletions internal/connectors/matrix/actions/message/change_event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package message

// TODO add tests!

import (
"regexp"

"github.com/CubicrootXYZ/gologger"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix"
matrixdb "github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/database"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/format"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/mautrixcl"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/messenger"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/msghelper"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/database"
)

var changeEventActionRegex = regexp.MustCompile("(?i)(^(change|update|set)[ ]+(reminder|reminder id|)[ ]*[0-9]+)")

// ChangeEventAction for changing an existing event.
type ChangeEventAction struct {
logger gologger.Logger
client mautrixcl.Client
messenger messenger.Messenger
matrixDB matrixdb.Service
db database.Service
storer *msghelper.Storer
}

// Configure is called on startup and sets all dependencies.
func (action *ChangeEventAction) Configure(logger gologger.Logger, client mautrixcl.Client, messenger messenger.Messenger, matrixDB matrixdb.Service, db database.Service, _ *matrix.BridgeServices) {
action.logger = logger
action.client = client
action.matrixDB = matrixDB
action.db = db
action.messenger = messenger
action.storer = msghelper.NewStorer(matrixDB, messenger, logger)
}

// Name of the action
func (action *ChangeEventAction) Name() string {
return "Change event"
}

func (action *ChangeEventAction) GetDocu() (title, explaination string, examples []string) {
return "Change event",
"Change an existing Event.",
[]string{"change reminder 1 to tomorrow", "update 68 to Saturday 4 pm"}
}

// Selector defines a regex on what messages the action should be used.
func (action *ChangeEventAction) Selector() *regexp.Regexp {
return changeEventActionRegex
}

// HandleEvent is where the message event get's send to if it matches the Selector.
func (action *ChangeEventAction) HandleEvent(event *matrix.MessageEvent) {
match := changeEventActionRegex.Find([]byte(event.Content.Body))
if match == nil {
go action.storer.SendAndStoreResponse(
"Ups, seems like there is a reminder ID missing in your message.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

eventID, err := format.GetSuffixInt(string(match))
if err != nil {
go action.storer.SendAndStoreResponse(
"Ups, seems like there is a reminder ID missing in your message.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

newTime, err := format.ParseTime(event.Content.Body, event.Room.TimeZone, false)
if err != nil {
go action.storer.SendAndStoreResponse(
"Ehm, sorry to say that, but I was not able to understand the time to schedule the reminder to.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

events, err := action.db.ListEvents(&database.ListEventsOpts{
IDs: []uint{uint(eventID)},
ChannelID: &event.Channel.ID,
})
if err != nil || len(events) == 0 {
go action.storer.SendAndStoreResponse(
"This reminder is not in my database.",
matrixdb.MessageTypeChangeEvent,
*event,
)
return
}

evt := &events[0]
evt.Time = newTime
evt, err = action.db.UpdateEvent(evt)
if err != nil || len(events) == 0 {
go action.storer.SendAndStoreResponse(
"Whups, this did not work, sorry.",
matrixdb.MessageTypeChangeEventError,
*event,
)
return
}

msgFormater := format.Formater{}
msgFormater.TextLine("I rescheduled your reminder")
msgFormater.QuoteLine(evt.Message)
msgFormater.Text("to ")
msgFormater.Text(format.ToLocalTime(newTime, event.Room.TimeZone))
msg, formattedMsg := msgFormater.Build()

go action.storer.SendAndStoreMessage(msg, formattedMsg, matrixdb.MessageTypeChangeEvent, *event)
}
1 change: 1 addition & 0 deletions internal/connectors/matrix/database/interface.go
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ var (
MessageTypeEventDelete = MatrixMessageType("EVENT_DELETE")
MessageTypeAddUser = MatrixMessageType("USER_ADD")
MessageTypeChangeEvent = MatrixMessageType("EVENT_CHANGE")
MessageTypeChangeEventError = MatrixMessageType("EVENT_CHANGE_ERROR")
MessageTypeIcalExportEnable = MatrixMessageType("ICAL_ENABLE")
MessageTypeIcalRegenToken = MatrixMessageType("ICAL_REGEN")
MessageTypeEventList = MatrixMessageType("EVENT_LIST")
19 changes: 19 additions & 0 deletions internal/connectors/matrix/format/numbers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package format

import (
"errors"
"strconv"
"strings"
)

// GetSuffixInt returns a suffixed integer in the given string value
func GetSuffixInt(value string) (int, error) {
splitUp := strings.Split(value, " ")
if len(splitUp) == 0 {
return 0, errors.New("empty string does not contain integer")
}

integerString := splitUp[len(splitUp)-1]

return strconv.Atoi(integerString)
}
28 changes: 28 additions & 0 deletions internal/connectors/matrix/format/numbers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package format_test

import (
"testing"

"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/format"
"github.com/stretchr/testify/assert"
)

func Test_GetSuffixIntOnSuccess(t *testing.T) {
result, err := format.GetSuffixInt("Well, this is a very long sentencen: please add some more characters and an integer like 203")
assert.NoError(t, err)
assert.Equal(t, 203, result)
}

func Test_GetSuffixIntOnFailure(t *testing.T) {
t.Run("missing number", func(t *testing.T) {
result, err := format.GetSuffixInt("Well, this is a very long sentencen: please add some more characters and an integer like two hundred")
assert.Error(t, err)
assert.Equal(t, 0, result)
})

t.Run("empty string", func(t *testing.T) {
result, err := format.GetSuffixInt("")
assert.Error(t, err)
assert.Equal(t, 0, result)
})
}
1 change: 1 addition & 0 deletions internal/connectors/matrix/msghelper/send_and_store.go
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@ func (storer *Storer) SendAndStoreMessage(message, messageFormatted string, mess
// ResponseOpts defines a type for response options.
type ResponseOpts func(msg *matrixdb.MatrixMessage)

// TODO sometimes is called async, needs to be taken care of in shutdown!
// SendAndStoreResponse outsources response sending and storing. Call it asynchronous with "go SendAndStoreMessage(...)"
func (storer *Storer) SendAndStoreResponse(message string, messageType matrixdb.MatrixMessageType, event matrix.MessageEvent, opts ...ResponseOpts) {
resp, err := storer.messenger.SendResponse(messenger.PlainTextResponse(