diff --git a/app/jobs/regular/notify_mailing_list_subscribers.rb b/app/jobs/regular/notify_mailing_list_subscribers.rb
new file mode 100644
index 00000000000..31ac2d5e85d
--- /dev/null
+++ b/app/jobs/regular/notify_mailing_list_subscribers.rb
@@ -0,0 +1,37 @@
+module Jobs
+
+ class NotifyMailingListSubscribers < Jobs::Base
+
+ def execute(args)
+ post_id = args[:post_id]
+ post = Post.find(post_id) if post_id
+
+ raise Discourse::InvalidParameters.new(:post_id) unless post
+
+ User.not_suspended
+ .not_blocked
+ .real
+ .where(mailing_list_mode: true)
+ .where('NOT EXISTS(
+ SELECT 1
+ FROM topic_users tu
+ WHERE
+ tu.topic_id = ? AND
+ tu.user_id = users.id AND
+ tu.notification_level = ?
+ )', post.topic_id, TopicUser.notification_levels[:muted])
+ .where('NOT EXISTS(
+ SELECT 1
+ FROM category_users cu
+ WHERE
+ cu.category_id = ? AND
+ cu.user_id = users.id AND
+ cu.notification_level = ?
+ )', post.topic.category_id, CategoryUser.notification_levels[:muted])
+ .each do |user|
+ UserNotifications.mailing_list_notify(user, post).deliver
+ end
+
+ end
+ end
+end
diff --git a/app/mailers/user_notifications.rb b/app/mailers/user_notifications.rb
index f2d5cd661bc..bea3c7e45be 100644
--- a/app/mailers/user_notifications.rb
+++ b/app/mailers/user_notifications.rb
@@ -93,6 +93,17 @@ class UserNotifications < ActionMailer::Base
notification_email(user, opts)
end
+ def mailing_list_notify(user, post)
+ send_notification_email(
+ title: post.topic.title,
+ post: post,
+ from_alias: post.user.username,
+ allow_reply_by_email: true,
+ notification_type: "posted",
+ user: user
+ )
+ end
+
protected
def email_post_markdown(post)
@@ -130,9 +141,34 @@ class UserNotifications < ActionMailer::Base
username = @notification.data_hash[:original_username]
notification_type = opts[:notification_type] || Notification.types[@notification.notification_type].to_s
+ return if SiteSetting.enable_mailing_list_mode &&
+ ["replied", "mentioned", "quoted", "posted"].include?(notification_type)
+
+ title = @notification.data_hash[:topic_title]
+ allow_reply_by_email = opts[:allow_reply_by_email]
+
+ send_notification_email(
+ title: title,
+ post: @post,
+ from_alias: username,
+ allow_reply_by_email: allow_reply_by_email,
+ notification_type: notification_type,
+ user: user
+ )
+
+ end
+
+ def send_notification_email(opts)
+ post = opts[:post]
+ title = opts[:title]
+ allow_reply_by_email = opts[:allow_reply_by_email]
+ from_alias = opts[:from_alias]
+ notification_type = opts[:notification_type]
+ user = opts[:user]
+
context = ""
- tu = TopicUser.get(@post.topic_id, user)
- context_posts = self.class.get_context_posts(@post, tu)
+ tu = TopicUser.get(post.topic_id, user)
+ context_posts = self.class.get_context_posts(post, tu)
# make .present? cheaper
context_posts = context_posts.to_a
@@ -147,37 +183,36 @@ class UserNotifications < ActionMailer::Base
html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render(
template: 'email/notification',
format: :html,
- locals: { context_posts: context_posts, post: @post }
+ locals: { context_posts: context_posts, post: post }
)
template = "user_notifications.user_#{notification_type}"
- if @post.topic.private_message?
+ if post.topic.private_message?
template << "_pm"
end
email_opts = {
- topic_title: @notification.data_hash[:topic_title],
- message: email_post_markdown(@post),
- url: @post.url,
- post_id: @post.id,
- topic_id: @post.topic_id,
+ topic_title: title,
+ message: email_post_markdown(post),
+ url: post.url,
+ post_id: post.id,
+ topic_id: post.topic_id,
context: context,
- username: username,
+ username: from_alias,
add_unsubscribe_link: true,
- allow_reply_by_email: opts[:allow_reply_by_email],
+ allow_reply_by_email: allow_reply_by_email,
template: template,
html_override: html,
style: :notification
}
# If we have a display name, change the from address
- if username.present?
- email_opts[:from_alias] = username
+ if from_alias.present?
+ email_opts[:from_alias] = from_alias
end
- TopicUser.change(user.id, @post.topic_id, last_emailed_post_number: @post.post_number)
+ TopicUser.change(user.id, post.topic_id, last_emailed_post_number: post.post_number)
build_email(user.email, email_opts)
end
-
end
diff --git a/app/models/topic_user.rb b/app/models/topic_user.rb
index b69216b800a..ba64e223874 100644
--- a/app/models/topic_user.rb
+++ b/app/models/topic_user.rb
@@ -72,23 +72,6 @@ class TopicUser < ActiveRecord::Base
TopicUser.where('topic_id = ? and user_id = ?', topic, user).first
end
- def auto_watch_new_topic(topic_id)
- # Can not afford to slow down creation of topics when a pile of users are watching new topics, reverting to SQL for max perf here
- sql = < { where(blocked: true) } # no index
+ scope :not_blocked, -> { where(blocked: false) } # no index
scope :suspended, -> { where('suspended_till IS NOT NULL AND suspended_till > ?', Time.zone.now) } # no index
scope :not_suspended, -> { where('suspended_till IS NULL') }
# excluding fake users like the community user
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index f7f30c17c88..411e306a0ab 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -51,7 +51,7 @@ class UserSerializer < BasicUserSerializer
:email_direct,
:email_always,
:digest_after_days,
- :watch_new_topics,
+ :mailing_list_mode,
:auto_track_topics_after_msecs,
:new_topic_duration_minutes,
:external_links_in_new_tab,
diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb
index 40801d664d1..ade9dd64c72 100644
--- a/app/services/user_updater.rb
+++ b/app/services/user_updater.rb
@@ -14,7 +14,7 @@ class UserUpdater
:external_links_in_new_tab,
:enable_quoting,
:dynamic_favicon,
- :watch_new_topics
+ :mailing_list_mode
]
def initialize(actor, user)
diff --git a/config/locales/client.da.yml b/config/locales/client.da.yml
index 4423b7ec7ed..11cb97bce33 100644
--- a/config/locales/client.da.yml
+++ b/config/locales/client.da.yml
@@ -229,7 +229,6 @@ da:
deleted: "(slettet)"
suspended_notice: "Denne bruger er suspenderet indtil {{date}}."
suspended_reason: "Begrundelse: "
- watch_new_topics: "Overvåg automatisk alle nye emner i forummet"
watched_categories: "Overvåget"
watched_categories_instructions: "Du overvåger automatisk alle emner i disse kategorier"
tracked_categories: "Fulgt"
diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml
index 363e378e8a5..c0292426331 100644
--- a/config/locales/client.de.yml
+++ b/config/locales/client.de.yml
@@ -230,7 +230,6 @@ de:
deleted: "(gelöscht)"
suspended_notice: "Diser Benutzer ist bis zum {{date}} susperndiert."
suspended_reason: "Grund: "
- watch_new_topics: "Automatische alle neuen Themen dieses Forums beobachten"
watched_categories: "Beobachten"
watched_categories_instructions: "Das selbe wie 'verfolgen', zusätzlich wirst du über alle neuen Beiträge und Themen informiert."
tracked_categories: "Verfolgen"
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index d8bccf977eb..08928b2b44f 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -231,7 +231,7 @@ en:
deleted: "(deleted)"
suspended_notice: "This user is suspended until {{date}}."
suspended_reason: "Reason: "
- watch_new_topics: "Automatically watch all new topics posted on the forum"
+ mailing_list_mode: "Automatically recieve an email every time a post is made on the forum (unless you have the topic or category muted)"
watched_categories: "Watched"
watched_categories_instructions: "Same as Tracking, plus you will be notified of all new posts and topics."
tracked_categories: "Tracked"
diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml
index c5a009596a5..f0ee7401337 100644
--- a/config/locales/client.fr.yml
+++ b/config/locales/client.fr.yml
@@ -229,7 +229,6 @@ fr:
deleted: "(supprimé)"
suspended_notice: "L'utilisateur est suspendu jusqu'au {{date}}."
suspended_reason: "Raison :"
- watch_new_topics: "Surveiller automatiquement toutes les nouvelles discussions postées sur le forum"
watched_categories: "Surveillées"
watched_categories_instructions: "Vous allez surveiller automatiquement toutes les discussions de ces catégories"
tracked_categories: "Suivies"
diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml
index 513689274d1..1e4c084479b 100644
--- a/config/locales/client.nl.yml
+++ b/config/locales/client.nl.yml
@@ -233,7 +233,6 @@ nl:
deleted: (verwijderd)
suspended_notice: "Deze gebruiker is geschorst tot {{date}}."
suspended_reason: "Reden: "
- watch_new_topics: "Houd alle nieuwe topics in het forum automatisch in de gaten"
watched_categories: "In de gaten gehouden"
watched_categories_instructions: "Zelfde als volgen, daarnaast zou je een notificatie ontvangen voor alle nieuwe berichten en topics"
tracked_categories: "Gevolgd"
diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml
index 0cc6afcf0ec..44fb33e9be2 100644
--- a/config/locales/client.zh_CN.yml
+++ b/config/locales/client.zh_CN.yml
@@ -229,7 +229,6 @@ zh_CN:
deleted: "(已删除)"
suspended_notice: "该用户将被禁止登录,直至{{date}}."
suspended_reason: "原因:"
- watch_new_topics: "自动关注论坛中所有新发表的主题"
watched_categories: "已关注"
watched_categories_instructions: "和跟踪相同,此外你还将收到新的帖子和主题的通知。"
tracked_categories: "已跟踪"
diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml
index 600f8a6e004..7ccd13d0155 100644
--- a/config/locales/server.da.yml
+++ b/config/locales/server.da.yml
@@ -749,7 +749,6 @@ da:
pop3s_polling_host: "Host til polling af POP3S-konto."
pop3s_polling_username: "Brugernavn til polling af POP3S-konto."
pop3s_polling_password: "Adgangskode til polling af POP3S-konto."
- enable_watch_new_topics: "Lad brugerne overvåge alle nye emner (valgfrit) via en brugerindstilling"
minimum_topics_similar: "Hvor emner der skal eksistere i databasen før der vises tilsvarende emner."
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 363d3de9d45..ca4d099f09a 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -761,7 +761,7 @@ en:
pop3s_polling_host: "The host to poll for email via POP3S"
pop3s_polling_username: "The username for the POP3S account to poll for email"
pop3s_polling_password: "The password for the POP3S account to poll for email"
- enable_watch_new_topics: "Allow users to watch all new topics (optionally) via a user preference"
+ enable_mailing_list_mode: "Allow users to (optionally) opt-in to mailing list mode via a user preference"
minimum_topics_similar: "How many topics need to exist in the database before similar topics are presented."
diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml
index 5ae5b133239..cda482b48d1 100644
--- a/config/locales/server.fr.yml
+++ b/config/locales/server.fr.yml
@@ -663,7 +663,6 @@ fr:
pop3s_polling_host: "L'hôte utilisé pour le polling pour l'email via POP3S"
pop3s_polling_username: "Le nom d'utilisateur pour le polling POPS3 par email"
pop3s_polling_password: "Le mot de passe pour le polling POPS3 par email"
- enable_watch_new_topics: "Autoriser les utilisateurs à suivre toutes les nouvelles discussions (optionnellement) via une préférence de l'utilisateur"
minimum_topics_similar: "Combien de topics ont besoin d'exister dans la base de données avant que des topics similaires soit présentés."
relative_date_duration: "Nombre de jours après la création d'un message à partir desquels les dates seront affichées en absolu plutôt qu'en relatif. Exemple: relatif : 7j, absolut : 20 Fév"
delete_user_max_age: "L'age maximum d'un utilisateur, en jours, qui permet à un administrateur de le supprimer."
diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml
index 4508dec7a76..3308a42b4e0 100644
--- a/config/locales/server.nl.yml
+++ b/config/locales/server.nl.yml
@@ -753,7 +753,6 @@ nl:
pop3s_polling_host: "De host voor POP3S"
pop3s_polling_username: "De username voor het POP3S e-mailaccount"
pop3s_polling_password: "Het wachtwoord voor het POP3S e-mailaccount"
- enable_watch_new_topics: "Sta toe dat gebruikers alle nieuwe topics in de gaten houden (optioneel) via hun gebruikersinstellingen"
minimum_topics_similar: "Hoeveel topics moeten er in de database staan voordat er vergelijkbare topics getoond worden?"
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 5b43ab241ec..ebe34472984 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -232,7 +232,7 @@ email:
pop3s_polling_port: 995
pop3s_polling_username: ''
pop3s_polling_password: ''
- enable_watch_new_topics:
+ enable_mailing_list_mode:
default: false
client: true
diff --git a/db/migrate/20140206215029_add_mailing_list_mode_to_users.rb b/db/migrate/20140206215029_add_mailing_list_mode_to_users.rb
new file mode 100644
index 00000000000..c4de0991fda
--- /dev/null
+++ b/db/migrate/20140206215029_add_mailing_list_mode_to_users.rb
@@ -0,0 +1,5 @@
+class AddMailingListModeToUsers < ActiveRecord::Migration
+ def change
+ rename_column :users, :watch_new_topics, :mailing_list_mode
+ end
+end
diff --git a/lib/post_creator.rb b/lib/post_creator.rb
index fd57cd80c82..46f5ecce994 100644
--- a/lib/post_creator.rb
+++ b/lib/post_creator.rb
@@ -135,8 +135,17 @@ class PostCreator
end
def after_post_create
- if !@topic.private_message? && @post.post_number > 1 && @post.post_type != Post.types[:moderator_action]
- TopicTrackingState.publish_unread(@post)
+ if !@topic.private_message? && @post.post_type != Post.types[:moderator_action]
+ if @post.post_number > 1
+ TopicTrackingState.publish_unread(@post)
+ end
+ if SiteSetting.enable_mailing_list_mode
+ Jobs.enqueue_in(
+ SiteSetting.email_time_window_mins.minutes,
+ :notify_mailing_list_subscribers,
+ post_id: @post.id
+ )
+ end
end
end
diff --git a/lib/topic_creator.rb b/lib/topic_creator.rb
index 37a497446b2..62202f4c6a9 100644
--- a/lib/topic_creator.rb
+++ b/lib/topic_creator.rb
@@ -39,7 +39,6 @@ class TopicCreator
@topic.notifier.watch_topic!(id, nil)
end
- TopicUser.auto_watch_new_topic(@topic.id)
CategoryUser.auto_watch_new_topic(@topic)
end
diff --git a/spec/models/topic_user_spec.rb b/spec/models/topic_user_spec.rb
index cccaf2acd9b..4e11d9c3b2f 100644
--- a/spec/models/topic_user_spec.rb
+++ b/spec/models/topic_user_spec.rb
@@ -268,21 +268,28 @@ describe TopicUser do
tu.seen_post_count.should == 2
end
- describe "auto_watch_new_topic" do
+ describe "mailing_list_mode" do
+
+ it "will receive email notification for every topic" do
+ SiteSetting.stubs(:enable_mailing_list_mode).returns(true)
- it "auto watches topics when called" do
user1 = Fabricate(:user)
- user2 = Fabricate(:user, watch_new_topics: true)
- user3 = Fabricate(:user, watch_new_topics: true)
- TopicUser.auto_watch_new_topic(topic.id)
+ user2 = Fabricate(:user, mailing_list_mode: true)
+ post = create_post
+ user3 = Fabricate(:user, mailing_list_mode: true)
+ create_post(topic_id: post.topic_id)
- TopicUser.get(topic, user1).should == nil
+ # mails posts from earlier topics
+ tu = TopicUser.where(user_id: user3.id, topic_id: post.topic_id).first
+ tu.last_emailed_post_number.should == 2
- tu = TopicUser.get(topic, user2)
- tu.notification_level.should == TopicUser.notification_levels[:watching]
- tu.notifications_reason_id.should == TopicUser.notification_reasons[:auto_watch]
+ # mails nothing to random users
+ tu = TopicUser.where(user_id: user1.id, topic_id: post.topic_id).first
+ tu.should be_nil
- TopicUser.get(topic, user3).notification_level.should == TopicUser.notification_levels[:watching]
+ # mails other user
+ tu = TopicUser.where(user_id: user2.id, topic_id: post.topic_id).first
+ tu.last_emailed_post_number.should == 2
end
end