diff --git a/app/assets/javascripts/admin/templates/dashboard.js.handlebars b/app/assets/javascripts/admin/templates/dashboard.js.handlebars index f011c4e6872..f4e12f4ef5f 100644 --- a/app/assets/javascripts/admin/templates/dashboard.js.handlebars +++ b/app/assets/javascripts/admin/templates/dashboard.js.handlebars @@ -130,7 +130,28 @@ {{ render 'admin_report_counts' likes }} {{ render 'admin_report_counts' flags }} {{ render 'admin_report_counts' emails }} - {{ render 'admin_report_counts' private_messages }} + {{/unless}} + + + +
+ + + + + + + + + + + + {{#unless loading}} + {{ render 'admin_report_counts' user_to_user_private_messages }} + {{ render 'admin_report_counts' system_private_messages }} + {{ render 'admin_report_counts' notify_moderators_private_messages }} + {{ render 'admin_report_counts' notify_user_private_messages }} + {{ render 'admin_report_counts' moderator_warning_private_messages }} {{/unless}}
 {{i18n admin.dashboard.reports.today}}{{i18n admin.dashboard.reports.yesterday}}{{i18n admin.dashboard.reports.last_7_days}}{{i18n admin.dashboard.reports.last_30_days}}{{i18n admin.dashboard.reports.all}}
diff --git a/app/assets/stylesheets/admin/admin_base.scss b/app/assets/stylesheets/admin/admin_base.scss index 337fec6a325..31565b24236 100644 --- a/app/assets/stylesheets/admin/admin_base.scss +++ b/app/assets/stylesheets/admin/admin_base.scss @@ -336,8 +336,8 @@ table { .dashboard-stats { margin-top: 30px; - width: 450px; - margin-left: 40px; + width: 460px; + margin-left: 30px; table { width: 100%; diff --git a/app/models/admin_dashboard_data.rb b/app/models/admin_dashboard_data.rb index f81597dc565..776da4a4334 100644 --- a/app/models/admin_dashboard_data.rb +++ b/app/models/admin_dashboard_data.rb @@ -2,7 +2,21 @@ require_dependency 'mem_info' class AdminDashboardData - REPORTS = ['visits', 'signups', 'topics', 'posts', 'flags', 'users_by_trust_level', 'likes', 'emails', 'private_messages'] + REPORTS = [ + 'visits', + 'signups', + 'topics', + 'posts', + 'flags', + 'users_by_trust_level', + 'likes', + 'emails', + 'user_to_user_private_messages', + 'system_private_messages', + 'moderator_warning_private_messages', + 'notify_moderators_private_messages', + 'notify_user_private_messages' + ] def self.fetch_all AdminDashboardData.new diff --git a/app/models/post.rb b/app/models/post.rb index b4441f17efe..d533a3a72cd 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -42,6 +42,7 @@ class Post < ActiveRecord::Base scope :with_user, includes(:user) scope :public_posts, -> { joins(:topic).where('topics.archetype <> ?', Archetype.private_message) } scope :private_posts, -> { joins(:topic).where('topics.archetype = ?', Archetype.private_message) } + scope :with_topic_subtype, ->(subtype) { joins(:topic).where('topics.subtype = ?', subtype) } def self.hidden_reasons @hidden_reasons ||= Enum.new(:flag_threshold_reached, :flag_threshold_reached_again) @@ -393,11 +394,11 @@ class Post < ActiveRecord::Base Jobs.enqueue(:process_post, args) end - def self.public_posts_count_per_day(sinceDaysAgo=30) - public_posts.where('posts.created_at > ?', sinceDaysAgo.days.ago).group('date(posts.created_at)').order('date(posts.created_at)').count + def self.public_posts_count_per_day(since_days_ago=30) + public_posts.where('posts.created_at > ?', since_days_ago.days.ago).group('date(posts.created_at)').order('date(posts.created_at)').count end - def self.private_messages_count_per_day(sinceDaysAgo=30) - private_posts.where('posts.created_at > ?', sinceDaysAgo.days.ago).group('date(posts.created_at)').order('date(posts.created_at)').count + def self.private_messages_count_per_day(since_days_ago, topic_subtype) + private_posts.with_topic_subtype(topic_subtype).where('posts.created_at > ?', since_days_ago.days.ago).group('date(posts.created_at)').order('date(posts.created_at)').count end end diff --git a/app/models/post_action.rb b/app/models/post_action.rb index a06f5d802bc..a5b1adae24c 100644 --- a/app/models/post_action.rb +++ b/app/models/post_action.rb @@ -73,7 +73,7 @@ class PostAction < ActiveRecord::Base def self.act(user, post, post_action_type_id, message = nil) begin - title, target_usernames,body = nil + title, target_usernames, subtype, body = nil if message [:notify_moderators, :notify_user].each do |k| @@ -84,6 +84,7 @@ class PostAction < ActiveRecord::Base body = I18n.t("post_action_types.#{k}.email_body", message: message, link: "#{Discourse.base_url}#{post.url}") + subtype = k == :notify_moderators ? TopicSubtype.notify_moderators : TopicSubtype.notify_user end end end @@ -92,6 +93,7 @@ class PostAction < ActiveRecord::Base PostCreator.new(user, target_usernames: target_usernames, archetype: Archetype.private_message, + subtype: subtype, title: title, raw: body ).create diff --git a/app/models/report.rb b/app/models/report.rb index c141bb2ca93..24bb394e129 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -1,3 +1,5 @@ +require_dependency 'topic_subtype' + class Report attr_accessor :type, :data, :total, :prev30Days @@ -51,12 +53,6 @@ class Report report.prev30Days = Post.public_posts.where('posts.created_at > ? and posts.created_at < ?', 60.days.ago, 30.days.ago).count end - def self.report_private_messages(report) - basic_report_about report, Post, :private_messages_count_per_day - report.total = Post.private_posts.count - report.prev30Days = Post.private_posts.where('posts.created_at > ? and posts.created_at < ?', 60.days.ago, 30.days.ago).count - end - def self.report_emails(report) report_about report, EmailLog end @@ -66,9 +62,9 @@ class Report add_counts(report, subject_class) end - def self.basic_report_about(report, subject_class, report_method) + def self.basic_report_about(report, subject_class, report_method, *args) report.data = [] - subject_class.send(report_method, 30).each do |date, count| + subject_class.send(report_method, 30, *args).each do |date, count| report.data << {x: date, y: count} end end @@ -109,4 +105,30 @@ class Report report.total = likesQuery.count report.prev30Days = likesQuery.where('created_at > ? and created_at < ?', 60.days.ago, 30.days.ago).count end + + def self.private_messages_report(report, topic_subtype) + basic_report_about report, Post, :private_messages_count_per_day, topic_subtype + report.total = Post.private_posts.with_topic_subtype(topic_subtype).count + report.prev30Days = Post.private_posts.with_topic_subtype(topic_subtype).where('posts.created_at > ? and posts.created_at < ?', 60.days.ago, 30.days.ago).count + end + + def self.report_user_to_user_private_messages(report) + private_messages_report report, TopicSubtype.user_to_user + end + + def self.report_system_private_messages(report) + private_messages_report report, TopicSubtype.system_message + end + + def self.report_moderator_warning_private_messages(report) + private_messages_report report, TopicSubtype.moderator_warning + end + + def self.report_notify_moderators_private_messages(report) + private_messages_report report, TopicSubtype.notify_moderators + end + + def self.report_notify_user_private_messages(report) + private_messages_report report, TopicSubtype.notify_user + end end diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 3b266d75d5a..92921a1ecf9 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -305,8 +305,24 @@ en: title: "Emails Sent" xaxis: "Day" yaxis: "Number of Emails" - private_messages: - title: "Private Messages" + user_to_user_private_messages: + title: "User-to-User Messages" + xaxis: "Day" + yaxis: "Number of private messages" + system_private_messages: + title: "System Messages" + xaxis: "Day" + yaxis: "Number of private messages" + moderator_warning_private_messages: + title: "Moderator Warning Messages" + xaxis: "Day" + yaxis: "Number of private messages" + notify_moderators_private_messages: + title: "Notify Moderators Messages" + xaxis: "Day" + yaxis: "Number of private messages" + notify_user_private_messages: + title: "Nofity User Messages" xaxis: "Day" yaxis: "Number of private messages" diff --git a/db/migrate/20130416170855_add_subtype_to_topics.rb b/db/migrate/20130416170855_add_subtype_to_topics.rb new file mode 100644 index 00000000000..93aa0c32284 --- /dev/null +++ b/db/migrate/20130416170855_add_subtype_to_topics.rb @@ -0,0 +1,10 @@ +class AddSubtypeToTopics < ActiveRecord::Migration + def up + add_column :topics, :subtype, :string + execute "update topics set subtype = 'user_to_user' where archetype = 'private_message'" + end + + def down + remove_column :topics, :subtype + end +end diff --git a/lib/post_creator.rb b/lib/post_creator.rb index 824be4e9856..264a0307a0b 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -42,6 +42,7 @@ class PostCreator if @opts[:topic_id].blank? topic_params = {title: @opts[:title], user_id: @user.id, last_post_user_id: @user.id} topic_params[:archetype] = @opts[:archetype] if @opts[:archetype].present? + topic_params[:subtype] = @opts[:subtype] if @opts[:subtype].present? guardian.ensure_can_create!(Topic) @@ -53,6 +54,8 @@ class PostCreator if @opts[:archetype] == Archetype.private_message + topic.subtype = TopicSubtype.user_to_user unless topic.subtype + usernames = @opts[:target_usernames].split(',') User.where(username: usernames).each do |u| diff --git a/lib/system_message.rb b/lib/system_message.rb index c7ce4bf1ed9..162c3f37bef 100644 --- a/lib/system_message.rb +++ b/lib/system_message.rb @@ -1,5 +1,6 @@ # Handle sending a message to a user from the system. require_dependency 'post_creator' +require_dependency 'topic_subtype' class SystemMessage @@ -33,6 +34,7 @@ class SystemMessage raw: raw_body, title: title, archetype: Archetype.private_message, + subtype: TopicSubtype.system_message, target_usernames: @recipient.username) end diff --git a/lib/topic_subtype.rb b/lib/topic_subtype.rb new file mode 100644 index 00000000000..5d5e459532d --- /dev/null +++ b/lib/topic_subtype.rb @@ -0,0 +1,52 @@ +class TopicSubtype + include ActiveModel::Serialization + + attr_accessor :id, :options + + def initialize(id, options) + @id = id + @options = options + end + + def attributes + {'id' => @id, + 'options' => @options} + end + + def self.list + return [] unless @archetypes.present? + @archetypes.values + end + + def self.user_to_user + 'user_to_user' + end + + def self.system_message + 'system_message' + end + + def self.moderator_warning + 'moderator_warning' + end + + def self.notify_moderators + 'notify_moderators' + end + + def self.notify_user + 'notify_user' + end + + def self.register(name, options={}) + @subtypes ||= {} + @subtypes[name] = TopicSubtype.new(name, options) + end + + register 'user_to_user' + register 'system_message' + register 'moderator_warning' + register 'notify_moderators' + register 'notify_user' + +end \ No newline at end of file diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb index 2a0c184c533..633270aa875 100644 --- a/spec/components/post_creator_spec.rb +++ b/spec/components/post_creator_spec.rb @@ -1,5 +1,6 @@ require 'spec_helper' require 'post_creator' +require 'topic_subtype' describe PostCreator do @@ -173,22 +174,28 @@ describe PostCreator do context 'private message' do let(:target_user1) { Fabricate(:coding_horror) } let(:target_user2) { Fabricate(:moderator) } - let(:post) do - PostCreator.create(user, title: 'hi there welcome to my topic', - raw: 'this is my awesome message', - archetype: Archetype.private_message, - target_usernames: [target_user1.username, target_user2.username].join(',')) - end - it 'has the right archetype' do - post.topic.archetype.should == Archetype.private_message - end + describe 'regular user to user' do + let(:post) do + PostCreator.create(user, title: 'hi there welcome to my topic', + raw: 'this is my awesome message', + archetype: Archetype.private_message, + target_usernames: [target_user1.username, target_user2.username].join(',')) + end - it 'has the right count (me and 2 other users)' do - post.topic.topic_allowed_users.count.should == 3 + it 'has the right archetype' do + post.topic.archetype.should == Archetype.private_message + end + + it 'has the right count (me and 2 other users)' do + post.topic.topic_allowed_users.count.should == 3 + end + + it 'has the right subtype' do + post.topic.subtype.should == TopicSubtype.user_to_user + end end end - end diff --git a/spec/components/system_message_spec.rb b/spec/components/system_message_spec.rb index 640a4cece62..2a976f55095 100644 --- a/spec/components/system_message_spec.rb +++ b/spec/components/system_message_spec.rb @@ -1,5 +1,6 @@ require 'spec_helper' require 'system_message' +require 'topic_subtype' describe SystemMessage do @@ -20,6 +21,10 @@ describe SystemMessage do topic.should be_private_message end + it 'should have the correct topic subtype' do + topic.subtype.should == TopicSubtype.system_message + end + it 'should be visible by the user' do topic.allowed_users.include?(user).should be_true end diff --git a/spec/fabricators/post_fabricator.rb b/spec/fabricators/post_fabricator.rb index 4274891eda4..efa83f59a3f 100644 --- a/spec/fabricators/post_fabricator.rb +++ b/spec/fabricators/post_fabricator.rb @@ -68,6 +68,7 @@ Fabricator(:private_message_post, from: :post) do Fabricate( :private_message_topic, user: attrs[:user], created_at: attrs[:created_at], + subtype: TopicSubtype.user_to_user, topic_allowed_users: [ Fabricate.build(:topic_allowed_user, user_id: attrs[:user].id), Fabricate.build(:topic_allowed_user, user_id: Fabricate(:user).id) diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb index 7cf66991772..f76de86309e 100644 --- a/spec/models/post_action_spec.rb +++ b/spec/models/post_action_spec.rb @@ -18,19 +18,43 @@ describe PostAction do let(:bookmark) { PostAction.new(user_id: post.user_id, post_action_type_id: PostActionType.types[:bookmark] , post_id: post.id) } describe "messaging" do - it "sends an email to all moderators if selected" do - PostAction.stubs(:create) - PostAction.expects(:target_moderators).returns("bob") - PostCreator.any_instance.expects(:create).returns(nil) - PostAction.act(build(:user), build(:post), PostActionType.types[:notify_moderators], "this is my special message"); + describe 'notify_moderators' do + before do + PostAction.stubs(:create) + PostAction.expects(:target_moderators).returns("bob") + end + + it "sends an email to all moderators if selected" do + PostCreator.any_instance.expects(:create).returns(nil) + PostAction.act(build(:user), build(:post), PostActionType.types[:notify_moderators], "this is my special message"); + end + + it "uses the correct topic subtype" do + PostCreator.expects(:new).with do |user, opts| + opts[:subtype] == TopicSubtype.notify_moderators + end.returns(stub_everything) + PostAction.act(build(:user), build(:post), PostActionType.types[:notify_moderators], "this is my special message"); + end end - it "sends an email to user if selected" do - PostAction.stubs(:create) - PostCreator.any_instance.expects(:create).returns(nil) - post = build(:post) - post.user = build(:user) - PostAction.act(build(:user), post, PostActionType.types[:notify_user], "this is my special message"); + describe "notify_user" do + before do + PostAction.stubs(:create) + post = build(:post) + post.user = build(:user) + end + + it "sends an email to user if selected" do + PostCreator.any_instance.expects(:create).returns(nil) + PostAction.act(build(:user), post, PostActionType.types[:notify_user], "this is my special message"); + end + + it "uses the correct topic subtype" do + PostCreator.expects(:new).with do |user, opts| + opts[:subtype] == TopicSubtype.notify_user + end.returns(stub_everything) + PostAction.act(build(:user), post, PostActionType.types[:notify_user], "this is my special message"); + end end end diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index f283f34961f..a172ba294f5 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -61,7 +61,7 @@ describe Report do end describe 'private messages' do - let(:report) { Report.find('private_messages') } + let(:report) { Report.find('user_to_user_private_messages') } it 'topic report should not include private messages' do Fabricate(:private_message_topic, created_at: 1.hour.ago)