aboutsummaryrefslogtreecommitdiff
path: root/connector
diff options
context:
space:
mode:
Diffstat (limited to 'connector')
-rw-r--r--connector/connector.go2
-rw-r--r--connector/irc/irc.go14
-rw-r--r--connector/mattermost/mattermost.go146
-rw-r--r--connector/mediaobject.go3
-rw-r--r--connector/xmpp/xmpp.go13
5 files changed, 142 insertions, 36 deletions
diff --git a/connector/connector.go b/connector/connector.go
index 2bf1704..2235318 100644
--- a/connector/connector.go
+++ b/connector/connector.go
@@ -115,7 +115,7 @@ type Event struct {
Text string
// Attached files such as images
- Attachements []MediaObject
+ Attachments []MediaObject
}
type UserInfo struct {
diff --git a/connector/irc/irc.go b/connector/irc/irc.go
index 38aa79d..2ed3923 100644
--- a/connector/irc/irc.go
+++ b/connector/irc/irc.go
@@ -205,9 +205,17 @@ func (irc *IRC) Send(event *Event) error {
return fmt.Errorf("Invalid target")
}
- if event.Attachements != nil && len(event.Attachements) > 0 {
- // TODO find a way to send them using some hosing of some kind
- return fmt.Errorf("Attachements not supported on IRC")
+ if event.Attachments != nil && len(event.Attachments) > 0 {
+ for _, at := range event.Attachments {
+ url := at.URL()
+ if url == "" {
+ // TODO find a way to send them using some hosing of some kind
+ return fmt.Errorf("Attachment without URL sent to IRC")
+ } else {
+ irc.conn.Cmd.Message(dest, fmt.Sprintf("%s (%s, %dkb)",
+ url, at.Mimetype(), at.Size()/1024))
+ }
+ }
}
if event.Type == EVENT_MESSAGE {
diff --git a/connector/mattermost/mattermost.go b/connector/mattermost/mattermost.go
index 330026a..73ea66b 100644
--- a/connector/mattermost/mattermost.go
+++ b/connector/mattermost/mattermost.go
@@ -1,10 +1,12 @@
package mattermost
import (
+ "net/http"
"fmt"
_ "os"
"strings"
"time"
+ "io/ioutil"
"encoding/json"
"github.com/mattermost/mattermost-server/model"
@@ -210,9 +212,6 @@ func (mm *Mattermost) Leave(roomId RoomID) {
}
func (mm *Mattermost) Send(event *Event) error {
- // TODO: attachements
- // TODO: verify private messages work
-
post := &model.Post{
Message: event.Text,
}
@@ -248,8 +247,30 @@ func (mm *Mattermost) Send(event *Event) error {
return fmt.Errorf("Invalid target")
}
+ if event.Attachments != nil {
+ post.FileIds = []string{}
+ for _, file := range event.Attachments {
+ rdr, err := file.Read()
+ if err != nil {
+ return err
+ }
+ defer rdr.Close()
+ data, err := ioutil.ReadAll(rdr)
+ if err != nil {
+ return err
+ }
+ up_file, err := mm.conn.UploadFile(data, post.ChannelId, file.Filename())
+ if err != nil {
+ log.Warnf("UploadFile error: %s", err)
+ return err
+ }
+ post.FileIds = append(post.FileIds, up_file)
+ }
+ }
+
_, resp := mm.conn.Client.CreatePost(post)
if resp.Error != nil {
+ log.Warnf("CreatePost error: %s", resp.Error)
return resp.Error
}
return nil
@@ -277,16 +298,58 @@ func (mm *Mattermost) handleConnected() {
if len(strings.Split(ch.Name, "__")) == 2 {
continue // This is a DM channel
}
+
id := mm.reverseRoomId(ch.Id)
- chName := ch.DisplayName
- if teamName := mm.conn.GetTeamName(ch.TeamId); teamName != "" {
- chName = teamName + " / " + chName
- }
mm.handler.Joined(id)
- mm.handler.RoomInfoUpdated(id, UserID(""), &RoomInfo{
- Name: chName,
+
+ // Update room info
+ room_info := &RoomInfo{
+ Name: ch.DisplayName,
Topic: ch.Header,
- })
+ }
+ for _, t := range mm.conn.OtherTeams {
+ if t.Id == ch.TeamId {
+ if t.Team.DisplayName != "" {
+ room_info.Name = t.Team.DisplayName + " / " + room_info.Name
+ } else {
+ room_info.Name = t.Team.Name + " / " + room_info.Name
+ }
+ // TODO: cache last update time so we don't do this needlessly
+ if t.Team.LastTeamIconUpdate > 0 {
+ team_img, resp := mm.conn.Client.GetTeamIcon(t.Id, "")
+ if resp.Error == nil {
+ room_info.Picture = &BlobMediaObject{
+ ObjectFilename: t.Team.Name,
+ ObjectMimetype: http.DetectContentType(team_img),
+ ObjectData: team_img,
+ }
+ } else {
+ log.Warnf("Could not get team image: %s", resp.Error)
+ }
+ }
+ break
+ }
+ }
+ mm.handler.RoomInfoUpdated(id, UserID(""), room_info)
+
+ // Update member list
+ members, resp := mm.conn.Client.GetChannelMembers(ch.Id, 0, 1000, "")
+ if resp.Error == nil {
+ for _, mem := range *members {
+ if mem.UserId == mm.conn.User.Id {
+ continue
+ }
+ user := mm.conn.GetUser(mem.UserId)
+ if user != nil {
+ mm.ensureJoined(user, id)
+ mm.updateUserInfo(user)
+ } else {
+ log.Warnf("Could not find joined user: %s", mem.UserId)
+ }
+ }
+ } else {
+ log.Warnf("Could not get channel members: %s", resp.Error)
+ }
}
}
@@ -306,6 +369,45 @@ func (mm *Mattermost) handleLoop(msgCh chan *matterclient.Message, quitCh chan b
}
}
+func (mm *Mattermost) updateUserInfo(user *model.User) {
+ userId := UserID(fmt.Sprintf("%s@%s", user.Username, mm.server))
+ userDisp := user.GetDisplayName(model.SHOW_NICKNAME_FULLNAME)
+
+ if lastdn, ok := mm.userdisplaynamemap[userId]; !ok || lastdn != userDisp {
+ ui := &UserInfo{
+ DisplayName: userDisp,
+ }
+ if user.LastPictureUpdate > 0 {
+ // TODO: cache last update time so we don't do this needlessly
+ img, resp := mm.conn.Client.GetProfileImage(user.Id, "")
+ if resp.Error == nil {
+ ui.Avatar = &BlobMediaObject{
+ ObjectFilename: user.Username,
+ ObjectMimetype: http.DetectContentType(img),
+ ObjectData: img,
+ }
+ } else {
+ log.Warnf("Could not get profile picture: %s", resp.Error)
+ }
+ mm.handler.UserInfoUpdated(userId, ui)
+ mm.userdisplaynamemap[userId] = userDisp
+ }
+ }
+}
+
+func (mm *Mattermost) ensureJoined(user *model.User, roomId RoomID) {
+ userId := UserID(fmt.Sprintf("%s@%s", user.Username, mm.server))
+ cache_key := fmt.Sprintf("%s / %s", userId, roomId)
+ if _, ok := mm.sentjoinedmap[cache_key]; !ok {
+ mm.handler.Event(&Event{
+ Author: userId,
+ Room: roomId,
+ Type: EVENT_JOIN,
+ })
+ mm.sentjoinedmap[cache_key] = true
+ }
+}
+
func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
channel_name := msg.Data["channel_name"].(string)
post_str := msg.Data["post"].(string)
@@ -326,14 +428,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
return fmt.Errorf("Invalid user")
}
userId := UserID(fmt.Sprintf("%s@%s", user.Username, mm.server))
-
- userDisp := user.GetDisplayName(model.SHOW_NICKNAME_FULLNAME)
- if lastdn, ok := mm.userdisplaynamemap[userId]; !ok || lastdn != userDisp {
- mm.handler.UserInfoUpdated(userId, &UserInfo{
- DisplayName: userDisp,
- })
- mm.userdisplaynamemap[userId] = userDisp
- }
+ mm.updateUserInfo(user)
// Build message event
msg_ev := &Event{
@@ -347,7 +442,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
// Handle files
if post.FileIds != nil && len(post.FileIds) > 0 {
- msg_ev.Attachements = []MediaObject{}
+ msg_ev.Attachments = []MediaObject{}
for _, file := range post.Metadata.Files {
blob, resp := mm.conn.Client.GetFile(file.Id)
if resp.Error != nil {
@@ -355,7 +450,6 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
}
media_object := &BlobMediaObject{
ObjectFilename: file.Name,
- ObjectSize: file.Size,
ObjectMimetype: file.MimeType,
ObjectData: blob,
}
@@ -365,7 +459,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
Height: file.Height,
}
}
- msg_ev.Attachements = append(msg_ev.Attachements, media_object)
+ msg_ev.Attachments = append(msg_ev.Attachments, media_object)
}
}
@@ -384,15 +478,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
return fmt.Errorf("Invalid channel id")
}
- cache_key := fmt.Sprintf("%s / %s", userId, roomId)
- if _, ok := mm.sentjoinedmap[cache_key]; !ok {
- mm.handler.Event(&Event{
- Author: userId,
- Room: roomId,
- Type: EVENT_JOIN,
- })
- mm.sentjoinedmap[cache_key] = true
- }
+ mm.ensureJoined(user, roomId)
if post.Type == "system_header_change" {
new_header := post.Props["new_header"].(string)
diff --git a/connector/mediaobject.go b/connector/mediaobject.go
index c6634b7..a8d6f9a 100644
--- a/connector/mediaobject.go
+++ b/connector/mediaobject.go
@@ -97,7 +97,6 @@ func (m *UrlMediaObject) URL() string {
type BlobMediaObject struct {
ObjectFilename string
- ObjectSize int64
ObjectMimetype string
ObjectImageSize *ImageSize
ObjectData []byte
@@ -108,7 +107,7 @@ func (m *BlobMediaObject) Filename() string {
}
func (m *BlobMediaObject) Size() int64 {
- return m.ObjectSize
+ return int64(len(m.ObjectData))
}
func (m *BlobMediaObject) Mimetype() string {
diff --git a/connector/xmpp/xmpp.go b/connector/xmpp/xmpp.go
index b18e670..02d1a96 100644
--- a/connector/xmpp/xmpp.go
+++ b/connector/xmpp/xmpp.go
@@ -308,6 +308,19 @@ func (xm *XMPP) Leave(roomId RoomID) {
}
func (xm *XMPP) Send(event *Event) error {
+ if event.Attachments != nil && len(event.Attachments) > 0 {
+ for _, at := range event.Attachments {
+ url := at.URL()
+ if url == "" {
+ // TODO find a way to send them using some hosing of some kind
+ return fmt.Errorf("Attachment without URL sent to XMPP")
+ } else {
+ event.Text += fmt.Sprintf("\n%s (%s, %dkb)",
+ url, at.Mimetype(), at.Size()/1024)
+ }
+ }
+ }
+
fmt.Printf("xm *XMPP Send %#v\n", event)
if len(event.Recipient) > 0 {
_, err := xm.conn.Send(gxmpp.Chat{