diff --git a/app/controllers/activity_feeds_controller.rb b/app/controllers/activity_feeds_controller.rb new file mode 100644 index 000000000..b23311937 --- /dev/null +++ b/app/controllers/activity_feeds_controller.rb @@ -0,0 +1,7 @@ +class ActivityFeedsController < ApplicationController + before_filter :authenticate_user! + + def index + @activity_feeds = current_user.activity_feeds.order('created_at DESC') + end +end diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 3dae0ee00..f7ed16b9d 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -19,10 +19,10 @@ class CategoriesController < ApplicationController if @platform @categories = Category.select('categories.id, categories.name, categories.ancestry, count(projects.id) projects_count'). joins(:projects => :repositories).where('repositories.platform_id = ?', @platform.id). - having('count(projects.id) > 0').group('categories.id, categories.name, categories.ancestry, projects_count').default_order + having('count(projects.id) > 0').group('categories.id, categories.name, categories.ancestry, projects_count') render 'index2' else - @categories = Category.default_order.paginate(:page => params[:page]) + @categories = Category.paginate(:page => params[:page]) end end diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 7364f1943..fd398d1aa 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -256,6 +256,7 @@ class WikiController < ApplicationController # @committer.after_commit do |committer, sha1| # here goes callback for notification # end + ActivityFeedObserver.instance.after_create(@committer).delay @committer end diff --git a/app/helpers/activity_feeds_helper.rb b/app/helpers/activity_feeds_helper.rb new file mode 100644 index 000000000..f3facbf94 --- /dev/null +++ b/app/helpers/activity_feeds_helper.rb @@ -0,0 +1,5 @@ +module ActivityFeedsHelper + def render_activity_feed(activity_feed) + render :partial => activity_feed.partial, :locals => activity_feed.data + end +end diff --git a/app/models/activity_feed.rb b/app/models/activity_feed.rb new file mode 100644 index 000000000..934ef56ea --- /dev/null +++ b/app/models/activity_feed.rb @@ -0,0 +1,9 @@ +class ActivityFeed < ActiveRecord::Base + belongs_to :user + + serialize :data + + def partial + 'activity_feeds/partials/' + self.kind + end +end diff --git a/app/models/activity_feed_observer.rb b/app/models/activity_feed_observer.rb new file mode 100644 index 000000000..6092ddea3 --- /dev/null +++ b/app/models/activity_feed_observer.rb @@ -0,0 +1,121 @@ +class ActivityFeedObserver < ActiveRecord::Observer + observe :issue, :comment, :user + + def after_create(record) + case record.class.to_s + when 'User' + ActivityFeed.create( + :user => record, + :kind => 'new_user_notification', + :data => {:user_name => record.name, :user_email => record.email} + ) + + when 'Issue' + recipients = record.collect_recipient_ids + recipients.each do |recipient_id| + recipient = User.find(recipient_id) + UserMailer.delay.new_issue_notification(record, recipient) if User.find(recipient).notifier.can_notify && User.find(recipient).notifier.new_issue + ActivityFeed.create( + :user => recipient, + :kind => 'new_issue_notification', + :data => {:user_name => recipient.name, :issue_serial_id => record.serial_id, :issue_title => record.title, :project_id => record.project.id, :project_name => record.project.name} + ) + end + + if record.user_id_was != record.user_id + UserMailer.delay.issue_assign_notification(record, record.user) if record.user.notifier.issue_assign && record.user.notifier.can_notify + ActivityFeed.create( + :user => record.user, + :kind => 'issue_assign_notification', + :data => {:user_name => record.user.name, :issue_serial_id => record.serial_id, :project_id => record.project.id, :issue_title => record.title} + ) + end + + when 'Comment' + if record.commentable.class == Issue + subscribes = record.commentable.subscribes.finder_hack + subscribes.each do |subscribe| + if record.user_id != subscribe.user_id + UserMailer.delay.new_comment_notification(record, subscribe.user) if record.can_notify_on_new_comment?(subscribe) + ActivityFeed.create( + :user => subscribe.user, + :kind => 'new_comment_notification', + :data => {:user_name => subscribe.user.name, :comment_body => record.body, :issue_title => record.commentable.title, + :issue_serial_id => record.commentable.serial_id, :project_id => record.commentable.project.id} + ) + end + end + elsif record.commentable.class == Grit::Commit + subscribes = Subscribe.comment_subscribes(record).where(:status => true) + subscribes.each do |subscribe| + next if record.own_comment?(subscribe.user) + UserMailer.delay.new_comment_notification(record, subscribe.user) if subscribe.user.notifier.can_notify + ActivityFeed.create( + :user => subscribe.user, + :kind => 'new_comment_commit_notification', + :data => {:user_name => subscribe.user.name, :comment_body => record.body, :commit_message => record.commentable.message.encode_to_default, + :commit_id => record.commentable.id, :project_id => record.project.id} + ) + end + end + + when 'GitHook' + change_type = record.change_type + branch_name = record.refname.match(/\/([\w\d]+)$/)[1] + #user_name = record. + + #owner = record.owner + project = Project.find_by_name(record.repo) + + last_commits = project.git_repository.repo.log(branch_name, nil).first(3).collect do |commit| #:author => 'author' + [commit.sha, commit.message] + end + + if change_type == 'delete' + kind = 'git_delete_branch_notification' + options = {:project_id => project.id, :project_name => project.name, :branch_name => branch_name, :change_type => change_type} + else + kind = 'git_new_push_notification' + options = {:project_id => project.id, :project_name => project.name, :last_commits => last_commits, :branch_name => branch_name, :change_type => change_type} + end + + project.owner_and_admin_ids.each do |recipient| + ActivityFeed.create( + :user => User.find(recipient), + :kind => kind, + :data => options + ) + end + + when 'Gollum::Committer' + actor = User.find_by_uname(record.actor.name) + project_name = record.wiki.path.match(/\/(\w+)\.wiki\.git$/)[1] + project = Project.find_by_name(project_name) + commit_sha = record.commit + #wiki_name = record.wiki.name + + project.owner_and_admin_ids.each do |recipient| + ActivityFeed.create( + :user => User.find(recipient),#record.user, + :kind => 'wiki_new_commit_notification', + :data => {:user_id => actor.id, :user_name => actor.name, :project_id => project.id, :project_name => project_name, :commit_sha => commit_sha} + ) + end + end + end + + def after_update(record) + case record.class.to_s + when 'Issue' + if record.user_id_was != record.user_id + UserMailer.delay.issue_assign_notification(record, record.user) if record.user.notifier.issue_assign && record.user.notifier.can_notify + ActivityFeed.create( + :user => record.user, + :kind => 'issue_assign_notification', + :data => {:user_name => record.user.name, :issue_serial_id => record.serial_id, :project_id => record.project.id, :issue_title => record.title} + ) + end + end + end + +end diff --git a/app/models/comment.rb b/app/models/comment.rb index 1e5f22530..85382f129 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -8,9 +8,10 @@ class Comment < ActiveRecord::Base default_scope order('created_at') - after_create :invoke_helper, :if => "commentable_type == 'Grit::Commit'" + # FIXME + after_create :subscribe_on_reply, :unless => lambda {|c| c.commit_comment?} + after_create :invoke_helper, :if => lambda {|c| c.commit_comment?} after_create :subscribe_users - after_create {|c| Subscribe.new_comment_notification(c)} def helper class_eval { def commentable; project.git_repository.commit(commentable_id.to_s(16)); end } if commit_comment? @@ -24,8 +25,16 @@ class Comment < ActiveRecord::Base commentable_type == 'Grit::Commit' end + def can_notify_on_new_comment?(subscribe) + User.find(subscribe.user).notifier.new_comment && User.find(subscribe.user).notifier.can_notify + end + protected + def subscribe_on_reply + self.commentable.subscribes.create(:user_id => self.user_id) if !self.commentable.subscribes.exists?(:user_id => self.user_id) + end + def invoke_helper self.helper end @@ -33,7 +42,7 @@ class Comment < ActiveRecord::Base def subscribe_users if self.commentable.class == Issue self.commentable.subscribes.create(:user => self.user) if !self.commentable.subscribes.exists?(:user_id => self.user.id) - elsif self.commentable.class == Grit::Commit + elsif self.commit_comment? recipients = self.project.relations.by_role('admin').where(:object_type => 'User').map &:object # admins recipients << self.user << User.where(:email => self.commentable.committer.email).first # commentor and committer recipients << self.project.owner if self.project.owner_type == 'User' # project owner diff --git a/app/models/issue.rb b/app/models/issue.rb index dcb65ed79..5fff7f744 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -18,9 +18,6 @@ class Issue < ActiveRecord::Base after_create :set_serial_id after_create :subscribe_users - after_create :deliver_new_issue_notification - after_create :deliver_issue_assign_notification - after_update :deliver_issue_assign_notification after_update :subscribe_issue_assigned_user attr_accessible :labelings_attributes, :title, :body @@ -58,6 +55,14 @@ class Issue < ActiveRecord::Base self.status = 'open' end + def collect_recipient_ids + recipients = self.project.relations.by_role('admin').where(:object_type => 'User').map { |rel| rel.read_attribute(:object_id) } + recipients = recipients | [self.user_id] if self.user_id + recipients = recipients | [self.project.owner_id] if self.project.owner_type == 'User' + + recipients + end + protected def set_serial_id @@ -65,18 +70,6 @@ class Issue < ActiveRecord::Base self.save! end - def deliver_new_issue_notification - recipients = collect_recipient_ids - recipients.each do |recipient_id| - recipient = User.find(recipient_id) - UserMailer.delay.new_issue_notification(self, recipient) if User.find(recipient).notifier.can_notify && User.find(recipient).notifier.new_issue - end - end - - def deliver_issue_assign_notification - UserMailer.delay.issue_assign_notification(self, self.user) if self.user_id_was != self.user_id && self.user.notifier.issue_assign && self.user.notifier.can_notify - end - def subscribe_users recipients = collect_recipient_ids recipients.each do |recipient_id| @@ -85,19 +78,6 @@ class Issue < ActiveRecord::Base end end - def collect_recipient_ids - recipients = self.project.relations.by_role('admin').where(:object_type => 'User').map { |rel| rel.read_attribute(:object_id) } - recipients = recipients | [self.user_id] if self.user_id - recipients = recipients | [self.project.owner_id] if self.project.owner_type == 'User' - - # filter by notification settings - recipients = recipients.select do |recipient| - User.find(recipient).notifier.new_issue && User.find(recipient).notifier.can_notify - end - - recipients - end - def subscribe_issue_assigned_user if self.user_id_was != self.user_id self.subscribes.where(:user_id => self.user_id_was).first.destroy unless self.user_id_was.blank? diff --git a/app/models/product.rb b/app/models/product.rb index 536b3dbbf..e52a700f0 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -10,7 +10,7 @@ class Product < ActiveRecord::Base has_attached_file :tar - validates_attachment_content_type :tar, :content_type => ["application/gnutar", "application/x-compressed", "application/x-gzip", "application/x-bzip", "application/x-bzip2", "application/x-tar"], :message => I18n.t('layout.invalid_content_type') + validates_attachment_content_type :tar, :content_type => ["application/gnutar", "application/x-compressed", "application/x-gzip", "application/x-bzip", "application/x-bzip2", "application/x-tar", "application/octet-stream"], :message => I18n.t('layout.invalid_content_type') validates :name, :presence => true, :uniqueness => {:scope => :platform_id} scope :recent, order("name ASC") diff --git a/app/models/product_build_list.rb b/app/models/product_build_list.rb index f9078f19d..24ee0afab 100644 --- a/app/models/product_build_list.rb +++ b/app/models/product_build_list.rb @@ -14,6 +14,7 @@ class ProductBuildList < ActiveRecord::Base attr_accessor :base_url after_create :xml_rpc_create + after_destroy :xml_delete_iso_container def container_path "/downloads/#{product.platform.name}/product/#{id}/" @@ -34,8 +35,17 @@ class ProductBuildList < ActiveRecord::Base if result == ProductBuilder::SUCCESS return true else - # return false - raise "Failed to create product_build_list #{id} inside platform #{product.platform.name} tar url #{tar_url} with code #{result}." + raise "Failed to create product_build_list #{id} inside platform #{platform.name} tar url #{tar_url} with code #{result}." + end + end + + def xml_delete_iso_container + result = ProductBuilder.delete_iso_container self + if result == ProductBuilder::SUCCESS + return true + else + raise "Failed to destroy product_build_list #{id} inside platform #{platform.name} with code #{result}." end end + end diff --git a/app/models/project.rb b/app/models/project.rb index a77dada77..72b3f57fe 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -204,7 +204,13 @@ class Project < ActiveRecord::Base def self.process_hook(owner_uname, repo, newrev, oldrev, ref, newrev_type, oldrev_type) rec = GitHook.new(owner_uname, repo, newrev, oldrev, ref, newrev_type, oldrev_type) - #ActivityFeedObserver.instance.after_create rec # for example + ActivityFeedObserver.instance.after_create rec + end + + def owner_and_admin_ids + recipients = self.relations.by_role('admin').where(:object_type => 'User').map { |rel| rel.read_attribute(:object_id) } + recipients = recipients | [self.owner_id] if self.owner_type == 'User' + recipients end protected diff --git a/app/models/subscribe.rb b/app/models/subscribe.rb index 257d812d0..0ed6e71df 100644 --- a/app/models/subscribe.rb +++ b/app/models/subscribe.rb @@ -18,27 +18,6 @@ class Subscribe < ActiveRecord::Base Subscribe.where(:subscribeable_id => comment.commentable_id, :subscribeable_type => comment.commentable.class.name, :project_id => comment.project) end - def self.new_comment_notification(comment) - commentable_class = comment.commentable.class - Subscribe.new_comment_issue_notification(comment) if commentable_class == Issue - Subscribe.new_comment_commit_notification(comment) if commentable_class == Grit::Commit - end - - def self.new_comment_issue_notification(comment) - comment.commentable.subscribes.finder_hack.each do |subscribe| - next if comment.own_comment?(subscribe.user) || !subscribe.user.notifier.can_notify - UserMailer.delay.new_comment_notification(comment, subscribe.user) if subscribe.user.notifier.new_comment_reply - end - end - - def self.new_comment_commit_notification(comment) - subscribes = Subscribe.comment_subscribes(comment).where(:status => true) - subscribes.each do |subscribe| - next if comment.own_comment?(subscribe.user) || !subscribe.user.notifier.can_notify - UserMailer.delay.new_comment_notification(comment, subscribe.user) - end - end - def self.subscribed_to_commit?(project, user, commit) subscribe = user.subscribes.where(:subscribeable_id => commit.id.hex, :subscribeable_type => commit.class.name, :project_id => project.id).first return subscribe.subscribed? if subscribe # return status if already subscribe present @@ -48,12 +27,10 @@ class Subscribe < ActiveRecord::Base (user.committer?(commit) && user.notifier.new_comment_commit_owner) end - def self.subscribe_to_commit(options) Subscribe.set_subscribe_to_commit(options, true) end - def self.unsubscribe_from_commit(options) Subscribe.set_subscribe_to_commit(options, false) end diff --git a/app/models/user.rb b/app/models/user.rb index 20906dc5c..44deb7fd1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -9,6 +9,8 @@ class User < ActiveRecord::Base has_one :notifier, :class_name => 'Settings::Notifier' #:notifier + has_many :activity_feeds + has_many :authentications, :dependent => :destroy has_many :build_lists, :dependent => :destroy has_many :subscribes, :foreign_key => :user_id, :dependent => :destroy diff --git a/app/views/activity_feeds/index.html.haml b/app/views/activity_feeds/index.html.haml new file mode 100644 index 000000000..838d9a62a --- /dev/null +++ b/app/views/activity_feeds/index.html.haml @@ -0,0 +1,21 @@ +%a{ :name => "comments" } +.block#block-list + .content + %h2.title + = t("layout.activity_feed.header") + .inner + %ul.list + - @activity_feeds.each do |activity_feed| + %li + .left + = link_to activity_feed.user.uname, user_path(activity_feed.user.uname) + %br + %br + = activity_feed.created_at + %br + %br + .item + = render_activity_feed(activity_feed) + %br + %br + %br diff --git a/app/views/activity_feeds/partials/_git_delete_branch_notification.haml b/app/views/activity_feeds/partials/_git_delete_branch_notification.haml new file mode 100644 index 000000000..10acc1d61 --- /dev/null +++ b/app/views/activity_feeds/partials/_git_delete_branch_notification.haml @@ -0,0 +1,3 @@ +%p== Branch #{ branch_name } has been deleted + +%p== Into project #{ link_to(project_name, project_path(project_id)) } diff --git a/app/views/activity_feeds/partials/_git_new_push_notification.haml b/app/views/activity_feeds/partials/_git_new_push_notification.haml new file mode 100644 index 000000000..46a62e834 --- /dev/null +++ b/app/views/activity_feeds/partials/_git_new_push_notification.haml @@ -0,0 +1,7 @@ +%p== Branch #{ branch_name } has been #{ change_type }d +%p== Into project #{ link_to(project_name, project_path(project_id)) } + +- last_commits.each do |commit| + = link_to commit[0], commit_path(project_id, commit[0]) + = commit[1] + %br diff --git a/app/views/activity_feeds/partials/_issue_assign_notification.haml b/app/views/activity_feeds/partials/_issue_assign_notification.haml new file mode 100644 index 000000000..f3ddea3b2 --- /dev/null +++ b/app/views/activity_feeds/partials/_issue_assign_notification.haml @@ -0,0 +1,3 @@ +%p== #{ t("notifications.bodies.issue_assign_notification.title", :user_name => user_name) } + +%p= raw t("notifications.bodies.issue_assign_notification.content", :issue_link => link_to(issue_title, project_issue_path(project_id, issue_serial_id))) diff --git a/app/views/activity_feeds/partials/_new_comment_notification.haml b/app/views/activity_feeds/partials/_new_comment_notification.haml new file mode 100644 index 000000000..23c15ef74 --- /dev/null +++ b/app/views/activity_feeds/partials/_new_comment_notification.haml @@ -0,0 +1,5 @@ +%p== #{ t("notifications.bodies.new_comment_notification.title", :user_name => user_name) } + +%p= raw t("notifications.bodies.new_comment_notification.content", {:issue_link => link_to(issue_title, project_issue_path(project_id, issue_serial_id))}) + +%p "#{ comment_body }" diff --git a/app/views/activity_feeds/partials/_new_commit_comment_notification.haml b/app/views/activity_feeds/partials/_new_commit_comment_notification.haml new file mode 100644 index 000000000..32826e333 --- /dev/null +++ b/app/views/activity_feeds/partials/_new_commit_comment_notification.haml @@ -0,0 +1,5 @@ +%p== #{ t("notifications.bodies.new_commit_comment_notification.title", :user_name => user_name) } + +%p= raw t("notifications.bodies.new_comment_notification.commit_content", {:commit_link => link_to(commit_message, commit_path(project_id, commit_id))}) + +%p "#{ comment_body }" diff --git a/app/views/activity_feeds/partials/_new_issue_notification.haml b/app/views/activity_feeds/partials/_new_issue_notification.haml new file mode 100644 index 000000000..6f1666c74 --- /dev/null +++ b/app/views/activity_feeds/partials/_new_issue_notification.haml @@ -0,0 +1,3 @@ +%p== #{ t("notifications.bodies.new_issue_notification.title", :user_name => user_name) } + +%p= raw t("notifications.bodies.new_issue_notification.content", :issue_link => link_to(issue_title, project_issue_path(project_id, issue_serial_id)), :project_link => link_to(project_name, project_path(project_id))) diff --git a/app/views/activity_feeds/partials/_new_user_notification.haml b/app/views/activity_feeds/partials/_new_user_notification.haml new file mode 100644 index 000000000..98d4796e9 --- /dev/null +++ b/app/views/activity_feeds/partials/_new_user_notification.haml @@ -0,0 +1,5 @@ +%p== #{ t("notifications.bodies.new_user_notification.title", :user_name => user_name) } + +%p #{ t("notifications.bodies.new_user_notification.content") } + +%p #{ t("notifications.bodies.new_user_notification.email", :user_email => user_email) } \ No newline at end of file diff --git a/app/views/activity_feeds/partials/_wiki_new_commit_notification.haml b/app/views/activity_feeds/partials/_wiki_new_commit_notification.haml new file mode 100644 index 000000000..eb33be273 --- /dev/null +++ b/app/views/activity_feeds/partials/_wiki_new_commit_notification.haml @@ -0,0 +1,2 @@ +%p== User #{ link_to user_name, user_path(user_id) } has been update wiki #{ link_to "history", compare_versions_project_wiki_index_path(project_id, commit_sha) } +%p== Into project #{ link_to(project_name, project_path(project_id)) } diff --git a/app/views/platforms/show.html.haml b/app/views/platforms/show.html.haml index 1ae334f17..3622927a5 100644 --- a/app/views/platforms/show.html.haml +++ b/app/views/platforms/show.html.haml @@ -113,7 +113,7 @@ = link_to t("layout.edit"), edit_platform_product_path(@platform, product) if can? :update, product | = link_to t("layout.delete"), platform_product_path(@platform, product), :method => :delete, :confirm => t("layout.products.confirm_delete") if can? :destroy, product - = (product.can_clone? ? "| #{link_to t("layout.products.clone"), clone_platform_product_path(@platform, product)}" : "").html_safe + =# (product.can_clone? ? "| #{link_to t("layout.products.clone"), clone_platform_product_path(@platform, product)}" : "").html_safe .actions-bar.wat-cf .actions - content_for :sidebar, render(:partial => 'sidebar') diff --git a/app/views/product_build_lists/_product_build_list.html.haml b/app/views/product_build_lists/_product_build_list.html.haml index 38a70580e..91fb1c373 100644 --- a/app/views/product_build_lists/_product_build_list.html.haml +++ b/app/views/product_build_lists/_product_build_list.html.haml @@ -3,5 +3,5 @@ %td= link_to product_build_list.product.name, [product_build_list.product.platform, product_build_list.product] %td= link_to nil, product_build_list.container_path %td= product_build_list.human_status - %td= link_to t("layout.product_build_lists.delete"), platform_product_product_build_list_path(product_build_list.product.platform, product_build_list.product, product_build_list), :method => "delete", :confirm => t("layout.confirm") if can? :delete, product_build_list + %td= link_to t("layout.product_build_lists.delete"), platform_product_product_build_list_path(product_build_list.product.platform, product_build_list.product, product_build_list), :method => "delete", :confirm => t("layout.confirm") if can? :destroy, product_build_list %td= product_build_list.notified_at \ No newline at end of file diff --git a/app/views/products/show.html.haml b/app/views/products/show.html.haml index a1cfc880a..f61124ea8 100644 --- a/app/views/products/show.html.haml +++ b/app/views/products/show.html.haml @@ -31,7 +31,7 @@ - if can? :destroy, @product = link_to image_tag("x.png", :alt => t("layout.delete")) + " " + t("layout.delete"), platform_product_path(@platform, @product), :method => "delete", :class => "button", :confirm => t("layout.products.confirm_delete") - if @product.can_clone? - = link_to t("layout.products.clone"), clone_platform_product_path(@platform, @product), :class => "button" + =# link_to t("layout.products.clone"), clone_platform_product_path(@platform, @product), :class => "button" - if can?(:create, @product => ProductBuildList) = link_to t("layout.products.build"), platform_product_product_build_lists_path(@platform, @product), :class => "button", :method => 'post', :confirm => t("layout.confirm") diff --git a/app/views/user_mailer/new_comment_reply_notification.en.haml b/app/views/user_mailer/new_comment_reply_notification.en.haml deleted file mode 100644 index b2838b2e0..000000000 --- a/app/views/user_mailer/new_comment_reply_notification.en.haml +++ /dev/null @@ -1,9 +0,0 @@ -%p== Hello, #{@user.name}. - -- #TODO hmm... this need to be refactored. -%p Your comment into issue #{ link_to @comment.commentable.title, project_issue_url(@comment.commentable.project, @comment.commentable) } has been answered. - -%p "#{ @comment.body }" - - -%p== Support team «ROSA Build System» diff --git a/app/views/user_mailer/new_user_notification.en.haml b/app/views/user_mailer/new_user_notification.en.haml index d1a0722bf..c0f05d467 100644 --- a/app/views/user_mailer/new_user_notification.en.haml +++ b/app/views/user_mailer/new_user_notification.en.haml @@ -6,7 +6,5 @@ %p ==Your email : #{@user.email} - %br/ - ==Your password: #{@user.password} %p== Support team «ROSA Build System» diff --git a/app/views/user_mailer/new_user_notification.ru.haml b/app/views/user_mailer/new_user_notification.ru.haml index f3c6d1ec7..acae98cba 100644 --- a/app/views/user_mailer/new_user_notification.ru.haml +++ b/app/views/user_mailer/new_user_notification.ru.haml @@ -6,7 +6,5 @@ %p ==Ваш email : #{@user.email} - %br/ - ==Ваш пароль: #{@user.password} %p== Команда поддержки «ROSA Build System» diff --git a/config/application.rb b/config/application.rb index 6a537ab65..86b7679c0 100644 --- a/config/application.rb +++ b/config/application.rb @@ -31,7 +31,7 @@ module Rosa # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Activate observers that should always be running. - config.active_record.observers = :event_log_observer + config.active_record.observers = :event_log_observer, :activity_feed_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/config/locales/activity_feed.en.yml b/config/locales/activity_feed.en.yml new file mode 100644 index 000000000..0794427a7 --- /dev/null +++ b/config/locales/activity_feed.en.yml @@ -0,0 +1,30 @@ +en: + + layout: + activity_feed: + header: Activity Feed + + notifications: + subjects: + new_comment_notification: New comment to task + new_commit_comment_notification: New comment to commit + new_issue_notification: New task added to project + new_user_notification: Registered on project «%{ project_name }» + issue_assign_notification: New task assigned + + bodies: + new_comment_notification: + title: Hello, %{user_name}. + content: To the issue %{issue_link} added a comment. + commit_content: To the commit %{commit_link} added a comment. + new_issue_notification: + title: Hello, %{user_name}. + content: To project %{project_link} has been added an issue %{issue_link} + new_user_notification: + title: Hello, %{user_name}. + content: You have been sign up to project «ROSA Build System» and now can sign in. + email: ==Your email %{user_email} + password: ==Your password %{user_password} + issue_assign_notification: + title: Hello, %{user_name}. + content: You have been assigned to issue %{issue_link} diff --git a/config/locales/activity_feed.ru.yml b/config/locales/activity_feed.ru.yml new file mode 100644 index 000000000..256a8d7bb --- /dev/null +++ b/config/locales/activity_feed.ru.yml @@ -0,0 +1,31 @@ +ru: + + layout: + activity_feed: + header: Лента активности + + notifications: + subjects: + new_comment_notification: Новый комментарий к задаче + new_commit_comment_notification: Новый комментарий к коммиту + new_issue_notification: Новая задача добавлена к проекту + new_user_notification: Регистрация на проекте «%{ project_name }» + issue_assign_notification: Вам назначили задачу + + bodies: + new_comment_notification: + title: Здравствуйте, %{user_name}. + content: К задаче %{issue_link} был добавлен новый комментарий. + commit_content: К коммиту %{commit_link} был добавлен новый комментарий. + new_issue_notification: + title: Здравствуйте, %{user_name}. + content: К проекту %{project_link} была добавлена задача %{issue_link} + new_user_notification: + title: Здравствуйте, %{user_name}. + content: Вы зарегистрированы на проекте «ROSA Build System» и теперь можете войти в систему. + email: ==Ваш email %{user_email} + password: ==Ваш пароль %{user_password} + issue_assign_notification: + title: Здравствуйте, %{user_name}. + content: Вам была назначена задача %{issue_link} + invite_approve_notification: Приглашение в ABF \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 36873588a..c8a02fb1b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3,7 +3,7 @@ en: previous_label: ‹ Previous next_label: Next › page_gap: ... - + datatables: previous_label: ‹ Prev. next_label: Next › @@ -109,126 +109,6 @@ en: edit_header: Edit category confirm_delete: Are you sure to delete this category? - comments: - confirm_delete: Are you sure to delete the comment? - new_header: New comment - edit_header: Editing a comment - - platforms: - admin_id: Owner - build_all: Build all - list: List - new: Create - edit: Edit - new_header: New platform - edit_header: Edit - list_header: Platforms - list_header_main: General - list_header_personal: Personal - list_header_all: All - clone_header: Platform clone - show: Platform - projects: Projects - products: Products - location: Location - repositories: Repositories - back_to_the_list: ⇐To platform list - freeze: Freeze - unfreeze: Unfeeze - confirm_freeze: Are you sure to freeze this platform? - confirm_freeze: Are you sure to clone this platform? - confirm_unfreeze: Are you sure to defrost this platform? - released_suffix: (released) - confirm_delete: Are you sure to delete this platform? - current_platform_header: Current platform - owner: Owner - visibility: Visibility - platform_type: Platform type - distrib_type: Distribution kit type - private_users: Access data - confirm_clone: To clone? - clone: To clone - - event_logs: - list: List - list_header: Event log - - repositories: - list: List - list_header: Repositories - new: New repository - new_header: New repository - show: Repository - location: Location - projects: Projects - new_header: New repository - back_to_the_list: ⇐ List of repositories - confirm_delete: Are you sure to delete this repository? - current_repository_header: Current repository - - personal_repositories: - settings_header: Settings - change_visibility_from_hidden: Replace the status to "Opened" - change_visibility_from_open: Replace the status to "Private" - settings: Settings - show: My repository - private_users: Private repository users - - products: - list: List - new: New product - list_header: Products - clone: Clone - build: Build - new_header: New product - edit_header: Product editing - confirm_delete: Are you sure to delete this product? - - cron_tab_generator: - show: Show cron tab the generator - hide: Hide cron tab the generator - choose: Choose - every_minute: Every minute - every_hour: Every hour - every_day: Every day - every_month: Every month - every_weekday: Every weekdays - minutes: Minutes - hours: Hours - days: Days - months: Months - weekdays: weekdays - - projects: - add: Add - edit: Edit - list: List - list_header: Projects - edit_header: Edit the project - show: Project - build: Build - new_build: New build %{project_name} - confirm_delete: Are you sure to delete this project? - new: New project - new_header: New project - new_header: New project - location: Location - git_repo_location: Path to git repo - current_project_header: Current project - current_build_lists: Current builds - build_button: Start build - add_collaborators: Add collaborators - members: Members - collaborators: Collaborators - groups: Groups - edit_collaborators: Edit collaborators - issues: Issues - wiki: Wiki - delete_warning: Attention! Deleted project can not be restored! - sections: Sections - has_issue_description: Issues adds lightweight issue tracking tightly integrated with your repository. Add issues to milestones, label issues, and close & reference issues from commit messages. - has_wiki_description: Wikis are the simplest way to let others contribute content. Any user can create and edit pages to use for documentation, examples, support or anything you wish. - collaborators: back_to_proj: Back to project edit: Edit list @@ -246,27 +126,6 @@ en: writer: Writer admin: Admin - users: - list: List - new: Create - edit: Edit - new_header: New user - edit_header: Edit - list_header: Users - groups: Groups - show: User - back_to_the_list: ⇐ List of users - confirm_delete: Are you sure to remove this user? - own_projects: My projects - part_projects: Participate projects - filter_header: Filter - group: Group - description: Descripton - leave_group: Leave group - projects_list: Projects list - public_profile: Public profile - delete_warning: Attention! Deleted group can not be restored! - git: repositories: empty: "Repository is empty. You need to wait some time if you have forked project or imported package" @@ -290,10 +149,15 @@ en: saved: Settings saved success save_error: Setting update error + private_users: "Login: %{login} Password: %{password}" subscribe: saved: Subscription on notifications for this task is created + saved_error: Subscription create error destroyed: Subscription on notifications for this task is cleaned + commit: + saved: Subscription on notifications for this commit is created + destroyed: Subscription on notifications for this commit is cleaned exception_message: Access violation to this page! @@ -319,66 +183,6 @@ en: save_error: Category saves error destroyed: Category deleted - comment: - saved: Comment saved - save_error: Comment saves error - destroyed: Comment deleted - - project: - saved: Project saved - save_error: Project saves error - save_warning_ssh_key: Owner of the project must specify in profile a SSH key - destroyed: Project deleted - forked: Project forked - fork_error: Project fork error - - user: - saved: User saved - save_error: User data saves error - destroyed: User account deleted - - group: - saved: Group saved - save_error: Group saves error - destroyed: Group deleted - user_uname_exists: User already exists - - repository: - saved: Repository added - save_error: Repository adding error - destroyed: Repository deleted - project_added: Project added on repository - project_not_added: Project adding error. In this repository already is a project with such name. First remove the old project - project_removed: Project deleted - project_not_removed: Project deleting failed - - product: - saved: Product saved - save_error: Product saves error - build_started: Product build started - destroyed: Product deleted - build_list_delete: Product build list deleted - - platform: - saved: Platform saved - save_error: Platform saves error - freezed: Platform freezed - freeze_error: Platform freezing error, try again - unfreezed: Platform unfreezed - unfreeze_error: Platform unfreezing error, try again - destroyed: Platform deleted - build_all_success: All project build in progress - clone_success: Cloned successfully - - wiki: - ref_not_exist: No such version - successfully_updated: Page '%{name}' successfully updated - duplicate_page: Page '%{name}' already exists - page_successfully_removed: Page successfully removed - page_not_found: Page '%{name}' not found - revert_success: Changes successfully reverted - patch_does_not_apply: Patch does not apply - blob: successfully_updated: File '%{name}' successfully updated updating_error: Error updating file '%{name}' @@ -401,35 +205,13 @@ en: models: category: Category - repository: Repository arch: Arch container: Container - platform: Platform - group: Group - event_log: Event log - project: Project rpm: RPM - user: User private_user: Private user - product: Product product_build_list: Product build list download: Statistics auto_build_list: Auto rebuild list - settings: - saved: Settings saved success - save_error: Setting update error - - private_users: "Login: %{login} Password: %{password}" - - subscribe: - saved: Subscription on notifications for this task is created - saved_error: Subscription create error - destroyed: Subscription on notifications for this task is cleaned - commit: - saved: Subscription on notifications for this commit is created - destroyed: Subscription on notifications for this commit is cleaned - - exception_message: Access violation to this page! attributes: settings: @@ -439,6 +221,9 @@ en: new_comment_reply: New reply of comment notifications new_issue: New task notifications issue_assign: New task assignment notifications + new_comment_commit_owner: Notify about comments to my commit + new_comment_commit_repo_owner: Notify about comments to my repository commits + new_comment_commit_commentor: Notify about comments after my commit auto_build_list: project_id: Project @@ -450,10 +235,6 @@ en: arch_id: Architecture arch: Architecture - comment: - body: Content - user: Author - private_user: login: Login password: Password @@ -462,32 +243,6 @@ en: parent_id: Parent name: Name - repository: - name: Name - description: Description - platform_id: Platform - platform: Platform - created_at: Created - updated_at: Updated - owner: Owner - - product: - name: Name - platform_id: Platform - build_status: Build status - build_path: ISO path - created_at: Created - updated_at: Updated - ks: Content .ks.template - counter: Content .counter - build_script: Content build - menu: Content .menu.xml - tar: Tar.bz2 file - is_template: Template - system_wide: System - cron_tab: Cront tab - use_cron: Cron usage - arch: name: Name created_at: Created @@ -502,48 +257,6 @@ en: created_at: Created updated_at: Updated - platform: - name: Name - description: Description - parent_platform_id: Parent platform - parent: Parent platform - released: Released - created_at: Created - updated_at: Updated - distrib_type: Source type - visibility: Status - visibility_types: - open: Open - hidden: Hidden - - event_log: - kind: Event type - created_at: Event date and time - user: User - ip: User IP - protocol: Access protocol - description: Description - - project: - category_id: Category - name: Name - description: Descripton - owner: Owner - visibility: Visibility - visibility_types: - open: Open - hidden: Hidden - repository_id: Repository - repository: Repository - created_at: Created - updated_at: Updated - has_issues: Tracker on - has_wiki: Wiki on - srpm: Import code from src.rpm - who_owns: - me: I - group: Group - rpm: name: Name arch_id: Arch @@ -553,28 +266,6 @@ en: created_at: Created updated_at: Updated - role: - name: Name - on: Slave - to: Master - use_default: By default - use_default_for_owner: Default by owner - - user: - name: User - login: Nickname or Email - email: Email - uname: Nickname - ssh_key: SSH key - current_password: Current password - role: Role - created_at: Created - updated_at: Updated - role: System role - language: Language - password: Password - password_confirm: Confirmation - product_build_list: id: Id product: Product @@ -588,12 +279,3 @@ en: distro: Source platform: Platform counter: Downloads - - notifications: - subjects: - new_comment_notification: New comment to your task - new_issue_notification: New task added to project - new_user_notification: Registered on project «%{ project_name }» - issue_assign_notification: New task assigned - new_commit_comment_notification: New comment to commit - invite_approve_notification: Invitation to ABF diff --git a/config/locales/ru.yml b/config/locales/ru.yml index cb97e60bf..bccb71891 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -572,11 +572,3 @@ ru: platform: Архитектура counter: Закачки - notifications: - subjects: - new_comment_notification: Новый комментарий к Вашей задаче - new_issue_notification: Новая задача добавлена к проекту - new_user_notification: Регистрация на проекте «%{ project_name }» - issue_assign_notification: Вам назначили задачу - new_commit_comment_notification: Новый комментарий к коммиту - invite_approve_notification: Приглашение в ABF diff --git a/config/routes.rb b/config/routes.rb index 039b6f3bd..b79b1131c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -184,6 +184,8 @@ Rosa::Application.routes.draw do end end + resources :activity_feeds, :only => [:index] + resources :users, :groups do resources :platforms, :only => [:new, :create] @@ -228,6 +230,6 @@ Rosa::Application.routes.draw do match '/projects/:project_id/git/raw/:treeish/*path', :controller => "git/blobs", :action => :raw, :treeish => /[0-9a-zA-Z_.\-]*/, :defaults => { :treeish => :master }, :as => :raw, :format => false match '/projects/:project_id/git/commit/raw/:commit_hash/*path', :controller => "git/blobs", :action => :raw, :as => :raw_commit - root :to => "platforms#index" + root :to => "activity_feeds#index" match '/forbidden', :to => 'platforms#forbidden', :as => 'forbidden' end diff --git a/db/migrate/20120124065207_create_activity_feeds.rb b/db/migrate/20120124065207_create_activity_feeds.rb new file mode 100644 index 000000000..d5b13fc3a --- /dev/null +++ b/db/migrate/20120124065207_create_activity_feeds.rb @@ -0,0 +1,15 @@ +class CreateActivityFeeds < ActiveRecord::Migration + def self.up + create_table :activity_feeds do |t| + t.integer :user_id, :null => false + t.string :kind + t.text :data + + t.timestamps + end + end + + def self.down + drop_table :activity_feeds + end +end diff --git a/db/schema.rb b/db/schema.rb index bd359a27b..30578adab 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -21,6 +21,14 @@ ActiveRecord::Schema.define(:version => 20120302102734) do t.datetime "updated_at" end + create_table "activity_feeds", :force => true do |t| + t.integer "user_id", :null => false + t.string "kind" + t.text "data" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "arches", :force => true do |t| t.string "name", :null => false t.datetime "created_at" diff --git a/lib/product_builder.rb b/lib/product_builder.rb index dfcac41df..a845f2dda 100644 --- a/lib/product_builder.rb +++ b/lib/product_builder.rb @@ -14,4 +14,8 @@ class ProductBuilder call('create_product', pbl.id.to_s, pbl.product.platform.name, pbl.product.ks, pbl.product.menu, pbl.product.build_script, pbl.product.counter, [], pbl.product.tar.exists? ? "#{pbl.base_url}#{pbl.product.tar.url}" : '') end + + def self.delete_iso_container pbl # product_build_list + self.client(pbl.product.platform.distrib_type).call('delete_iso_container', pbl.product.platform.name, pbl.id.to_s) + end end diff --git a/spec/controllers/activity_feeds_controller_spec.rb b/spec/controllers/activity_feeds_controller_spec.rb new file mode 100644 index 000000000..54ce3026a --- /dev/null +++ b/spec/controllers/activity_feeds_controller_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe ActivityFeedsController do + +end diff --git a/spec/factories/activity_feeds.rb b/spec/factories/activity_feeds.rb new file mode 100644 index 000000000..d0e1984cc --- /dev/null +++ b/spec/factories/activity_feeds.rb @@ -0,0 +1,6 @@ +# Read about factories at http://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :activity_feed do + end +end \ No newline at end of file diff --git a/spec/helpers/activity_feeds_helper_spec.rb b/spec/helpers/activity_feeds_helper_spec.rb new file mode 100644 index 000000000..623c526ec --- /dev/null +++ b/spec/helpers/activity_feeds_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the ActivityFeedsHelper. For example: +# +# describe ActivityFeedsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe ActivityFeedsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/activity_feed_observer_spec.rb b/spec/models/activity_feed_observer_spec.rb new file mode 100644 index 000000000..378ee2377 --- /dev/null +++ b/spec/models/activity_feed_observer_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe ActivityFeedObserver do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/activity_feed_spec.rb b/spec/models/activity_feed_spec.rb new file mode 100644 index 000000000..c77e1d83a --- /dev/null +++ b/spec/models/activity_feed_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe ActivityFeed do + pending "add some examples to (or delete) #{__FILE__}" +end