aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-02-21 15:57:53 +0100
committerAlex Auvolat <alex@adnab.me>2020-02-21 15:57:53 +0100
commitddd5936fb1f92432123a9a30d1d3a1fa644a4f8e (patch)
tree6a06aac9b5e676a2987f4bf612abea5500155ea2
parent92d380aa86dfd3e60f5b8d826ec96c0fbc17614a (diff)
downloadeasybridge-ddd5936fb1f92432123a9a30d1d3a1fa644a4f8e.tar.gz
easybridge-ddd5936fb1f92432123a9a30d1d3a1fa644a4f8e.zip
Files&images Mattermost->Matrix works
-rw-r--r--appservice/account.go39
-rw-r--r--appservice/server.go21
-rw-r--r--connector/connector.go10
-rw-r--r--connector/mattermost/mattermost.go24
-rw-r--r--connector/mediaobject.go85
-rw-r--r--go.mod6
-rw-r--r--go.sum12
-rw-r--r--mxlib/client.go6
-rw-r--r--mxlib/mediaobject.go7
9 files changed, 198 insertions, 12 deletions
diff --git a/appservice/account.go b/appservice/account.go
index 311f266..a2b95d7 100644
--- a/appservice/account.go
+++ b/appservice/account.go
@@ -249,6 +249,43 @@ func (a *Account) eventInternal(event *Event) error {
typ = "m.emote"
}
- return mx.SendMessageAs(mx_room_id, typ, event.Text, mx_user_id)
+ err = mx.SendMessageAs(mx_room_id, typ, event.Text, mx_user_id)
+ if err != nil {
+ return err
+ }
+
+ if event.Attachements != nil {
+ for _, file := range event.Attachements {
+ mxfile, err := mx.UploadMedia(file)
+ if err != nil {
+ return err
+ }
+ content := map[string]interface{} {
+ "body": mxfile.Filename(),
+ "filename": mxfile.Filename(),
+ "url": fmt.Sprintf("mxc://%s/%s", mxfile.MxcServer, mxfile.MxcMediaId),
+ }
+ if sz := mxfile.ImageSize(); sz != nil {
+ content["msgtype"] = "m.image"
+ content["info"] = map[string]interface{} {
+ "mimetype": mxfile.Mimetype(),
+ "size": mxfile.Size(),
+ "width": sz.Width,
+ "height": sz.Height,
+ }
+ } else {
+ content["msgtype"] = "m.file"
+ content["info"] = map[string]interface{} {
+ "mimetype": mxfile.Mimetype(),
+ "size": mxfile.Size(),
+ }
+ }
+ err = mx.SendAs(mx_room_id, "m.room.message", content, mx_user_id)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
}
}
diff --git a/appservice/server.go b/appservice/server.go
index 48e26a6..5a5cebe 100644
--- a/appservice/server.go
+++ b/appservice/server.go
@@ -41,15 +41,18 @@ func Start(r *mxlib.Registration, c *Config) (chan error, error) {
if mxe, ok := err.(*mxlib.MxError); !ok || mxe.ErrCode != "M_USER_IN_USE" {
return nil, err
}
- err = mx.ProfileDisplayname(ezbrMxId(), fmt.Sprintf("Easybridge (%s)", EASYBRIDGE_SYSTEM_PROTOCOL))
- if err != nil {
- return nil, err
- }
- err = mx.ProfileAvatar(ezbrMxId(), &connector.FileMediaObject{
- Path: "easybridge.jpg",
- })
- if err != nil {
- return nil, err
+ if err == nil {
+ // If Easybridge account was created, update avatar and display name
+ err = mx.ProfileAvatar(ezbrMxId(), &connector.FileMediaObject{
+ Path: "easybridge.jpg",
+ })
+ if err != nil {
+ return nil, err
+ }
+ err = mx.ProfileDisplayname(ezbrMxId(), fmt.Sprintf("Easybridge (%s)", EASYBRIDGE_SYSTEM_PROTOCOL))
+ if err != nil {
+ return nil, err
+ }
}
router := mux.NewRouter()
diff --git a/connector/connector.go b/connector/connector.go
index d05f4a2..2bf1704 100644
--- a/connector/connector.go
+++ b/connector/connector.go
@@ -115,7 +115,7 @@ type Event struct {
Text string
// Attached files such as images
- Attachements map[string]MediaObject
+ Attachements []MediaObject
}
type UserInfo struct {
@@ -134,6 +134,9 @@ type MediaObject interface {
Size() int64
Mimetype() string
+ // Returns the size of an image if it is an image, otherwise nil
+ ImageSize() *ImageSize
+
// Read: must always be implemented
Read() (io.ReadCloser, error)
@@ -141,3 +144,8 @@ type MediaObject interface {
// If so, Read() is the only way to retrieve the object
URL() string
}
+
+type ImageSize struct {
+ Width int
+ Height int
+}
diff --git a/connector/mattermost/mattermost.go b/connector/mattermost/mattermost.go
index 81adbde..330026a 100644
--- a/connector/mattermost/mattermost.go
+++ b/connector/mattermost/mattermost.go
@@ -345,6 +345,30 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
msg_ev.Type = EVENT_ACTION
}
+ // Handle files
+ if post.FileIds != nil && len(post.FileIds) > 0 {
+ msg_ev.Attachements = []MediaObject{}
+ for _, file := range post.Metadata.Files {
+ blob, resp := mm.conn.Client.GetFile(file.Id)
+ if resp.Error != nil {
+ return resp.Error
+ }
+ media_object := &BlobMediaObject{
+ ObjectFilename: file.Name,
+ ObjectSize: file.Size,
+ ObjectMimetype: file.MimeType,
+ ObjectData: blob,
+ }
+ if file.Width > 0 {
+ media_object.ObjectImageSize = &ImageSize{
+ Width: file.Width,
+ Height: file.Height,
+ }
+ }
+ msg_ev.Attachements = append(msg_ev.Attachements, media_object)
+ }
+ }
+
// Dispatch as PM or as room message
if len(strings.Split(channel_name, "__")) == 2 {
// Private message, no need to find room id
diff --git a/connector/mediaobject.go b/connector/mediaobject.go
index 75635ee..c6634b7 100644
--- a/connector/mediaobject.go
+++ b/connector/mediaobject.go
@@ -1,6 +1,7 @@
package connector
import (
+ "bytes"
"io"
"net/http"
"os"
@@ -41,6 +42,11 @@ func (m *FileMediaObject) Mimetype() string {
return http.DetectContentType(buffer)
}
+func (m *FileMediaObject) ImageSize() *ImageSize {
+ // TODO but not really usefull
+ return nil
+}
+
func (m *FileMediaObject) Read() (io.ReadCloser, error) {
return os.Open(m.Path)
}
@@ -48,3 +54,82 @@ func (m *FileMediaObject) Read() (io.ReadCloser, error) {
func (m *FileMediaObject) URL() string {
return ""
}
+
+// ----
+
+type UrlMediaObject struct {
+ ObjectFilename string
+ ObjectSize int64
+ ObjectMimetype string
+ ObjectURL string
+ ObjectImageSize *ImageSize
+}
+
+func (m *UrlMediaObject) Filename() string {
+ return m.ObjectFilename
+}
+
+func (m *UrlMediaObject) Size() int64 {
+ return m.ObjectSize
+}
+
+func (m *UrlMediaObject) Mimetype() string {
+ return m.ObjectMimetype
+}
+
+func (m *UrlMediaObject) ImageSize() *ImageSize {
+ return m.ObjectImageSize
+}
+
+func (m *UrlMediaObject) Read() (io.ReadCloser, error) {
+ resp, err := http.Get(m.ObjectURL)
+ if err != nil {
+ return nil, err
+ }
+ return resp.Body, nil
+}
+
+func (m *UrlMediaObject) URL() string {
+ return m.ObjectURL
+}
+
+// ----
+
+type BlobMediaObject struct {
+ ObjectFilename string
+ ObjectSize int64
+ ObjectMimetype string
+ ObjectImageSize *ImageSize
+ ObjectData []byte
+}
+
+func (m *BlobMediaObject) Filename() string {
+ return m.ObjectFilename
+}
+
+func (m *BlobMediaObject) Size() int64 {
+ return m.ObjectSize
+}
+
+func (m *BlobMediaObject) Mimetype() string {
+ return m.ObjectMimetype
+}
+
+func (m *BlobMediaObject) ImageSize() *ImageSize {
+ return m.ObjectImageSize
+}
+
+func (m *BlobMediaObject) Read() (io.ReadCloser, error) {
+ return nullCloseReader{bytes.NewBuffer(m.ObjectData)}, nil
+}
+
+func (m *BlobMediaObject) URL() string {
+ return ""
+}
+
+type nullCloseReader struct {
+ io.Reader
+}
+func (ncr nullCloseReader) Close() error {
+ return nil
+}
diff --git a/go.mod b/go.mod
index 1e54bf0..d7fdba8 100644
--- a/go.mod
+++ b/go.mod
@@ -4,12 +4,16 @@ go 1.13
require (
github.com/42wim/matterbridge v1.16.5
+ github.com/blang/semver v3.5.1+incompatible // indirect
+ github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8 // indirect
+ github.com/go-ldap/ldap v3.0.3+incompatible // indirect
github.com/gorilla/mux v1.7.4
github.com/jinzhu/gorm v1.9.12
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
- github.com/mattermost/mattermost-server v5.5.0+incompatible
+ github.com/mattermost/mattermost-server v5.11.1+incompatible
github.com/mattn/go-xmpp v0.0.0-20200128155807-a86b6abcb3ad
github.com/sirupsen/logrus v1.4.2
+ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/yaml.v2 v2.2.8
)
diff --git a/go.sum b/go.sum
index f157a34..22f0e27 100644
--- a/go.sum
+++ b/go.sum
@@ -20,6 +20,8 @@ github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
+github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bwmarrin/discordgo v0.20.2/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -35,10 +37,14 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xb
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec/go.mod h1:UGa5M2Sz/Uh13AMse4+RELKCDw7kqgqlTjeGae+7vUY=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8 h1:6muCmMJat6z7qptVrIf/+OWPxsjAfvhw5/6t+FwEkgg=
+github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8/go.mod h1:nYia/MIs9OyvXXYboPmNOj0gVWo97Wx0sde+ZuKkoM4=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk=
+github.com/go-ldap/ldap v3.0.3+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
@@ -116,6 +122,8 @@ github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU=
github.com/mattermost/mattermost-server v5.5.0+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
+github.com/mattermost/mattermost-server v5.11.1+incompatible h1:LPzKY0+2Tic/ik67qIg6VrydRCgxNXZQXOeaiJ2rMBY=
+github.com/mattermost/mattermost-server v5.11.1+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@@ -225,6 +233,7 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -246,6 +255,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -260,6 +270,8 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
+gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
diff --git a/mxlib/client.go b/mxlib/client.go
index 6d87663..d8237d1 100644
--- a/mxlib/client.go
+++ b/mxlib/client.go
@@ -280,6 +280,11 @@ func (mx *Client) RoomTopicAs(room string, topic string, as_user string) error {
}
func (mx *Client) UploadMedia(m connector.MediaObject) (*MediaObject, error) {
+ // Return early if this is already a Matrix media object
+ if mxm, ok := m.(*MediaObject); ok {
+ return mxm, nil
+ }
+
reader, err := m.Read()
if err != nil {
return nil, err
@@ -308,6 +313,7 @@ func (mx *Client) UploadMedia(m connector.MediaObject) (*MediaObject, error) {
filename: m.Filename(),
size: m.Size(),
mimetype: m.Mimetype(),
+ imageSize: m.ImageSize(),
MxcServer: mxc[0],
MxcMediaId: mxc[1],
}
diff --git a/mxlib/mediaobject.go b/mxlib/mediaobject.go
index 8a730d2..1c35187 100644
--- a/mxlib/mediaobject.go
+++ b/mxlib/mediaobject.go
@@ -5,6 +5,8 @@ import (
"fmt"
"net/url"
"net/http"
+
+ "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
)
type MediaObject struct {
@@ -12,6 +14,7 @@ type MediaObject struct {
filename string
size int64
mimetype string
+ imageSize *connector.ImageSize
MxcServer string
MxcMediaId string
}
@@ -28,6 +31,10 @@ func (m *MediaObject) Mimetype() string {
return m.mimetype
}
+func (m *MediaObject) ImageSize() *connector.ImageSize {
+ return m.imageSize
+}
+
func (m *MediaObject) Read() (io.ReadCloser, error) {
req, err := http.NewRequest("GET", m.URL(), nil)
if err != nil {