refactor to mautrix 0.17.x; update deps

This commit is contained in:
Aine
2024-02-11 20:47:04 +02:00
parent 0a9701f4c9
commit dd0ad4c245
237 changed files with 9091 additions and 3317 deletions

View File

@@ -1,13 +1,14 @@
package linkpearl
import (
"context"
"strings"
"maunium.net/go/mautrix/id"
)
// GetAccountData of the user (from cache and API, with encryption support)
func (l *Linkpearl) GetAccountData(name string) (map[string]string, error) {
func (l *Linkpearl) GetAccountData(ctx context.Context, name string) (map[string]string, error) {
cached, ok := l.acc.Get(name)
if ok {
if cached == nil {
@@ -17,7 +18,7 @@ func (l *Linkpearl) GetAccountData(name string) (map[string]string, error) {
}
var data map[string]string
err := l.GetClient().GetAccountData(name, &data)
err := l.GetClient().GetAccountData(ctx, name, &data)
if err != nil {
data = map[string]string{}
if strings.Contains(err.Error(), "M_NOT_FOUND") {
@@ -33,15 +34,15 @@ func (l *Linkpearl) GetAccountData(name string) (map[string]string, error) {
}
// SetAccountData of the user (to cache and API, with encryption support)
func (l *Linkpearl) SetAccountData(name string, data map[string]string) error {
func (l *Linkpearl) SetAccountData(ctx context.Context, name string, data map[string]string) error {
l.acc.Add(name, data)
data = l.encryptAccountData(data)
return UnwrapError(l.GetClient().SetAccountData(name, data))
return UnwrapError(l.GetClient().SetAccountData(ctx, name, data))
}
// GetRoomAccountData of the room (from cache and API, with encryption support)
func (l *Linkpearl) GetRoomAccountData(roomID id.RoomID, name string) (map[string]string, error) {
func (l *Linkpearl) GetRoomAccountData(ctx context.Context, roomID id.RoomID, name string) (map[string]string, error) {
key := roomID.String() + name
cached, ok := l.acc.Get(key)
if ok {
@@ -52,7 +53,7 @@ func (l *Linkpearl) GetRoomAccountData(roomID id.RoomID, name string) (map[strin
}
var data map[string]string
err := l.GetClient().GetRoomAccountData(roomID, name, &data)
err := l.GetClient().GetRoomAccountData(ctx, roomID, name, &data)
if err != nil {
data = map[string]string{}
if strings.Contains(err.Error(), "M_NOT_FOUND") {
@@ -68,12 +69,12 @@ func (l *Linkpearl) GetRoomAccountData(roomID id.RoomID, name string) (map[strin
}
// SetRoomAccountData of the room (to cache and API, with encryption support)
func (l *Linkpearl) SetRoomAccountData(roomID id.RoomID, name string, data map[string]string) error {
func (l *Linkpearl) SetRoomAccountData(ctx context.Context, roomID id.RoomID, name string, data map[string]string) error {
key := roomID.String() + name
l.acc.Add(key, data)
data = l.encryptAccountData(data)
return UnwrapError(l.GetClient().SetRoomAccountData(roomID, name, data))
return UnwrapError(l.GetClient().SetRoomAccountData(ctx, roomID, name, data))
}
func (l *Linkpearl) encryptAccountData(data map[string]string) map[string]string {

View File

@@ -1,6 +1,7 @@
package linkpearl
import (
"context"
"crypto/hmac"
"crypto/sha512"
"database/sql"
@@ -25,7 +26,7 @@ type Config struct {
// JoinPermit is a callback function that tells
// if linkpearl should respond to the given "invite" event
// and join the room
JoinPermit func(*event.Event) bool
JoinPermit func(context.Context, *event.Event) bool
// AutoLeave if true, linkpearl will automatically leave empty rooms
AutoLeave bool

View File

@@ -1,6 +1,7 @@
package linkpearl
import (
"context"
"strconv"
"maunium.net/go/mautrix"
@@ -15,7 +16,7 @@ type RespThreads struct {
}
// Threads endpoint, ref: https://spec.matrix.org/v1.8/client-server-api/#get_matrixclientv1roomsroomidthreads
func (l *Linkpearl) Threads(roomID id.RoomID, fromToken ...string) (*RespThreads, error) {
func (l *Linkpearl) Threads(ctx context.Context, roomID id.RoomID, fromToken ...string) (*RespThreads, error) {
var from string
if len(fromToken) > 0 {
from = fromToken[0]
@@ -28,18 +29,18 @@ func (l *Linkpearl) Threads(roomID id.RoomID, fromToken ...string) (*RespThreads
var resp *RespThreads
urlPath := l.GetClient().BuildURLWithQuery(mautrix.ClientURLPath{"v1", "rooms", roomID, "threads"}, query)
_, err := l.GetClient().MakeRequest("GET", urlPath, nil, &resp)
_, err := l.GetClient().MakeRequest(ctx, "GET", urlPath, nil, &resp)
return resp, UnwrapError(err)
}
// FindThreadBy tries to find thread message event by field and value
func (l *Linkpearl) FindThreadBy(roomID id.RoomID, field, value string, fromToken ...string) *event.Event {
func (l *Linkpearl) FindThreadBy(ctx context.Context, roomID id.RoomID, field, value string, fromToken ...string) *event.Event {
var from string
if len(fromToken) > 0 {
from = fromToken[0]
}
resp, err := l.Threads(roomID, from)
resp, err := l.Threads(ctx, roomID, from)
err = UnwrapError(err)
if err != nil {
l.log.Warn().Err(err).Str("roomID", roomID.String()).Msg("cannot get room threads")
@@ -47,7 +48,7 @@ func (l *Linkpearl) FindThreadBy(roomID id.RoomID, field, value string, fromToke
}
for _, msg := range resp.Chunk {
evt, contains := l.eventContains(msg, field, value)
evt, contains := l.eventContains(ctx, msg, field, value)
if contains {
return evt
}
@@ -57,17 +58,17 @@ func (l *Linkpearl) FindThreadBy(roomID id.RoomID, field, value string, fromToke
return nil
}
return l.FindThreadBy(roomID, field, value, resp.NextBatch)
return l.FindThreadBy(ctx, roomID, field, value, resp.NextBatch)
}
// FindEventBy tries to find message event by field and value
func (l *Linkpearl) FindEventBy(roomID id.RoomID, field, value string, fromToken ...string) *event.Event {
func (l *Linkpearl) FindEventBy(ctx context.Context, roomID id.RoomID, field, value string, fromToken ...string) *event.Event {
var from string
if len(fromToken) > 0 {
from = fromToken[0]
}
resp, err := l.GetClient().Messages(roomID, from, "", mautrix.DirectionBackward, nil, l.eventsLimit)
resp, err := l.GetClient().Messages(ctx, roomID, from, "", mautrix.DirectionBackward, nil, l.eventsLimit)
err = UnwrapError(err)
if err != nil {
l.log.Warn().Err(err).Str("roomID", roomID.String()).Msg("cannot get room events")
@@ -75,7 +76,7 @@ func (l *Linkpearl) FindEventBy(roomID id.RoomID, field, value string, fromToken
}
for _, msg := range resp.Chunk {
evt, contains := l.eventContains(msg, field, value)
evt, contains := l.eventContains(ctx, msg, field, value)
if contains {
return evt
}
@@ -85,13 +86,13 @@ func (l *Linkpearl) FindEventBy(roomID id.RoomID, field, value string, fromToken
return nil
}
return l.FindEventBy(roomID, field, value, resp.End)
return l.FindEventBy(ctx, roomID, field, value, resp.End)
}
func (l *Linkpearl) eventContains(evt *event.Event, field, value string) (*event.Event, bool) {
func (l *Linkpearl) eventContains(ctx context.Context, evt *event.Event, field, value string) (*event.Event, bool) {
if evt.Type == event.EventEncrypted {
ParseContent(evt, &l.log)
decrypted, err := l.GetClient().Crypto.Decrypt(evt)
decrypted, err := l.GetClient().Crypto.Decrypt(ctx, evt)
if err == nil {
evt = decrypted
}

View File

@@ -2,6 +2,7 @@
package linkpearl
import (
"context"
"database/sql"
lru "github.com/hashicorp/golang-lru/v2"
@@ -31,7 +32,7 @@ type Linkpearl struct {
log zerolog.Logger
api *mautrix.Client
joinPermit func(*event.Event) bool
joinPermit func(ctx context.Context, evt *event.Event) bool
autoleave bool
maxretries int
eventsLimit int
@@ -54,7 +55,7 @@ func setDefaults(cfg *Config) {
}
if cfg.JoinPermit == nil {
// By default, we approve all join requests
cfg.JoinPermit = func(*event.Event) bool { return true }
cfg.JoinPermit = func(_ context.Context, _ *event.Event) bool { return true }
}
}
@@ -103,7 +104,7 @@ func New(cfg *Config) (*Linkpearl, error) {
return nil, err
}
lp.ch.LoginAs = cfg.LoginAs()
if err = lp.ch.Init(); err != nil {
if err = lp.ch.Init(context.Background()); err != nil {
return nil, err
}
lp.api.Crypto = lp.ch
@@ -131,16 +132,16 @@ func (l *Linkpearl) GetAccountDataCrypter() *Crypter {
}
// SetPresence (own). See https://spec.matrix.org/v1.3/client-server-api/#put_matrixclientv3presenceuseridstatus
func (l *Linkpearl) SetPresence(presence event.Presence, message string) error {
func (l *Linkpearl) SetPresence(ctx context.Context, presence event.Presence, message string) error {
req := ReqPresence{Presence: presence, StatusMsg: message}
u := l.GetClient().BuildClientURL("v3", "presence", l.GetClient().UserID, "status")
_, err := l.GetClient().MakeRequest("PUT", u, req, nil)
_, err := l.GetClient().MakeRequest(ctx, "PUT", u, req, nil)
return err
}
// SetJoinPermit sets the the join permit callback function
func (l *Linkpearl) SetJoinPermit(value func(*event.Event) bool) {
func (l *Linkpearl) SetJoinPermit(value func(context.Context, *event.Event) bool) {
l.joinPermit = value
}
@@ -152,7 +153,7 @@ func (l *Linkpearl) Start(optionalStatusMsg ...string) error {
statusMsg = optionalStatusMsg[0]
}
err := l.SetPresence(event.PresenceOnline, statusMsg)
err := l.SetPresence(context.Background(), event.PresenceOnline, statusMsg)
if err != nil {
l.log.Error().Err(err).Msg("cannot set presence")
}
@@ -165,7 +166,7 @@ func (l *Linkpearl) Start(optionalStatusMsg ...string) error {
// Stop the client
func (l *Linkpearl) Stop() {
l.log.Debug().Msg("stopping the client")
if err := l.api.SetPresence(event.PresenceOffline); err != nil {
if err := l.api.SetPresence(context.Background(), event.PresenceOffline); err != nil {
l.log.Error().Err(err).Msg("cannot set presence")
}
l.api.StopSync()

View File

@@ -1,6 +1,8 @@
package linkpearl
import (
"context"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/format"
@@ -10,9 +12,9 @@ import (
// Send a message to the roomID and automatically try to encrypt it, if the destination room is encrypted
//
//nolint:unparam // it's public interface
func (l *Linkpearl) Send(roomID id.RoomID, content interface{}) (id.EventID, error) {
func (l *Linkpearl) Send(ctx context.Context, roomID id.RoomID, content interface{}) (id.EventID, error) {
l.log.Debug().Str("roomID", roomID.String()).Any("content", content).Msg("sending event")
resp, err := l.api.SendMessageEvent(roomID, event.EventMessage, content)
resp, err := l.api.SendMessageEvent(ctx, roomID, event.EventMessage, content)
if err != nil {
return "", UnwrapError(err)
}
@@ -20,7 +22,7 @@ func (l *Linkpearl) Send(roomID id.RoomID, content interface{}) (id.EventID, err
}
// SendNotice to a room with optional relations, markdown supported
func (l *Linkpearl) SendNotice(roomID id.RoomID, message string, relates ...*event.RelatesTo) {
func (l *Linkpearl) SendNotice(ctx context.Context, roomID id.RoomID, message string, relates ...*event.RelatesTo) {
var withRelatesTo bool
content := format.RenderMarkdown(message, true, true)
content.MsgType = event.MsgNotice
@@ -29,12 +31,12 @@ func (l *Linkpearl) SendNotice(roomID id.RoomID, message string, relates ...*eve
content.RelatesTo = relates[0]
}
_, err := l.Send(roomID, &content)
_, err := l.Send(ctx, roomID, &content)
if err != nil {
l.log.Error().Err(UnwrapError(err)).Str("roomID", roomID.String()).Str("retries", "1/2").Msg("cannot send a notice into the room")
if withRelatesTo {
content.RelatesTo = nil
_, err = l.Send(roomID, &content)
_, err = l.Send(ctx, roomID, &content)
if err != nil {
l.log.Error().Err(UnwrapError(err)).Str("roomID", roomID.String()).Str("retries", "2/2").Msg("cannot send a notice into the room even without relations")
}
@@ -43,13 +45,13 @@ func (l *Linkpearl) SendNotice(roomID id.RoomID, message string, relates ...*eve
}
// SendFile to a matrix room
func (l *Linkpearl) SendFile(roomID id.RoomID, req *mautrix.ReqUploadMedia, msgtype event.MessageType, relates ...*event.RelatesTo) error {
func (l *Linkpearl) SendFile(ctx context.Context, roomID id.RoomID, req *mautrix.ReqUploadMedia, msgtype event.MessageType, relates ...*event.RelatesTo) error {
var relation *event.RelatesTo
if len(relates) > 0 {
relation = relates[0]
}
resp, err := l.GetClient().UploadMedia(*req)
resp, err := l.GetClient().UploadMedia(ctx, *req)
if err != nil {
err = UnwrapError(err)
l.log.Error().Err(err).Str("file", req.FileName).Msg("cannot upload file")
@@ -62,13 +64,13 @@ func (l *Linkpearl) SendFile(roomID id.RoomID, req *mautrix.ReqUploadMedia, msgt
RelatesTo: relation,
}
_, err = l.Send(roomID, content)
_, err = l.Send(ctx, roomID, content)
err = UnwrapError(err)
if err != nil {
l.log.Error().Err(err).Str("roomID", roomID.String()).Str("retries", "1/2").Msg("cannot send file into the room")
if relation != nil {
content.RelatesTo = nil
_, err = l.Send(roomID, &content)
_, err = l.Send(ctx, roomID, &content)
err = UnwrapError(err)
if err != nil {
l.log.Error().Err(UnwrapError(err)).Str("roomID", roomID.String()).Str("retries", "2/2").Msg("cannot send file into the room even without relations")

View File

@@ -1,6 +1,7 @@
package linkpearl
import (
"context"
"strings"
"time"
@@ -28,54 +29,56 @@ func (l *Linkpearl) OnEvent(callback mautrix.EventHandler) {
func (l *Linkpearl) initSync() {
l.api.Syncer.(mautrix.ExtensibleSyncer).OnEventType(
event.StateEncryption,
func(source mautrix.EventSource, evt *event.Event) {
go l.onEncryption(source, evt)
func(ctx context.Context, evt *event.Event) {
go l.onEncryption(ctx, evt)
},
)
l.api.Syncer.(mautrix.ExtensibleSyncer).OnEventType(
event.StateMember,
func(source mautrix.EventSource, evt *event.Event) {
go l.onMembership(source, evt)
func(ctx context.Context, evt *event.Event) {
go l.onMembership(ctx, evt)
},
)
}
func (l *Linkpearl) onMembership(src mautrix.EventSource, evt *event.Event) {
l.ch.Machine().HandleMemberEvent(src, evt)
l.api.StateStore.SetMembership(evt.RoomID, id.UserID(evt.GetStateKey()), evt.Content.AsMember().Membership)
func (l *Linkpearl) onMembership(ctx context.Context, evt *event.Event) {
l.ch.Machine().HandleMemberEvent(ctx, evt)
if err := l.api.StateStore.SetMembership(ctx, evt.RoomID, id.UserID(evt.GetStateKey()), evt.Content.AsMember().Membership); err != nil {
l.log.Error().Err(err).Str("roomID", evt.RoomID.String()).Str("userID", evt.GetStateKey()).Msg("cannot set membership")
}
// potentially autoaccept invites
l.onInvite(evt)
l.onInvite(ctx, evt)
// autoleave empty rooms
l.onEmpty(evt)
l.onEmpty(ctx, evt)
}
func (l *Linkpearl) onInvite(evt *event.Event) {
func (l *Linkpearl) onInvite(ctx context.Context, evt *event.Event) {
userID := l.api.UserID.String()
invite := evt.Content.AsMember().Membership == event.MembershipInvite
if !invite || evt.GetStateKey() != userID {
return
}
if l.joinPermit(evt) {
l.tryJoin(evt.RoomID, 0)
if l.joinPermit(ctx, evt) {
l.tryJoin(ctx, evt.RoomID, 0)
return
}
l.tryLeave(evt.RoomID, 0)
l.tryLeave(ctx, evt.RoomID, 0)
}
// TODO: https://spec.matrix.org/v1.8/client-server-api/#post_matrixclientv3joinroomidoralias
// endpoint supports server_name param and tells "The servers to attempt to join the room through. One of the servers must be participating in the room.",
// meaning you can specify more than 1 server. It is not clear, what format should be used "example.com,example.org", or "example.com example.org", or whatever else.
// Moreover, it is not clear if the following values can be used together with that field: l.api.UserID.Homeserver() and evt.Sender.Homeserver()
func (l *Linkpearl) tryJoin(roomID id.RoomID, retry int) {
func (l *Linkpearl) tryJoin(ctx context.Context, roomID id.RoomID, retry int) {
if retry >= l.maxretries {
return
}
_, err := l.api.JoinRoom(roomID.String(), "", nil)
_, err := l.api.JoinRoom(ctx, roomID.String(), "", nil)
err = UnwrapError(err)
if err != nil {
l.log.Error().Err(err).Str("roomID", roomID.String()).Msg("cannot join room")
@@ -84,31 +87,31 @@ func (l *Linkpearl) tryJoin(roomID id.RoomID, retry int) {
}
time.Sleep(5 * time.Second)
l.log.Error().Err(err).Str("roomID", roomID.String()).Int("retry", retry+1).Msg("trying to join again")
l.tryJoin(roomID, retry+1)
l.tryJoin(ctx, roomID, retry+1)
}
}
func (l *Linkpearl) tryLeave(roomID id.RoomID, retry int) {
func (l *Linkpearl) tryLeave(ctx context.Context, roomID id.RoomID, retry int) {
if retry >= l.maxretries {
return
}
_, err := l.api.LeaveRoom(roomID)
_, err := l.api.LeaveRoom(ctx, roomID)
err = UnwrapError(err)
if err != nil {
l.log.Error().Err(err).Str("roomID", roomID.String()).Msg("cannot leave room")
time.Sleep(5 * time.Second)
l.log.Error().Err(err).Str("roomID", roomID.String()).Int("retry", retry+1).Msg("trying to leave again")
l.tryLeave(roomID, retry+1)
l.tryLeave(ctx, roomID, retry+1)
}
}
func (l *Linkpearl) onEmpty(evt *event.Event) {
func (l *Linkpearl) onEmpty(ctx context.Context, evt *event.Event) {
if !l.autoleave {
return
}
members, err := l.api.StateStore.GetRoomJoinedOrInvitedMembers(evt.RoomID)
members, err := l.api.StateStore.GetRoomJoinedOrInvitedMembers(ctx, evt.RoomID)
err = UnwrapError(err)
if err != nil {
l.log.Error().Err(err).Str("roomID", evt.RoomID.String()).Msg("cannot get joined or invited members")
@@ -119,9 +122,11 @@ func (l *Linkpearl) onEmpty(evt *event.Event) {
return
}
l.tryLeave(evt.RoomID, 0)
l.tryLeave(ctx, evt.RoomID, 0)
}
func (l *Linkpearl) onEncryption(_ mautrix.EventSource, evt *event.Event) {
l.api.StateStore.SetEncryptionEvent(evt.RoomID, evt.Content.AsEncryption())
func (l *Linkpearl) onEncryption(ctx context.Context, evt *event.Event) {
if err := l.api.StateStore.SetEncryptionEvent(ctx, evt.RoomID, evt.Content.AsEncryption()); err != nil {
l.log.Error().Err(err).Str("roomID", evt.RoomID.String()).Msg("cannot set encryption event")
}
}