From e1b838d30493effbcd8a23fe43e2b131c745b722 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 21 Feb 2020 18:43:47 +0100 Subject: Implement on-demand updating of room & user pictures --- connector/mattermost/mattermost.go | 52 ++++++++++++++++++++++---------------- connector/mediaobject.go | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 22 deletions(-) (limited to 'connector') diff --git a/connector/mattermost/mattermost.go b/connector/mattermost/mattermost.go index 73ea66b..6282831 100644 --- a/connector/mattermost/mattermost.go +++ b/connector/mattermost/mattermost.go @@ -314,17 +314,21 @@ func (mm *Mattermost) handleConnected() { } 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) + room_info.Picture = &LazyBlobMediaObject{ + ObjectFilename: fmt.Sprintf("%s-%d", + t.Team.Name, + t.Team.LastTeamIconUpdate), + GetFn: func(o *LazyBlobMediaObject) error { + team_img, resp := mm.conn.Client.GetTeamIcon(t.Id, "") + if resp.Error == nil { + log.Warnf("Could not get team image: %s", resp.Error) + return resp.Error + } + o.ObjectData = team_img + o.ObjectMimetype = http.DetectContentType(team_img) + return nil + }, } } break @@ -378,20 +382,24 @@ func (mm *Mattermost) updateUserInfo(user *model.User) { 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) + ui.Avatar = &LazyBlobMediaObject{ + ObjectFilename: fmt.Sprintf("%s-%d", + user.Username, + user.LastPictureUpdate), + GetFn: func(o *LazyBlobMediaObject) error { + img, resp := mm.conn.Client.GetProfileImage(user.Id, "") + if resp.Error == nil { + log.Warnf("Could not get profile picture: %s", resp.Error) + return resp.Error + } + o.ObjectData = img + o.ObjectMimetype = http.DetectContentType(img) + return nil + }, } - mm.handler.UserInfoUpdated(userId, ui) - mm.userdisplaynamemap[userId] = userDisp } + mm.handler.UserInfoUpdated(userId, ui) + mm.userdisplaynamemap[userId] = userDisp } } diff --git a/connector/mediaobject.go b/connector/mediaobject.go index a8d6f9a..244e571 100644 --- a/connector/mediaobject.go +++ b/connector/mediaobject.go @@ -132,3 +132,53 @@ type nullCloseReader struct { func (ncr nullCloseReader) Close() error { return nil } + +// ---- + +type LazyBlobMediaObject struct { + ObjectFilename string + ObjectMimetype string + ObjectImageSize *ImageSize + ObjectData []byte + + GetFn func(o *LazyBlobMediaObject) error +} + +func (m *LazyBlobMediaObject) Filename() string { + return m.ObjectFilename +} + +func (m *LazyBlobMediaObject) Size() int64 { + if m.ObjectData == nil { + m.GetFn(m) + } + return int64(len(m.ObjectData)) +} + +func (m *LazyBlobMediaObject) Mimetype() string { + if m.ObjectData == nil { + m.GetFn(m) + } + return m.ObjectMimetype +} + +func (m *LazyBlobMediaObject) ImageSize() *ImageSize { + if m.ObjectData == nil { + m.GetFn(m) + } + return m.ObjectImageSize +} + +func (m *LazyBlobMediaObject) Read() (io.ReadCloser, error) { + if m.ObjectData == nil { + err := m.GetFn(m) + if err != nil { + return nil, err + } + } + return nullCloseReader{bytes.NewBuffer(m.ObjectData)}, nil +} + +func (m *LazyBlobMediaObject) URL() string { + return "" +} -- cgit v1.2.3