[GH-15906][MM-22844] Redesign message notification emails. (#17184)
* Redesign message notification emails. * Fix tests and linter. * Fix tests * Fix tests * gofmt. * Fix date separator * Update html files * Remove date for message notification email. * Modify subtitle for mentions and direct and group messages. * Fix lint error * Fix DM subtitle. * Fixing translations Co-authored-by: Mattermod <mattermod@users.noreply.github.com> Co-authored-by: Jesús Espino <jespinog@gmail.com>
Этот коммит содержится в:
@@ -4,9 +4,11 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -201,33 +203,61 @@ func (es *EmailService) sendBatchedEmailNotification(userID string, notification
|
||||
|
||||
translateFunc := i18n.GetUserTranslations(user.Locale)
|
||||
displayNameFormat := *es.srv.Config().TeamSettings.TeammateNameDisplay
|
||||
siteURL := *es.srv.Config().ServiceSettings.SiteURL
|
||||
|
||||
var contents string
|
||||
for _, notification := range notifications {
|
||||
sender, err := es.srv.Store.User().Get(context.Background(), notification.post.UserId)
|
||||
if err != nil {
|
||||
mlog.Warn("Unable to find sender of post for batched email notification")
|
||||
continue
|
||||
postsData := make([]*postData, 0 /* len */, len(notifications) /* cap */)
|
||||
embeddedFiles := make(map[string]io.Reader)
|
||||
|
||||
emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL
|
||||
if license := es.srv.License(); license != nil && *license.Features.EmailNotificationContents {
|
||||
emailNotificationContentsType = *es.srv.Config().EmailSettings.EmailNotificationContentsType
|
||||
}
|
||||
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
for i, notification := range notifications {
|
||||
sender, errSender := es.srv.Store.User().Get(context.Background(), notification.post.UserId)
|
||||
if errSender != nil {
|
||||
mlog.Warn("Unable to find sender of post for batched email notification")
|
||||
}
|
||||
|
||||
channel, errCh := es.srv.Store.Channel().Get(notification.post.ChannelId, true)
|
||||
if errCh != nil {
|
||||
mlog.Warn("Unable to find channel of post for batched email notification")
|
||||
}
|
||||
|
||||
senderProfileImage, _, errProfileImage := es.srv.GetProfileImage(sender)
|
||||
if errProfileImage != nil {
|
||||
mlog.Warn("Unable to get the sender user profile image.", mlog.String("user_id", sender.Id), mlog.Err(errProfileImage))
|
||||
}
|
||||
|
||||
senderPhoto := fmt.Sprintf("user-avatar-%d.png", i)
|
||||
if senderProfileImage != nil {
|
||||
embeddedFiles[senderPhoto] = bytes.NewReader(senderProfileImage)
|
||||
}
|
||||
|
||||
tm := time.Unix(notification.post.CreateAt/1000, 0)
|
||||
timezone, _ := tm.Zone()
|
||||
|
||||
t := translateFunc("api.email_batching.send_batched_email_notification.time", map[string]interface{}{
|
||||
"Hour": tm.Hour(),
|
||||
"Minute": fmt.Sprintf("%02d", tm.Minute()),
|
||||
"Month": translateFunc(tm.Month().String()),
|
||||
"Day": tm.Day(),
|
||||
"Year": tm.Year(),
|
||||
"Timezone": timezone,
|
||||
})
|
||||
|
||||
MessageURL := siteURL + "/" + notification.teamName + "/pl/" + notification.post.Id
|
||||
|
||||
postsData = append(postsData, &postData{
|
||||
SenderPhoto: senderPhoto,
|
||||
SenderName: sender.GetDisplayName(displayNameFormat),
|
||||
Time: t,
|
||||
ChannelName: channel.DisplayName,
|
||||
Message: template.HTML(es.srv.GetMessageForNotification(notification.post, translateFunc)),
|
||||
MessageURL: MessageURL,
|
||||
})
|
||||
}
|
||||
|
||||
channel, errCh := es.srv.Store.Channel().Get(notification.post.ChannelId, true)
|
||||
if errCh != nil {
|
||||
mlog.Warn("Unable to find channel of post for batched email notification")
|
||||
continue
|
||||
}
|
||||
|
||||
emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL
|
||||
if license := es.srv.License(); license != nil && *license.Features.EmailNotificationContents {
|
||||
emailNotificationContentsType = *es.srv.Config().EmailSettings.EmailNotificationContentsType
|
||||
}
|
||||
|
||||
postContent, err := es.renderBatchedPost(notification, channel, sender, *es.srv.Config().ServiceSettings.SiteURL, displayNameFormat, translateFunc, user.Locale, emailNotificationContentsType)
|
||||
if err != nil {
|
||||
mlog.Warn("Unable to render post for batched email notification template", mlog.Err(err))
|
||||
continue
|
||||
}
|
||||
|
||||
contents += postContent
|
||||
}
|
||||
|
||||
tm := time.Unix(notifications[0].post.CreateAt/1000, 0)
|
||||
@@ -239,59 +269,31 @@ func (es *EmailService) sendBatchedEmailNotification(userID string, notification
|
||||
"Day": tm.Day(),
|
||||
})
|
||||
|
||||
data := es.newEmailTemplateData(user.Locale)
|
||||
data.Props["SiteURL"] = *es.srv.Config().ServiceSettings.SiteURL
|
||||
data.Props["Posts"] = template.HTML(contents)
|
||||
data.Props["BodyText"] = translateFunc("api.email_batching.send_batched_email_notification.body_text", len(notifications))
|
||||
|
||||
body, err2 := es.srv.TemplatesContainer().RenderToString("post_batched_body", data)
|
||||
if err2 != nil {
|
||||
mlog.Warn("Unable build the batched email notification template", mlog.Err(err2))
|
||||
return
|
||||
firstSender, err := es.srv.Store.User().Get(context.Background(), notifications[0].post.UserId)
|
||||
if err != nil {
|
||||
mlog.Warn("Unable to find sender of post for batched email notification")
|
||||
}
|
||||
|
||||
if nErr := es.sendNotificationMail(user.Email, subject, body); nErr != nil {
|
||||
data := es.newEmailTemplateData(user.Locale)
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["Title"] = translateFunc("api.email_batching.send_batched_email_notification.title", len(notifications)-1, map[string]interface{}{
|
||||
"SenderName": firstSender.GetDisplayName(displayNameFormat),
|
||||
})
|
||||
data.Props["SubTitle"] = translateFunc("api.email_batching.send_batched_email_notification.subTitle")
|
||||
data.Props["Button"] = translateFunc("api.email_batching.send_batched_email_notification.button")
|
||||
data.Props["ButtonURL"] = siteURL
|
||||
data.Props["Posts"] = postsData
|
||||
data.Props["MessageButton"] = translateFunc("api.email_batching.send_batched_email_notification.messageButton")
|
||||
data.Props["NotificationFooterTitle"] = translateFunc("app.notification.footer.title")
|
||||
data.Props["NotificationFooterInfoLogin"] = translateFunc("app.notification.footer.infoLogin")
|
||||
data.Props["NotificationFooterInfo"] = translateFunc("app.notification.footer.info")
|
||||
|
||||
renderedPage, renderErr := es.srv.TemplatesContainer().RenderToString("messages_notification", data)
|
||||
if renderErr != nil {
|
||||
mlog.Error("Unable to render email", mlog.Err(renderErr))
|
||||
}
|
||||
|
||||
if nErr := es.sendNotificationMail(user.Email, subject, renderedPage); nErr != nil {
|
||||
mlog.Warn("Unable to send batched email notification", mlog.String("email", user.Email), mlog.Err(nErr))
|
||||
}
|
||||
}
|
||||
|
||||
func (es *EmailService) renderBatchedPost(notification *batchedNotification, channel *model.Channel, sender *model.User, siteURL string, displayNameFormat string, translateFunc i18n.TranslateFunc, userLocale string, emailNotificationContentsType string) (string, error) {
|
||||
// don't include message contents if email notification contents type is set to generic
|
||||
var templateName = "post_batched_post_generic"
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
templateName = "post_batched_post_full"
|
||||
}
|
||||
|
||||
data := es.newEmailTemplateData(userLocale)
|
||||
data.Props["Button"] = translateFunc("api.email_batching.render_batched_post.go_to_post")
|
||||
data.Props["PostMessage"] = es.srv.GetMessageForNotification(notification.post, translateFunc)
|
||||
data.Props["PostLink"] = siteURL + "/" + notification.teamName + "/pl/" + notification.post.Id
|
||||
data.Props["SenderName"] = sender.GetDisplayName(displayNameFormat)
|
||||
|
||||
tm := time.Unix(notification.post.CreateAt/1000, 0)
|
||||
timezone, _ := tm.Zone()
|
||||
|
||||
data.Props["Date"] = translateFunc("api.email_batching.render_batched_post.date", map[string]interface{}{
|
||||
"Year": tm.Year(),
|
||||
"Month": translateFunc(tm.Month().String()),
|
||||
"Day": tm.Day(),
|
||||
"Hour": tm.Hour(),
|
||||
"Minute": fmt.Sprintf("%02d", tm.Minute()),
|
||||
"Timezone": timezone,
|
||||
})
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
data.Props["ChannelName"] = translateFunc("api.email_batching.render_batched_post.direct_message")
|
||||
} else if channel.Type == model.CHANNEL_GROUP {
|
||||
data.Props["ChannelName"] = translateFunc("api.email_batching.render_batched_post.group_message")
|
||||
} else {
|
||||
// don't include channel name if email notification contents type is set to generic
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
data.Props["ChannelName"] = channel.DisplayName
|
||||
} else {
|
||||
data.Props["ChannelName"] = translateFunc("api.email_batching.render_batched_post.notification")
|
||||
}
|
||||
}
|
||||
|
||||
return es.srv.TemplatesContainer().RenderToString(templateName, data)
|
||||
}
|
||||
|
||||
@@ -283,55 +283,3 @@ func TestCheckPendingNotificationsCantParseInterval(t *testing.T) {
|
||||
|
||||
require.Nil(t, job.pendingNotifications[th.BasicUser.Id], "should have sent queued post")
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensures that post contents are not included in notification email when email notification content type is set to generic
|
||||
*/
|
||||
func TestRenderBatchedPostGeneric(t *testing.T) {
|
||||
th := SetupWithStoreMock(t)
|
||||
defer th.TearDown()
|
||||
|
||||
var post = &model.Post{}
|
||||
post.Message = "This is the message"
|
||||
var notification = &batchedNotification{}
|
||||
notification.post = post
|
||||
var channel = &model.Channel{}
|
||||
channel.DisplayName = "Some Test Channel"
|
||||
var sender = &model.User{}
|
||||
sender.Email = "sender@test.com"
|
||||
|
||||
translateFunc := func(translationID string, args ...interface{}) string {
|
||||
// mock translateFunc just returns the translation id - this is good enough for our purposes
|
||||
return translationID
|
||||
}
|
||||
|
||||
rendered, err := th.Server.EmailService.renderBatchedPost(notification, channel, sender, "http://localhost:8065", "", translateFunc, "en", model.EMAIL_NOTIFICATION_CONTENTS_GENERIC)
|
||||
require.NoError(t, err)
|
||||
require.NotContains(t, rendered, post.Message, "Rendered email should not contain post contents when email notification contents type is set to Generic.")
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensures that post contents included in notification email when email notification content type is set to full
|
||||
*/
|
||||
func TestRenderBatchedPostFull(t *testing.T) {
|
||||
th := SetupWithStoreMock(t)
|
||||
defer th.TearDown()
|
||||
|
||||
var post = &model.Post{}
|
||||
post.Message = "This is the message"
|
||||
var notification = &batchedNotification{}
|
||||
notification.post = post
|
||||
var channel = &model.Channel{}
|
||||
channel.DisplayName = "Some Test Channel"
|
||||
var sender = &model.User{}
|
||||
sender.Email = "sender@test.com"
|
||||
|
||||
translateFunc := func(translationID string, args ...interface{}) string {
|
||||
// mock translateFunc just returns the translation id - this is good enough for our purposes
|
||||
return translationID
|
||||
}
|
||||
|
||||
rendered, err := th.Server.EmailService.renderBatchedPost(notification, channel, sender, "http://localhost:8065", "", translateFunc, "en", model.EMAIL_NOTIFICATION_CONTENTS_FULL)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, rendered, post.Message, "Rendered email should contain post contents when email notification contents type is set to Full.")
|
||||
}
|
||||
|
||||
21
app/file.go
21
app/file.go
@@ -128,15 +128,7 @@ func (a *App) TestFileStoreConnectionWithConfig(cfg *model.FileSettings) *model.
|
||||
}
|
||||
|
||||
func (a *App) ReadFile(path string) ([]byte, *model.AppError) {
|
||||
backend, err := a.FileBackend()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, nErr := backend.ReadFile(path)
|
||||
if nErr != nil {
|
||||
return nil, model.NewAppError("ReadFile", "api.file.read_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return result, nil
|
||||
return a.srv.ReadFile(path)
|
||||
}
|
||||
|
||||
// Caller must close the first return value
|
||||
@@ -202,16 +194,7 @@ func (a *App) MoveFile(oldPath, newPath string) *model.AppError {
|
||||
}
|
||||
|
||||
func (a *App) WriteFile(fr io.Reader, path string) (int64, *model.AppError) {
|
||||
backend, err := a.FileBackend()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
result, nErr := backend.WriteFile(fr, path)
|
||||
if nErr != nil {
|
||||
return result, model.NewAppError("WriteFile", "api.file.write_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return result, nil
|
||||
return a.srv.WriteFile(fr, path)
|
||||
}
|
||||
|
||||
func (a *App) AppendFile(fr io.Reader, path string) (int64, *model.AppError) {
|
||||
|
||||
@@ -254,8 +254,11 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
||||
}
|
||||
|
||||
if a.userAllowsEmail(profileMap[id], channelMemberNotifyPropsMap[id], post) {
|
||||
err := a.sendNotificationEmail(notification, profileMap[id], team)
|
||||
senderProfileImage, _, err := a.GetProfileImage(sender)
|
||||
if err != nil {
|
||||
a.Log().Warn("Unable to get the sender user profile image.", mlog.String("user_id", sender.Id), mlog.Err(err))
|
||||
}
|
||||
if err := a.sendNotificationEmail(notification, profileMap[id], team, senderProfileImage); err != nil {
|
||||
mlog.Warn("Unable to send notification email.", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -18,7 +20,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (a *App) sendNotificationEmail(notification *PostNotification, user *model.User, team *model.Team) error {
|
||||
func (a *App) sendNotificationEmail(notification *PostNotification, user *model.User, team *model.Team, senderProfileImage []byte) error {
|
||||
channel := notification.Channel
|
||||
post := notification.Post
|
||||
|
||||
@@ -95,14 +97,24 @@ func (a *App) sendNotificationEmail(notification *PostNotification, user *model.
|
||||
subjectText = getNotificationEmailSubject(user, post, translateFunc, *a.Config().TeamSettings.SiteName, team.DisplayName, useMilitaryTime)
|
||||
}
|
||||
|
||||
senderPhoto := ""
|
||||
embeddedFiles := make(map[string]io.Reader)
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL && senderProfileImage != nil {
|
||||
senderPhoto = "user-avatar.png"
|
||||
embeddedFiles = map[string]io.Reader{
|
||||
senderPhoto: bytes.NewReader(senderProfileImage),
|
||||
}
|
||||
}
|
||||
|
||||
landingURL := a.GetSiteURL() + "/landing#/" + team.Name
|
||||
var bodyText, err = a.getNotificationEmailBody(user, post, channel, channelName, senderName, team.Name, landingURL, emailNotificationContentsType, useMilitaryTime, translateFunc)
|
||||
|
||||
var bodyText, err = a.getNotificationEmailBody(user, post, channel, channelName, senderName, team.Name, landingURL, emailNotificationContentsType, useMilitaryTime, translateFunc, senderPhoto)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to render the email notification template")
|
||||
}
|
||||
|
||||
a.Srv().Go(func() {
|
||||
if nErr := a.Srv().EmailService.sendNotificationMail(user.Email, html.UnescapeString(subjectText), bodyText); nErr != nil {
|
||||
if nErr := a.Srv().EmailService.sendMailWithEmbeddedFiles(user.Email, html.UnescapeString(subjectText), bodyText, embeddedFiles); nErr != nil {
|
||||
mlog.Error("Error while sending the email", mlog.String("user_email", user.Email), mlog.Err(nErr))
|
||||
}
|
||||
})
|
||||
@@ -162,15 +174,33 @@ func getGroupMessageNotificationEmailSubject(user *model.User, post *model.Post,
|
||||
return translateFunc("app.notification.subject.group_message.generic", subjectParameters)
|
||||
}
|
||||
|
||||
type postData struct {
|
||||
SenderName string
|
||||
ChannelName string
|
||||
Message template.HTML
|
||||
MessageURL string
|
||||
SenderPhoto string
|
||||
PostPhoto string
|
||||
Time string
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the email body for notification messages
|
||||
*/
|
||||
func (a *App) getNotificationEmailBody(recipient *model.User, post *model.Post, channel *model.Channel, channelName string, senderName string, teamName string, landingURL string, emailNotificationContentsType string, useMilitaryTime bool, translateFunc i18n.TranslateFunc) (string, error) {
|
||||
// only include message contents in notification email if email notification contents type is set to full
|
||||
var templateName = "post_body_generic"
|
||||
data := a.Srv().EmailService.newEmailTemplateData(recipient.Locale)
|
||||
func (a *App) getNotificationEmailBody(recipient *model.User, post *model.Post, channel *model.Channel, channelName string, senderName string, teamName string, landingURL string, emailNotificationContentsType string, useMilitaryTime bool, translateFunc i18n.TranslateFunc, senderPhoto string) (string, error) {
|
||||
pData := postData{
|
||||
SenderName: senderName,
|
||||
SenderPhoto: senderPhoto,
|
||||
}
|
||||
|
||||
t := getFormattedPostTime(recipient, post, useMilitaryTime, translateFunc)
|
||||
messageTime := map[string]interface{}{
|
||||
"Hour": t.Hour,
|
||||
"Minute": t.Minute,
|
||||
"TimeZone": t.TimeZone,
|
||||
}
|
||||
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
templateName = "post_body_full"
|
||||
postMessage := a.GetMessageForNotification(post, translateFunc)
|
||||
postMessage = html.EscapeString(postMessage)
|
||||
normalizedPostMessage, err := a.generateHyperlinkForChannels(postMessage, teamName, landingURL)
|
||||
@@ -178,72 +208,47 @@ func (a *App) getNotificationEmailBody(recipient *model.User, post *model.Post,
|
||||
mlog.Warn("Encountered error while generating hyperlink for channels", mlog.String("team_name", teamName), mlog.Err(err))
|
||||
normalizedPostMessage = postMessage
|
||||
}
|
||||
data.Props["PostMessage"] = template.HTML(normalizedPostMessage)
|
||||
pData.Message = template.HTML(normalizedPostMessage)
|
||||
pData.Time = translateFunc("app.notification.body.dm.time", messageTime)
|
||||
}
|
||||
|
||||
data := a.Srv().EmailService.newEmailTemplateData(recipient.Locale)
|
||||
data.Props["SiteURL"] = a.GetSiteURL()
|
||||
if teamName != "select_team" {
|
||||
data.Props["TeamLink"] = landingURL + "/pl/" + post.Id
|
||||
data.Props["ButtonURL"] = landingURL + "/pl/" + post.Id
|
||||
} else {
|
||||
data.Props["TeamLink"] = landingURL
|
||||
}
|
||||
|
||||
t := getFormattedPostTime(recipient, post, useMilitaryTime, translateFunc)
|
||||
|
||||
info := map[string]interface{}{
|
||||
"Hour": t.Hour,
|
||||
"Minute": t.Minute,
|
||||
"TimeZone": t.TimeZone,
|
||||
"Month": t.Month,
|
||||
"Day": t.Day,
|
||||
}
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
data.Props["BodyText"] = translateFunc("app.notification.body.intro.direct.full")
|
||||
data.Props["Info1"] = ""
|
||||
info["SenderName"] = senderName
|
||||
data.Props["Info2"] = translateFunc("app.notification.body.text.direct.full", info)
|
||||
} else {
|
||||
data.Props["BodyText"] = translateFunc("app.notification.body.intro.direct.generic", map[string]interface{}{
|
||||
"SenderName": senderName,
|
||||
})
|
||||
data.Props["Info"] = translateFunc("app.notification.body.text.direct.generic", info)
|
||||
}
|
||||
} else if channel.Type == model.CHANNEL_GROUP {
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
data.Props["BodyText"] = translateFunc("app.notification.body.intro.group_message.full")
|
||||
data.Props["Info1"] = translateFunc("app.notification.body.text.group_message.full",
|
||||
map[string]interface{}{
|
||||
"ChannelName": channelName,
|
||||
})
|
||||
info["SenderName"] = senderName
|
||||
data.Props["Info2"] = translateFunc("app.notification.body.text.group_message.full2", info)
|
||||
} else {
|
||||
data.Props["BodyText"] = translateFunc("app.notification.body.intro.group_message.generic", map[string]interface{}{
|
||||
"SenderName": senderName,
|
||||
})
|
||||
data.Props["Info"] = translateFunc("app.notification.body.text.group_message.generic", info)
|
||||
}
|
||||
} else {
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
data.Props["BodyText"] = translateFunc("app.notification.body.intro.notification.full")
|
||||
data.Props["Info1"] = translateFunc("app.notification.body.text.notification.full",
|
||||
map[string]interface{}{
|
||||
"ChannelName": channelName,
|
||||
})
|
||||
info["SenderName"] = senderName
|
||||
data.Props["Info2"] = translateFunc("app.notification.body.text.notification.full2", info)
|
||||
} else {
|
||||
data.Props["BodyText"] = translateFunc("app.notification.body.intro.notification.generic", map[string]interface{}{
|
||||
"SenderName": senderName,
|
||||
})
|
||||
data.Props["Info"] = translateFunc("app.notification.body.text.notification.generic", info)
|
||||
}
|
||||
data.Props["ButtonURL"] = landingURL
|
||||
}
|
||||
|
||||
data.Props["SenderName"] = senderName
|
||||
data.Props["Button"] = translateFunc("api.templates.post_body.button")
|
||||
data.Props["NotificationFooterTitle"] = translateFunc("app.notification.footer.title")
|
||||
data.Props["NotificationFooterInfoLogin"] = translateFunc("app.notification.footer.infoLogin")
|
||||
data.Props["NotificationFooterInfo"] = translateFunc("app.notification.footer.info")
|
||||
|
||||
return a.Srv().TemplatesContainer().RenderToString(templateName, data)
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
// Direct Messages
|
||||
data.Props["Title"] = translateFunc("app.notification.body.dm.title", map[string]interface{}{"SenderName": senderName})
|
||||
data.Props["SubTitle"] = translateFunc("app.notification.body.dm.subTitle", map[string]interface{}{"SenderName": senderName})
|
||||
} else if channel.Type == model.CHANNEL_GROUP {
|
||||
// Group Messages
|
||||
data.Props["Title"] = translateFunc("app.notification.body.group.title", map[string]interface{}{"SenderName": senderName})
|
||||
data.Props["SubTitle"] = translateFunc("app.notification.body.group.subTitle", map[string]interface{}{"SenderName": senderName})
|
||||
} else {
|
||||
// mentions
|
||||
data.Props["Title"] = translateFunc("app.notification.body.mention.title", map[string]interface{}{"SenderName": senderName})
|
||||
data.Props["SubTitle"] = translateFunc("app.notification.body.mention.subTitle", map[string]interface{}{"SenderName": senderName, "ChannelName": channelName})
|
||||
pData.ChannelName = channelName
|
||||
}
|
||||
|
||||
// only include posts in notification email if email notification contents type is set to full
|
||||
if emailNotificationContentsType == model.EMAIL_NOTIFICATION_CONTENTS_FULL {
|
||||
data.Props["Posts"] = []postData{pData}
|
||||
} else {
|
||||
data.Props["Posts"] = []postData{}
|
||||
}
|
||||
|
||||
return a.Srv().TemplatesContainer().RenderToString("messages_notification", data)
|
||||
}
|
||||
|
||||
type formattedPostTime struct {
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -91,11 +90,9 @@ func TestGetNotificationEmailBodyFullNotificationPublicChannel(t *testing.T) {
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new notification.", fmt.Sprintf("Expected email text 'You have a new notification. Got %s", body))
|
||||
require.Contains(t, body, "Channel: "+channel.DisplayName, "Expected email text 'Channel: %s'. Got %s", channel.DisplayName, body)
|
||||
require.Contains(t, body, senderName+" - ", fmt.Sprintf("Expected email text '%s - '. Got %s", senderName, body))
|
||||
require.Contains(t, body, "mentioned you in a message", fmt.Sprintf("Expected email text 'mentioned you in a message. Got %s", body))
|
||||
require.Contains(t, body, post.Message, fmt.Sprintf("Expected email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
@@ -124,11 +121,9 @@ func TestGetNotificationEmailBodyFullNotificationGroupChannel(t *testing.T) {
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new Group Message.", fmt.Sprintf("Expected email text 'You have a new Group Message. Got "+body))
|
||||
require.Contains(t, body, "Channel: ChannelName", fmt.Sprintf("Expected email text 'Channel: ChannelName'. Got %s", body))
|
||||
require.Contains(t, body, senderName+" - ", fmt.Sprintf("Expected email text '%s - '. Got %s", senderName, body))
|
||||
require.Contains(t, body, "sent you a new message", fmt.Sprintf("Expected email text 'sent you a new message. Got "+body))
|
||||
require.Contains(t, body, post.Message, fmt.Sprintf("Expected email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
@@ -157,11 +152,9 @@ func TestGetNotificationEmailBodyFullNotificationPrivateChannel(t *testing.T) {
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new notification.", fmt.Sprintf("Expected email text 'You have a new notification. Got "+body))
|
||||
require.Contains(t, body, "Channel: "+channel.DisplayName, fmt.Sprintf("Expected email text 'Channel: "+channel.DisplayName+"'. Got "+body))
|
||||
require.Contains(t, body, senderName+" - ", fmt.Sprintf("Expected email text '%s - '. Got %s", senderName, body))
|
||||
require.Contains(t, body, "mentioned you in a message", fmt.Sprintf("Expected email text 'mentioned you in a message. Got "+body))
|
||||
require.Contains(t, body, post.Message, fmt.Sprintf("Expected email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
@@ -190,10 +183,9 @@ func TestGetNotificationEmailBodyFullNotificationDirectChannel(t *testing.T) {
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new Direct Message.", fmt.Sprintf("Expected email text 'You have a new Direct Message. Got "+body))
|
||||
require.Contains(t, body, senderName+" - ", fmt.Sprintf("Expected email text '%s - '. Got %s", senderName, body))
|
||||
require.Contains(t, body, "sent you a new message", fmt.Sprintf("Expected email text 'sent you a new message. Got "+body))
|
||||
require.Contains(t, body, post.Message, fmt.Sprintf("Expected email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
@@ -226,11 +218,11 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTimeWithTimezone(t *testi
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, false, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, false, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
r, _ := regexp.Compile("E([S|D]+)T")
|
||||
zone := r.FindString(body)
|
||||
require.Contains(t, body, "sender - 9:43 AM "+zone+", April 25", fmt.Sprintf("Expected email text 'sender - 9:43 AM %s, April 25'. Got %s", zone, body))
|
||||
require.Contains(t, body, "9:43 AM "+zone, fmt.Sprintf("Expected email text '9:43 AM %s'. Got %s", zone, body))
|
||||
}
|
||||
|
||||
func TestGetNotificationEmailBodyFullNotificationLocaleTimeNoTimezone(t *testing.T) {
|
||||
@@ -276,10 +268,10 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTimeNoTimezone(t *testing
|
||||
tmp, err := template.New("foo").Parse(`{{.}}`)
|
||||
require.NoError(t, err)
|
||||
var text bytes.Buffer
|
||||
err = tmp.Execute(&text, fmt.Sprintf("sender - %s:%s %s, %s %s", formattedTime.Hour, formattedTime.Minute, formattedTime.TimeZone, formattedTime.Month, formattedTime.Day))
|
||||
err = tmp.Execute(&text, fmt.Sprintf("%s:%s %s", formattedTime.Hour, formattedTime.Minute, formattedTime.TimeZone))
|
||||
require.NoError(t, err)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
postTimeLine := text.String()
|
||||
require.Contains(t, body, postTimeLine, fmt.Sprintf("Expected email text '%s'. Got %s", postTimeLine, body))
|
||||
@@ -313,10 +305,9 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTime12Hour(t *testing.T)
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, false, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, false, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "sender - 2:30 PM", fmt.Sprintf("Expected email text 'sender - 2:30 PM'. Got %s", body))
|
||||
require.Contains(t, body, "April 25", fmt.Sprintf("Expected email text 'April 25'. Got %s", body))
|
||||
require.Contains(t, body, "2:30 PM", fmt.Sprintf("Expected email text '2:30 PM'. Got %s", body))
|
||||
}
|
||||
|
||||
func TestGetNotificationEmailBodyFullNotificationLocaleTime24Hour(t *testing.T) {
|
||||
@@ -347,10 +338,9 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTime24Hour(t *testing.T)
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "sender - 14:30", fmt.Sprintf("Expected email text 'sender - 14:30'. Got %s", body))
|
||||
require.Contains(t, body, "April 25", fmt.Sprintf("Expected email text 'April 25'. Got %s", body))
|
||||
require.Contains(t, body, "14:30", fmt.Sprintf("Expected email text '14:30'. Got %s", body))
|
||||
}
|
||||
|
||||
// from here
|
||||
@@ -378,11 +368,9 @@ func TestGetNotificationEmailBodyGenericNotificationPublicChannel(t *testing.T)
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new notification from "+senderName, fmt.Sprintf("Expected email text 'You have a new notification from %s'. Got %s", senderName, body))
|
||||
require.False(t, strings.Contains(body, "Channel: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body))
|
||||
require.False(t, strings.Contains(body, post.Message), fmt.Sprintf("Did not expect email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, "mentioned you in a message", fmt.Sprintf("Expected email text 'mentioned you in a message. Got %s", body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
|
||||
@@ -410,11 +398,9 @@ func TestGetNotificationEmailBodyGenericNotificationGroupChannel(t *testing.T) {
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new Group Message from "+senderName, fmt.Sprintf("Expected email text 'You have a new Group Message from %s'. Got %s", senderName, body))
|
||||
require.False(t, strings.Contains(body, "CHANNEL: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body))
|
||||
require.False(t, strings.Contains(body, post.Message), fmt.Sprintf("Did not expect email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, "sent you a new message", fmt.Sprintf("Expected email text 'sent you a new message. Got "+body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
|
||||
@@ -442,11 +428,9 @@ func TestGetNotificationEmailBodyGenericNotificationPrivateChannel(t *testing.T)
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new notification from "+senderName, fmt.Sprintf("Expected email text 'You have a new notification from %s'. Got %s", senderName, body))
|
||||
require.False(t, strings.Contains(body, "CHANNEL: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body))
|
||||
require.False(t, strings.Contains(body, post.Message), fmt.Sprintf("Did not expect email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, "mentioned you in a message", fmt.Sprintf("Expected email text 'mentioned you in a message. Got %s", body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
|
||||
@@ -474,11 +458,9 @@ func TestGetNotificationEmailBodyGenericNotificationDirectChannel(t *testing.T)
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, "You have a new Direct Message from "+senderName, fmt.Sprintf("Expected email text 'You have a new Direct Message from "+senderName+"'. Got "+body))
|
||||
require.False(t, strings.Contains(body, "CHANNEL: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body))
|
||||
require.False(t, strings.Contains(body, post.Message), fmt.Sprintf("Did not expect email text '%s'. Got %s", post.Message, body))
|
||||
require.Contains(t, body, "sent you a new message", fmt.Sprintf("Expected email text 'sent you a new message. Got "+body))
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
|
||||
@@ -510,7 +492,7 @@ func TestGetNotificationEmailEscapingChars(t *testing.T) {
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, ch,
|
||||
channelName, senderName, teamName, teamURL,
|
||||
emailNotificationContentsType, true, translateFunc)
|
||||
emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotContains(t, body, message)
|
||||
@@ -554,7 +536,7 @@ func TestGetNotificationEmailBodyPublicChannelMention(t *testing.T) {
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, ch,
|
||||
ch.Name, senderName, teamName, teamURL,
|
||||
emailNotificationContentsType, true, translateFunc)
|
||||
emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
channelURL := teamURL + "/channels/" + ch.Name
|
||||
mention := "~" + ch.Name
|
||||
@@ -620,7 +602,7 @@ func TestGetNotificationEmailBodyMultiPublicChannelMention(t *testing.T) {
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, ch,
|
||||
ch.Name, senderName, teamName, teamURL,
|
||||
emailNotificationContentsType, true, translateFunc)
|
||||
emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
channelURL := teamURL + "/channels/" + ch.Name
|
||||
channelURL2 := teamURL + "/channels/" + ch2.Name
|
||||
@@ -669,7 +651,7 @@ func TestGetNotificationEmailBodyPrivateChannelMention(t *testing.T) {
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, ch,
|
||||
ch.Name, senderName, teamName, teamURL,
|
||||
emailNotificationContentsType, true, translateFunc)
|
||||
emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
channelURL := teamURL + "/channels/" + ch.Name
|
||||
mention := "~" + ch.Name
|
||||
@@ -813,7 +795,7 @@ func TestLandingLink(t *testing.T) {
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
@@ -843,7 +825,7 @@ func TestLandingLinkPermalink(t *testing.T) {
|
||||
teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil)
|
||||
storeMock.On("Team").Return(&teamStoreMock)
|
||||
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc)
|
||||
body, err := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc, "user-avatar.png")
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, body, teamURL+"/pl/"+post.Id, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body))
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/maphash"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -2114,6 +2116,76 @@ func (a *App) generateSupportPacketYaml() (*model.FileData, string) {
|
||||
return nil, warning
|
||||
}
|
||||
|
||||
func (s *Server) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) {
|
||||
if *s.Config().FileSettings.DriverName == "" {
|
||||
img, appErr := s.GetDefaultProfileImage(user)
|
||||
if appErr != nil {
|
||||
return nil, false, appErr
|
||||
}
|
||||
return img, false, nil
|
||||
}
|
||||
|
||||
path := "users/" + user.Id + "/profile.png"
|
||||
|
||||
data, err := s.ReadFile(path)
|
||||
if err != nil {
|
||||
img, appErr := s.GetDefaultProfileImage(user)
|
||||
if appErr != nil {
|
||||
return nil, false, appErr
|
||||
}
|
||||
|
||||
if user.LastPictureUpdate == 0 {
|
||||
if _, err := s.WriteFile(bytes.NewReader(img), path); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
}
|
||||
return img, true, nil
|
||||
}
|
||||
|
||||
return data, false, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError) {
|
||||
var img []byte
|
||||
var appErr *model.AppError
|
||||
|
||||
if user.IsBot {
|
||||
img = model.BotDefaultImage
|
||||
appErr = nil
|
||||
} else {
|
||||
img, appErr = CreateProfileImage(user.Username, user.Id, *s.Config().FileSettings.InitialFont)
|
||||
}
|
||||
if appErr != nil {
|
||||
return nil, appErr
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
func (s *Server) ReadFile(path string) ([]byte, *model.AppError) {
|
||||
backend, err := s.FileBackend()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, nErr := backend.ReadFile(path)
|
||||
if nErr != nil {
|
||||
return nil, model.NewAppError("ReadFile", "api.file.read_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Server) WriteFile(fr io.Reader, path string) (int64, *model.AppError) {
|
||||
backend, err := s.FileBackend()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
result, nErr := backend.WriteFile(fr, path)
|
||||
if nErr != nil {
|
||||
return result, model.NewAppError("WriteFile", "api.file.write_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func runDNDStatusExpireJob(a *App) {
|
||||
if a.IsLeader() {
|
||||
a.srv.dndnTaskMut.Lock()
|
||||
|
||||
41
app/user.go
41
app/user.go
@@ -875,48 +875,11 @@ func getFont(initialFont string) (*truetype.Font, error) {
|
||||
}
|
||||
|
||||
func (a *App) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) {
|
||||
if *a.Config().FileSettings.DriverName == "" {
|
||||
img, appErr := a.GetDefaultProfileImage(user)
|
||||
if appErr != nil {
|
||||
return nil, false, appErr
|
||||
}
|
||||
return img, false, nil
|
||||
}
|
||||
|
||||
path := "users/" + user.Id + "/profile.png"
|
||||
|
||||
data, err := a.ReadFile(path)
|
||||
if err != nil {
|
||||
img, appErr := a.GetDefaultProfileImage(user)
|
||||
if appErr != nil {
|
||||
return nil, false, appErr
|
||||
}
|
||||
|
||||
if user.LastPictureUpdate == 0 {
|
||||
if _, err := a.WriteFile(bytes.NewReader(img), path); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
}
|
||||
return img, true, nil
|
||||
}
|
||||
|
||||
return data, false, nil
|
||||
return a.srv.GetProfileImage(user)
|
||||
}
|
||||
|
||||
func (a *App) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError) {
|
||||
var img []byte
|
||||
var appErr *model.AppError
|
||||
|
||||
if user.IsBot {
|
||||
img = model.BotDefaultImage
|
||||
appErr = nil
|
||||
} else {
|
||||
img, appErr = CreateProfileImage(user.Username, user.Id, *a.Config().FileSettings.InitialFont)
|
||||
}
|
||||
if appErr != nil {
|
||||
return nil, appErr
|
||||
}
|
||||
return img, nil
|
||||
return a.srv.GetDefaultProfileImage(user)
|
||||
}
|
||||
|
||||
func (a *App) SetDefaultProfileImage(user *model.User) *model.AppError {
|
||||
|
||||
Ссылка в новой задаче
Block a user