From 8203fd16ce3356d69b0cc51287d0a1fc25318b2d Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Tue, 16 Aug 2016 14:41:47 -0400 Subject: PLT-3647 Email Batching (#3718) * PLT-3647 Added config settings for email batching * PLT-3647 Refactored generation of email notification * PLT-3647 Added serverside code for email batching * PLT-3647 Updated settings UI to enable email batching * PLT-3647 Removed debug code * PLT-3647 Fixed 0-padding of minutes in batched notification * PLT-3647 Updated clientside UI for when email batching is disabled * Go fmt * PLT-3647 Changed email batching to be disabled by default * Updated batched email message * Added email batching toggle to system console * Changed Email Notifications > Immediate setting to a 30 second batch interval * Go fmt * Fixed link to Mattermost icon in batched email notification * Updated users to use 30 second email batching by default * Fully disabled email batching when clustering is enabled * Fixed email batching setting in the system console * Fixed casing of 'Send Email notifications' -> 'Send email notifications' * Updating UI Improvements for email batching (#3736) * Updated text for notification settings and SiteURL. * Prevented enabling email batching when SiteURL isn't set in the system console * Re-added a couple debug messages * Added warning text when clustering is enabled --- model/config.go | 37 +++++++++++++++++++++++++++++++++++++ model/preference.go | 13 +++++++++++-- model/user.go | 18 ++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) (limited to 'model') diff --git a/model/config.go b/model/config.go index f73cb290b..32cb501a0 100644 --- a/model/config.go +++ b/model/config.go @@ -47,6 +47,9 @@ const ( RESTRICT_EMOJI_CREATION_ADMIN = "admin" RESTRICT_EMOJI_CREATION_SYSTEM_ADMIN = "system_admin" + EMAIL_BATCHING_BUFFER_SIZE = 256 + EMAIL_BATCHING_INTERVAL = 30 + SITENAME_MAX_LENGTH = 30 ) @@ -166,6 +169,9 @@ type EmailSettings struct { SendPushNotifications *bool PushNotificationServer *string PushNotificationContents *string + EnableEmailBatching *bool + EmailBatchingBufferSize *int + EmailBatchingInterval *int } type RateLimitSettings struct { @@ -508,6 +514,21 @@ func (o *Config) SetDefaults() { *o.EmailSettings.FeedbackOrganization = "" } + if o.EmailSettings.EnableEmailBatching == nil { + o.EmailSettings.EnableEmailBatching = new(bool) + *o.EmailSettings.EnableEmailBatching = false + } + + if o.EmailSettings.EmailBatchingBufferSize == nil { + o.EmailSettings.EmailBatchingBufferSize = new(int) + *o.EmailSettings.EmailBatchingBufferSize = EMAIL_BATCHING_BUFFER_SIZE + } + + if o.EmailSettings.EmailBatchingInterval == nil { + o.EmailSettings.EmailBatchingInterval = new(int) + *o.EmailSettings.EmailBatchingInterval = EMAIL_BATCHING_INTERVAL + } + if !IsSafeLink(o.SupportSettings.TermsOfServiceLink) { o.SupportSettings.TermsOfServiceLink = nil } @@ -871,6 +892,14 @@ func (o *Config) IsValid() *AppError { return NewLocAppError("Config.IsValid", "model.config.is_valid.listen_address.app_error", nil, "") } + if *o.ClusterSettings.Enable && *o.EmailSettings.EnableEmailBatching { + return NewLocAppError("Config.IsValid", "model.config.is_valid.cluster_email_batching.app_error", nil, "") + } + + if len(*o.ServiceSettings.SiteURL) == 0 && *o.EmailSettings.EnableEmailBatching { + return NewLocAppError("Config.IsValid", "model.config.is_valid.site_url_email_batching.app_error", nil, "") + } + if o.TeamSettings.MaxUsersPerTeam <= 0 { return NewLocAppError("Config.IsValid", "model.config.is_valid.max_users.app_error", nil, "") } @@ -947,6 +976,14 @@ func (o *Config) IsValid() *AppError { return NewLocAppError("Config.IsValid", "model.config.is_valid.email_reset_salt.app_error", nil, "") } + if *o.EmailSettings.EmailBatchingBufferSize <= 0 { + return NewLocAppError("Config.IsValid", "model.config.is_valid.email_batching_buffer_size.app_error", nil, "") + } + + if *o.EmailSettings.EmailBatchingInterval < 30 { + return NewLocAppError("Config.IsValid", "model.config.is_valid.email_batching_interval.app_error", nil, "") + } + if o.RateLimitSettings.MemoryStoreSize <= 0 { return NewLocAppError("Config.IsValid", "model.config.is_valid.rate_mem.app_error", nil, "") } diff --git a/model/preference.go b/model/preference.go index 5787fe6ef..cc35768cb 100644 --- a/model/preference.go +++ b/model/preference.go @@ -17,8 +17,13 @@ const ( PREFERENCE_CATEGORY_ADVANCED_SETTINGS = "advanced_settings" PREFERENCE_CATEGORY_FLAGGED_POST = "flagged_post" - PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings" - PREFERENCE_NAME_COLLAPSE_SETTING = "collapse_previews" + PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings" + PREFERENCE_NAME_COLLAPSE_SETTING = "collapse_previews" + PREFERENCE_NAME_DISPLAY_NAME_FORMAT = "name_format" + PREFERENCE_VALUE_DISPLAY_NAME_NICKNAME = "nickname_full_name" + PREFERENCE_VALUE_DISPLAY_NAME_FULL = "full_name" + PREFERENCE_VALUE_DISPLAY_NAME_USERNAME = "username" + PREFERENCE_DEFAULT_DISPLAY_NAME_FORMAT = PREFERENCE_VALUE_DISPLAY_NAME_USERNAME PREFERENCE_CATEGORY_THEME = "theme" // the name for theme props is the team id @@ -28,6 +33,10 @@ const ( PREFERENCE_CATEGORY_LAST = "last" PREFERENCE_NAME_LAST_CHANNEL = "channel" + + PREFERENCE_CATEGORY_NOTIFICATIONS = "notifications" + PREFERENCE_NAME_EMAIL_INTERVAL = "email_interval" + PREFERENCE_DEFAULT_EMAIL_INTERVAL = "30" // default to match the interval of the "immediate" setting (ie 30 seconds) ) type Preference struct { diff --git a/model/user.go b/model/user.go index bad616d73..d8ad54065 100644 --- a/model/user.go +++ b/model/user.go @@ -295,6 +295,24 @@ func (u *User) GetDisplayName() string { } } +func (u *User) GetDisplayNameForPreference(nameFormat string) string { + displayName := u.Username + + if nameFormat == PREFERENCE_VALUE_DISPLAY_NAME_NICKNAME { + if u.Nickname != "" { + displayName = u.Nickname + } else if fullName := u.GetFullName(); fullName != "" { + displayName = fullName + } + } else if nameFormat == PREFERENCE_VALUE_DISPLAY_NAME_FULL { + if fullName := u.GetFullName(); fullName != "" { + displayName = fullName + } + } + + return displayName +} + func IsValidUserRoles(userRoles string) bool { roles := strings.Split(userRoles, " ") -- cgit v1.2.3-1-g7c22