diff --git a/app/models/activity_feed_observer.rb b/app/models/activity_feed_observer.rb deleted file mode 100644 index 85ca47126..000000000 --- a/app/models/activity_feed_observer.rb +++ /dev/null @@ -1,185 +0,0 @@ -# -*- encoding : utf-8 -*- -class ActivityFeedObserver < ActiveRecord::Observer - observe :issue, :comment, :user, :build_list - - BUILD_LIST_STATUSES = [ - BuildList::BUILD_PUBLISHED, - BuildList::SUCCESS, - BuildList::BUILD_ERROR, - BuildList::FAILED_PUBLISH, - BuildList::TESTS_FAILED - ].freeze - - def after_create(record) - case record.class.to_s - when 'User' - ActivityFeed.create( - :user => record, - :kind => 'new_user_notification', - :data => {:user_name => record.user_appeal, :user_email => record.email} - ) - - when 'Issue' - record.collect_recipients.each do |recipient| - next if record.user_id == recipient.id - UserMailer.new_issue_notification(record, recipient).deliver if recipient.notifier.can_notify && recipient.notifier.new_issue - ActivityFeed.create( - :user => recipient, - :kind => 'new_issue_notification', - :data => {:user_name => record.user.name, :user_email => record.user.email, :user_id => record.user_id,:issue_serial_id => record.serial_id, - :issue_title => record.title, :project_id => record.project.id, :project_name => record.project.name, :project_owner => record.project.owner.uname} - ) - end - - if record.assignee_id_changed? - UserMailer.new_issue_notification(record, record.assignee).deliver if record.assignee.notifier.issue_assign && record.assignee.notifier.can_notify - ActivityFeed.create( - :user => record.user, - :kind => 'issue_assign_notification', - :data => {:user_name => record.user.name, :user_email => record.user.email, :user_id => record.user_id, :issue_serial_id => record.serial_id, - :project_id => record.project.id, :issue_title => record.title, :project_name => record.project.name, :project_owner => record.project.owner.uname} - ) - end - record.project.hooks.each{ |h| h.receive_issues(record, :create) } - Comment.create_link_on_issues_from_item(record) - when 'Comment' - return if record.automatic - if record.issue_comment? - subscribes = record.commentable.subscribes - subscribes.each do |subscribe| - if record.user_id != subscribe.user_id - UserMailer.new_comment_notification(record, subscribe.user).deliver if record.can_notify_on_new_comment?(subscribe) - ActivityFeed.create( - :user => subscribe.user, - :kind => 'new_comment_notification', - :data => {:user_name => record.user.name, :user_email => record.user.email, :user_id => record.user_id, :comment_body => record.body, - :issue_title => record.commentable.title, :issue_serial_id => record.commentable.serial_id, :project_id => record.commentable.project.id, - :comment_id => record.id, :project_name => record.project.name, :project_owner => record.project.owner.uname} - ) - end - end - elsif record.commit_comment? - subscribes = Subscribe.comment_subscribes(record).where(:status => true) - subscribes.each do |subscribe| - next if record.own_comment?(subscribe.user) - if subscribe.user.notifier.can_notify and - ( (subscribe.project.owner?(subscribe.user) && subscribe.user.notifier.new_comment_commit_repo_owner) or - (subscribe.user.commentor?(record.commentable) && subscribe.user.notifier.new_comment_commit_commentor) or - (subscribe.user.committer?(record.commentable) && subscribe.user.notifier.new_comment_commit_owner) ) - UserMailer.new_comment_notification(record, subscribe.user).deliver - end - ActivityFeed.create( - :user => subscribe.user, - :kind => 'new_comment_commit_notification', - :data => {:user_name => record.user.name, :user_email => record.user.email, :user_id => record.user_id, :comment_body => record.body, - :commit_message => record.commentable.message, :commit_id => record.commentable.id, - :project_id => record.project.id, :comment_id => record.id, :project_name => record.project.name, :project_owner => record.project.owner.uname} - ) - end - end - Comment.create_link_on_issues_from_item(record) - - when 'GitHook' - return unless record.project - PullRequest.where("from_project_id = ? OR to_project_id = ?", record.project, record.project).needed_checking.each {|pull| pull.check} - record.project.hooks.each{ |h| h.receive_push(record) } - - change_type = record.change_type - branch_name = record.refname.split('/').last - - if change_type == 'delete' - kind = 'git_delete_branch_notification' - options = {:project_id => record.project.id, :project_name => record.project.name, :branch_name => branch_name, - :change_type => change_type, :project_owner => record.project.owner.uname} - else - if record.message # online update - last_commits, commits = [[record.newrev, record.message]], [] - all_commits = last_commits - else - commits = record.project.repo.commits_between(record.oldrev, record.newrev) - all_commits = commits.collect { |commit| [commit.sha, commit.message] } - last_commits = all_commits.last(3).reverse - end - - kind = 'git_new_push_notification' - options = {:project_id => record.project.id, :project_name => record.project.name, :last_commits => last_commits, - :branch_name => branch_name, :change_type => change_type, :project_owner => record.project.owner.uname} - if commits.count > 3 - commits = commits[0...-3] - options.merge!({:other_commits_count => commits.count, :other_commits => "#{commits[0].sha[0..9]}...#{commits[-1].sha[0..9]}"}) - end - Comment.create_link_on_issues_from_item(record, all_commits) if all_commits.count > 0 - end - options.merge!({:user_id => record.user.id, :user_name => record.user.name, :user_email => record.user.email}) if record.user - - record.project.admins.each do |recipient| - next if record.user && record.user.id == recipient.id - ActivityFeed.create!( - :user => recipient, - :kind => kind, - :data => options - ) - end - - when 'Hash' # 'Gollum::Committer' - actor = User.find_by_uname! record[:actor_name] - project = Project.find record[:project_id] - - project.admins.each do |recipient| - ActivityFeed.create!( - :user => recipient, - :kind => 'wiki_new_commit_notification', - :data => {:user_id => actor.id, :user_name => actor.name, :user_email => actor.email, :project_id => project.id, - :project_name => project.name, :commit_sha => record[:commit_sha], :project_owner => project.owner.uname} - ) - end - end - end - - def after_update(record) - case record.class.to_s - when 'Issue' - if record.assignee_id && record.assignee_id_changed? - UserMailer.issue_assign_notification(record, record.assignee).deliver if record.assignee.notifier.issue_assign && record.assignee.notifier.can_notify - ActivityFeed.create( - :user => record.assignee, - :kind => 'issue_assign_notification', - :data => {:user_name => record.assignee.name, :user_email => record.assignee.email, :issue_serial_id => record.serial_id, :issue_title => record.title, - :project_id => record.project.id, :project_name => record.project.name, :project_owner => record.project.owner.uname} - ) - end - record.project.hooks.each{ |h| h.receive_issues(record, :update) } if record.status_changed? - # dont remove outdated issues link - Comment.create_link_on_issues_from_item(record) - when 'BuildList' - if record.mass_build.blank? && ( # Do not show mass build activity in activity feeds - record.status_changed? && BUILD_LIST_STATUSES.include?(record.status) || - record.status == BuildList::BUILD_PENDING && record.bs_id_changed? - ) - - record.project.admins.each do |recipient| - user = record.publisher || record.user - ActivityFeed.create( - :user => recipient, - :kind => 'build_list_notification', - :data => { - :task_num => record.bs_id, - :build_list_id => record.id, - :status => record.status, - :updated_at => record.updated_at, - :project_id => record.project_id, - :project_name => record.project.name, - :project_owner => record.project.owner.uname, - :user_name => user.name, - :user_email => user.email, - :user_id => user.id - } - ) - end - end - when 'Comment' - # dont remove outdated issues link - Comment.create_link_on_issues_from_item(record) - end - end -end diff --git a/app/models/build_list.rb b/app/models/build_list.rb index 7ab46c41c..adf967c07 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -3,6 +3,7 @@ class BuildList < ActiveRecord::Base include Modules::Models::CommitAndVersion include Modules::Models::FileStoreClean include AbfWorker::ModelHelper + include Modules::Observers::ActivityFeed::BuildList belongs_to :project belongs_to :arch diff --git a/app/models/comment.rb b/app/models/comment.rb index f78148b86..7272d6a9b 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,5 +1,7 @@ # -*- encoding : utf-8 -*- class Comment < ActiveRecord::Base + include Modules::Observers::ActivityFeed::Comment + # regexp take from http://code.google.com/p/concerto-platform/source/browse/v3/cms/lib/CodeMirror/mode/gfm/gfm.js?spec=svn861&r=861#71 # User/Project#Num # User#Num @@ -54,10 +56,6 @@ class Comment < ActiveRecord::Base user_id == user.id end - def can_notify_on_new_comment?(subscribe) - User.find(subscribe.user).notifier.new_comment && User.find(subscribe.user).notifier.can_notify - end - def actual_inline_comment?(diff = nil, force = false) unless force raise "This is not inline comment!" if data.blank? # for debug diff --git a/app/models/git_hook.rb b/app/models/git_hook.rb index 0aef7df8a..d13829002 100644 --- a/app/models/git_hook.rb +++ b/app/models/git_hook.rb @@ -65,7 +65,7 @@ class GitHook end def self.process(*args) - ActivityFeedObserver.instance.after_create(args.size > 1 ? GitHook.new(*args) : args.first) + Modules::Observers::ActivityFeed::Git.create_notifications(args.size > 1 ? GitHook.new(*args) : args.first) end def find_user(user) diff --git a/app/models/issue.rb b/app/models/issue.rb index c9236a489..9e043eb0a 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1,5 +1,6 @@ # -*- encoding : utf-8 -*- class Issue < ActiveRecord::Base + include Modules::Observers::ActivityFeed::Issue STATUSES = ['open', 'closed'] belongs_to :project diff --git a/app/models/user.rb b/app/models/user.rb index a53f530e1..1c4322cc2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -60,6 +60,7 @@ class User < Avatar include Modules::Models::PersonalRepository include Modules::Models::ActsLikeMember + include Modules::Observers::ActivityFeed::User def admin? role == 'admin' diff --git a/config/application.rb b/config/application.rb index 13f0a15c1..c51dde67b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -34,7 +34,7 @@ module Rosa # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Activate observers that should always be running. - config.active_record.observers = :event_log_observer, :activity_feed_observer, :build_list_observer + config.active_record.observers = :event_log_observer, :build_list_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. diff --git a/lib/modules/models/git.rb b/lib/modules/models/git.rb index 43cc16965..6d96bd851 100644 --- a/lib/modules/models/git.rb +++ b/lib/modules/models/git.rb @@ -150,7 +150,7 @@ module Modules module ClassMethods def process_hook(owner_uname, repo, newrev, oldrev, ref, newrev_type, user = nil, message = nil) rec = GitHook.new(owner_uname, repo, newrev, oldrev, ref, newrev_type, user, message) - ActivityFeedObserver.instance.after_create rec + Modules::Observers::ActivityFeed::Git.create_notifications rec end end end diff --git a/lib/modules/observers/activity_feed/build_list.rb b/lib/modules/observers/activity_feed/build_list.rb new file mode 100644 index 000000000..1873f01e4 --- /dev/null +++ b/lib/modules/observers/activity_feed/build_list.rb @@ -0,0 +1,46 @@ +# -*- encoding : utf-8 -*- +module Modules::Observers::ActivityFeed::BuildList + extend ActiveSupport::Concern + + included do + after_update :build_list_notifications + end + + private + + def build_list_notifications + if mass_build.blank? && ( # Do not show mass build activity in activity feeds + status_changed? && [ + BuildList::BUILD_PUBLISHED, + BuildList::SUCCESS, + BuildList::BUILD_ERROR, + BuildList::FAILED_PUBLISH, + BuildList::TESTS_FAILED + ].include?(status) || + status == BuildList::BUILD_PENDING && bs_id_changed? + ) + + updater = publisher || user + project.admins.each do |recipient| + ActivityFeed.create( + :user => recipient, + :kind => 'build_list_notification', + :data => { + :task_num => bs_id, + :build_list_id => id, + :status => status, + :updated_at => updated_at, + :project_id => project_id, + :project_name => project.name, + :project_owner => project.owner.uname, + :user_name => updater.name, + :user_email => updater.email, + :user_id => updater.id + } + ) + end + + end + end + +end \ No newline at end of file diff --git a/lib/modules/observers/activity_feed/comment.rb b/lib/modules/observers/activity_feed/comment.rb new file mode 100644 index 000000000..0327fcb12 --- /dev/null +++ b/lib/modules/observers/activity_feed/comment.rb @@ -0,0 +1,70 @@ +# -*- encoding : utf-8 -*- +module Modules::Observers::ActivityFeed::Comment + extend ActiveSupport::Concern + + included do + after_commit :new_comment_notifications, :on => :create + # dont remove outdated issues link + after_update -> { Comment.create_link_on_issues_from_item(self) } + end + + private + + def new_comment_notifications + return if automatic? + if issue_comment? + commentable.subscribes.each do |subscribe| + if user_id != subscribe.user_id + UserMailer.new_comment_notification(self, subscribe.user).deliver if can_notify_on_new_comment?(subscribe) + ActivityFeed.create( + :user => subscribe.user, + :kind => 'new_comment_notification', + :data => { + :user_name => user.name, + :user_email => user.email, + :user_id => user_id, + :comment_body => body, + :issue_title => commentable.title, + :issue_serial_id => commentable.serial_id, + :project_id => commentable.project.id, + :comment_id => id, + :project_name => project.name, + :project_owner => project.owner.uname + } + ) + end + end + elsif commit_comment? + Subscribe.comment_subscribes(self).where(:status => true).each do |subscribe| + next if own_comment?(subscribe.user) + if subscribe.user.notifier.can_notify and + ( (subscribe.project.owner?(subscribe.user) && subscribe.user.notifier.new_comment_commit_repo_owner) or + (subscribe.user.commentor?(self.commentable) && subscribe.user.notifier.new_comment_commit_commentor) or + (subscribe.user.committer?(self.commentable) && subscribe.user.notifier.new_comment_commit_owner) ) + UserMailer.new_comment_notification(self, subscribe.user).deliver + end + ActivityFeed.create( + :user => subscribe.user, + :kind => 'new_comment_commit_notification', + :data => { + :user_name => user.name, + :user_email => user.email, + :user_id => user_id, + :comment_body => body, + :commit_message => commentable.message, + :commit_id => commentable.id, + :project_id => project.id, + :comment_id => id, + :project_name => project.name, + :project_owner => project.owner.uname} + ) + end + end + Comment.create_link_on_issues_from_item(self) + end + + def can_notify_on_new_comment?(subscribe) + User.find(subscribe.user).notifier.new_comment && User.find(subscribe.user).notifier.can_notify + end + +end \ No newline at end of file diff --git a/lib/modules/observers/activity_feed/git.rb b/lib/modules/observers/activity_feed/git.rb new file mode 100644 index 000000000..cf5b19ebd --- /dev/null +++ b/lib/modules/observers/activity_feed/git.rb @@ -0,0 +1,65 @@ +# -*- encoding : utf-8 -*- +module Modules::Observers::ActivityFeed::Git + + def self.create_notifications(record) + + case record.class.to_s + when 'GitHook' + return unless record.project + PullRequest.where("from_project_id = ? OR to_project_id = ?", record.project, record.project).needed_checking.each {|pull| pull.check} + record.project.hooks.each{ |h| h.receive_push(record) } + + change_type = record.change_type + branch_name = record.refname.split('/').last + + if change_type == 'delete' + kind = 'git_delete_branch_notification' + options = {:project_id => record.project.id, :project_name => record.project.name, :branch_name => branch_name, + :change_type => change_type, :project_owner => record.project.owner.uname} + else + if record.message # online update + last_commits, commits = [[record.newrev, record.message]], [] + all_commits = last_commits + else + commits = record.project.repo.commits_between(record.oldrev, record.newrev) + all_commits = commits.collect { |commit| [commit.sha, commit.message] } + last_commits = all_commits.last(3).reverse + end + + kind = 'git_new_push_notification' + options = {:project_id => record.project.id, :project_name => record.project.name, :last_commits => last_commits, + :branch_name => branch_name, :change_type => change_type, :project_owner => record.project.owner.uname} + if commits.count > 3 + commits = commits[0...-3] + options.merge!({:other_commits_count => commits.count, :other_commits => "#{commits[0].sha[0..9]}...#{commits[-1].sha[0..9]}"}) + end + Comment.create_link_on_issues_from_item(record, all_commits) if all_commits.count > 0 + end + options.merge!({:user_id => record.user.id, :user_name => record.user.name, :user_email => record.user.email}) if record.user + + record.project.admins.each do |recipient| + next if record.user && record.user.id == recipient.id + ActivityFeed.create!( + :user => recipient, + :kind => kind, + :data => options + ) + end + + when 'Hash' # 'Gollum::Committer' + actor = User.find_by_uname! record[:actor_name] + project = Project.find record[:project_id] + + project.admins.each do |recipient| + ActivityFeed.create!( + :user => recipient, + :kind => 'wiki_new_commit_notification', + :data => {:user_id => actor.id, :user_name => actor.name, :user_email => actor.email, :project_id => project.id, + :project_name => project.name, :commit_sha => record[:commit_sha], :project_owner => project.owner.uname} + ) + end + end + + end + +end \ No newline at end of file diff --git a/lib/modules/observers/activity_feed/issue.rb b/lib/modules/observers/activity_feed/issue.rb new file mode 100644 index 000000000..d2ed1d016 --- /dev/null +++ b/lib/modules/observers/activity_feed/issue.rb @@ -0,0 +1,59 @@ +# -*- encoding : utf-8 -*- +module Modules::Observers::ActivityFeed::Issue + extend ActiveSupport::Concern + + included do + after_commit :new_issue_notifications, :on => :create + after_update -> { send_assign_notifications(:update) } + end + + private + + def new_issue_notifications + collect_recipients.each do |recipient| + next if user_id == recipient.id + UserMailer.new_issue_notification(self, recipient).deliver if recipient.notifier.can_notify && recipient.notifier.new_issue + ActivityFeed.create( + :user => recipient, + :kind => 'new_issue_notification', + :data => { + :user_name => user.name, + :user_email => user.email, + :user_id => user_id, + :issue_serial_id => serial_id, + :issue_title => title, + :project_id => project.id, + :project_name => project.name, + :project_owner => project.owner.uname + } + ) + end + send_assign_notifications + end + + def send_assign_notifications(action = :create) + if assignee_id && assignee_id_changed? + if assignee.notifier.issue_assign && assignee.notifier.can_notify + user_mailer_action = action == :create ? :new_issue_notification : :issue_assign_notification + UserMailer.send(user_mailer_action, self, assignee).deliver + end + ActivityFeed.create( + :user => assignee, + :kind => 'issue_assign_notification', + :data => { + :user_name => assignee.name, + :user_email => assignee.email, + :issue_serial_id => serial_id, + :issue_title => title, + :project_id => project.id, + :project_name => project.name, + :project_owner => project.owner.uname + } + ) + end + project.hooks.each{ |h| h.receive_issues(self, action) } if action == :create || status_changed? + # dont remove outdated issues link + Comment.create_link_on_issues_from_item(self) + end + +end \ No newline at end of file diff --git a/lib/modules/observers/activity_feed/user.rb b/lib/modules/observers/activity_feed/user.rb new file mode 100644 index 000000000..971378b30 --- /dev/null +++ b/lib/modules/observers/activity_feed/user.rb @@ -0,0 +1,19 @@ +# -*- encoding : utf-8 -*- +module Modules::Observers::ActivityFeed::User + extend ActiveSupport::Concern + + included do + after_commit :new_user_notification, :on => :create + end + + private + + def new_user_notification + ActivityFeed.create( + :user => self, + :kind => 'new_user_notification', + :data => {:user_name => self.user_appeal, :user_email => self.email} + ) + end + +end \ No newline at end of file diff --git a/spec/factories/comments.rb b/spec/factories/comments.rb index 145b50ca6..fdfb51a9c 100644 --- a/spec/factories/comments.rb +++ b/spec/factories/comments.rb @@ -4,5 +4,7 @@ FactoryGirl.define do body { FactoryGirl.generate(:string) } association :user, :factory => :user association :commentable, :factory => :issue + project { |c| c.commentable.project } + after(:create) { |c| c.send(:new_comment_notifications) } end end diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb index a76caea56..1bacc7763 100644 --- a/spec/factories/issues.rb +++ b/spec/factories/issues.rb @@ -7,5 +7,6 @@ FactoryGirl.define do association :user, :factory => :user association :assignee, :factory => :user status "open" + after(:create) { |i| i.send(:new_issue_notifications) } end end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 8f8d138a9..37dab7ef1 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -7,6 +7,7 @@ FactoryGirl.define do password '123456' password_confirmation {|u| u.password} confirmed_at { Time.now.utc } + after(:create) { |u| u.send(:new_user_notification) } end factory :admin, :parent => :user do diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 72c8674ec..17dacb5a8 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -2,7 +2,6 @@ require "spec_helper" describe UserMailer do - pending "add some examples to (or delete) #{__FILE__}" context 'On Issue create' do before(:each) do diff --git a/spec/models/activity_feed_observer_spec.rb b/spec/models/activity_feed_observer_spec.rb deleted file mode 100644 index f008468e9..000000000 --- a/spec/models/activity_feed_observer_spec.rb +++ /dev/null @@ -1,6 +0,0 @@ -# -*- encoding : utf-8 -*- -require 'spec_helper' - -describe ActivityFeedObserver do - pending "add some examples to (or delete) #{__FILE__}" -end