Merge branch '3.2-master' of github.com:warpc/rosa-build into 3.2-master

This commit is contained in:
George Vinogradov 2012-03-03 04:26:53 +04:00
commit ea0ecffd23
42 changed files with 381 additions and 413 deletions

View File

@ -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

View File

@ -19,10 +19,10 @@ class CategoriesController < ApplicationController
if @platform if @platform
@categories = Category.select('categories.id, categories.name, categories.ancestry, count(projects.id) projects_count'). @categories = Category.select('categories.id, categories.name, categories.ancestry, count(projects.id) projects_count').
joins(:projects => :repositories).where('repositories.platform_id = ?', @platform.id). 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' render 'index2'
else else
@categories = Category.default_order.paginate(:page => params[:page]) @categories = Category.paginate(:page => params[:page])
end end
end end

View File

@ -256,6 +256,7 @@ class WikiController < ApplicationController
# @committer.after_commit do |committer, sha1| # @committer.after_commit do |committer, sha1|
# here goes callback for notification # here goes callback for notification
# end # end
ActivityFeedObserver.instance.after_create(@committer).delay
@committer @committer
end end

View File

@ -0,0 +1,5 @@
module ActivityFeedsHelper
def render_activity_feed(activity_feed)
render :partial => activity_feed.partial, :locals => activity_feed.data
end
end

View File

@ -0,0 +1,9 @@
class ActivityFeed < ActiveRecord::Base
belongs_to :user
serialize :data
def partial
'activity_feeds/partials/' + self.kind
end
end

View File

@ -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

View File

@ -8,9 +8,10 @@ class Comment < ActiveRecord::Base
default_scope order('created_at') 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 :subscribe_users
after_create {|c| Subscribe.new_comment_notification(c)}
def helper def helper
class_eval { def commentable; project.git_repository.commit(commentable_id.to_s(16)); end } if commit_comment? 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' commentable_type == 'Grit::Commit'
end end
def can_notify_on_new_comment?(subscribe)
User.find(subscribe.user).notifier.new_comment && User.find(subscribe.user).notifier.can_notify
end
protected 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 def invoke_helper
self.helper self.helper
end end
@ -33,7 +42,7 @@ class Comment < ActiveRecord::Base
def subscribe_users def subscribe_users
if self.commentable.class == Issue if self.commentable.class == Issue
self.commentable.subscribes.create(:user => self.user) if !self.commentable.subscribes.exists?(:user_id => self.user.id) 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.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.user << User.where(:email => self.commentable.committer.email).first # commentor and committer
recipients << self.project.owner if self.project.owner_type == 'User' # project owner recipients << self.project.owner if self.project.owner_type == 'User' # project owner

View File

@ -18,9 +18,6 @@ class Issue < ActiveRecord::Base
after_create :set_serial_id after_create :set_serial_id
after_create :subscribe_users 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 after_update :subscribe_issue_assigned_user
attr_accessible :labelings_attributes, :title, :body attr_accessible :labelings_attributes, :title, :body
@ -58,6 +55,14 @@ class Issue < ActiveRecord::Base
self.status = 'open' self.status = 'open'
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'
recipients
end
protected protected
def set_serial_id def set_serial_id
@ -65,18 +70,6 @@ class Issue < ActiveRecord::Base
self.save! self.save!
end 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 def subscribe_users
recipients = collect_recipient_ids recipients = collect_recipient_ids
recipients.each do |recipient_id| recipients.each do |recipient_id|
@ -85,19 +78,6 @@ class Issue < ActiveRecord::Base
end end
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 def subscribe_issue_assigned_user
if self.user_id_was != self.user_id 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? self.subscribes.where(:user_id => self.user_id_was).first.destroy unless self.user_id_was.blank?

View File

@ -10,7 +10,7 @@ class Product < ActiveRecord::Base
has_attached_file :tar 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} validates :name, :presence => true, :uniqueness => {:scope => :platform_id}
scope :recent, order("name ASC") scope :recent, order("name ASC")

View File

@ -14,6 +14,7 @@ class ProductBuildList < ActiveRecord::Base
attr_accessor :base_url attr_accessor :base_url
after_create :xml_rpc_create after_create :xml_rpc_create
after_destroy :xml_delete_iso_container
def container_path def container_path
"/downloads/#{product.platform.name}/product/#{id}/" "/downloads/#{product.platform.name}/product/#{id}/"
@ -34,8 +35,17 @@ class ProductBuildList < ActiveRecord::Base
if result == ProductBuilder::SUCCESS if result == ProductBuilder::SUCCESS
return true return true
else else
# return false raise "Failed to create product_build_list #{id} inside platform #{platform.name} tar url #{tar_url} with code #{result}."
raise "Failed to create product_build_list #{id} inside platform #{product.platform.name} tar url #{tar_url} with code #{result}."
end end
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 end

View File

@ -204,7 +204,13 @@ class Project < ActiveRecord::Base
def self.process_hook(owner_uname, repo, newrev, oldrev, ref, newrev_type, oldrev_type) 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) 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 end
protected protected

View File

@ -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) Subscribe.where(:subscribeable_id => comment.commentable_id, :subscribeable_type => comment.commentable.class.name, :project_id => comment.project)
end 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) 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 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 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) (user.committer?(commit) && user.notifier.new_comment_commit_owner)
end end
def self.subscribe_to_commit(options) def self.subscribe_to_commit(options)
Subscribe.set_subscribe_to_commit(options, true) Subscribe.set_subscribe_to_commit(options, true)
end end
def self.unsubscribe_from_commit(options) def self.unsubscribe_from_commit(options)
Subscribe.set_subscribe_to_commit(options, false) Subscribe.set_subscribe_to_commit(options, false)
end end

View File

@ -9,6 +9,8 @@ class User < ActiveRecord::Base
has_one :notifier, :class_name => 'Settings::Notifier' #:notifier has_one :notifier, :class_name => 'Settings::Notifier' #:notifier
has_many :activity_feeds
has_many :authentications, :dependent => :destroy has_many :authentications, :dependent => :destroy
has_many :build_lists, :dependent => :destroy has_many :build_lists, :dependent => :destroy
has_many :subscribes, :foreign_key => :user_id, :dependent => :destroy has_many :subscribes, :foreign_key => :user_id, :dependent => :destroy

View File

@ -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

View File

@ -0,0 +1,3 @@
%p== Branch #{ branch_name } has been deleted
%p== Into project #{ link_to(project_name, project_path(project_id)) }

View File

@ -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

View File

@ -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)))

View File

@ -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 }"

View File

@ -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 }"

View File

@ -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)))

View File

@ -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) }

View File

@ -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)) }

View File

@ -113,7 +113,7 @@
= link_to t("layout.edit"), edit_platform_product_path(@platform, product) if can? :update, product = 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 = 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-bar.wat-cf
.actions .actions
- content_for :sidebar, render(:partial => 'sidebar') - content_for :sidebar, render(:partial => 'sidebar')

View File

@ -3,5 +3,5 @@
%td= link_to product_build_list.product.name, [product_build_list.product.platform, product_build_list.product] %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= link_to nil, product_build_list.container_path
%td= product_build_list.human_status %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 %td= product_build_list.notified_at

View File

@ -31,7 +31,7 @@
- if can? :destroy, @product - 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") = 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? - 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) - 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") = link_to t("layout.products.build"), platform_product_product_build_lists_path(@platform, @product), :class => "button", :method => 'post', :confirm => t("layout.confirm")

View File

@ -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»

View File

@ -6,7 +6,5 @@
%p %p
==Your email : #{@user.email} ==Your email : #{@user.email}
%br/
==Your password: #{@user.password}
%p== Support team «ROSA Build System» %p== Support team «ROSA Build System»

View File

@ -6,7 +6,5 @@
%p %p
==Ваш email : #{@user.email} ==Ваш email : #{@user.email}
%br/
==Ваш пароль: #{@user.password}
%p== Команда поддержки «ROSA Build System» %p== Команда поддержки «ROSA Build System»

View File

@ -31,7 +31,7 @@ module Rosa
# config.plugins = [ :exception_notification, :ssl_requirement, :all ] # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running. # 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. # 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. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.

View File

@ -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}

View File

@ -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

View File

@ -109,126 +109,6 @@ en:
edit_header: Edit category edit_header: Edit category
confirm_delete: Are you sure to delete this 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: collaborators:
back_to_proj: Back to project back_to_proj: Back to project
edit: Edit list edit: Edit list
@ -246,27 +126,6 @@ en:
writer: Writer writer: Writer
admin: Admin 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: git:
repositories: repositories:
empty: "Repository is empty. You need to wait some time if you have forked project or imported package" 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 saved: Settings saved success
save_error: Setting update error save_error: Setting update error
private_users: "Login: %{login} Password: %{password}"
subscribe: subscribe:
saved: Subscription on notifications for this task is created saved: Subscription on notifications for this task is created
saved_error: Subscription create error
destroyed: Subscription on notifications for this task is cleaned 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! exception_message: Access violation to this page!
@ -319,66 +183,6 @@ en:
save_error: Category saves error save_error: Category saves error
destroyed: Category deleted 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: blob:
successfully_updated: File '%{name}' successfully updated successfully_updated: File '%{name}' successfully updated
updating_error: Error updating file '%{name}' updating_error: Error updating file '%{name}'
@ -401,35 +205,13 @@ en:
models: models:
category: Category category: Category
repository: Repository
arch: Arch arch: Arch
container: Container container: Container
platform: Platform
group: Group
event_log: Event log
project: Project
rpm: RPM rpm: RPM
user: User
private_user: Private user private_user: Private user
product: Product
product_build_list: Product build list product_build_list: Product build list
download: Statistics download: Statistics
auto_build_list: Auto rebuild list 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: attributes:
settings: settings:
@ -439,6 +221,9 @@ en:
new_comment_reply: New reply of comment notifications new_comment_reply: New reply of comment notifications
new_issue: New task notifications new_issue: New task notifications
issue_assign: New task assignment 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: auto_build_list:
project_id: Project project_id: Project
@ -450,10 +235,6 @@ en:
arch_id: Architecture arch_id: Architecture
arch: Architecture arch: Architecture
comment:
body: Content
user: Author
private_user: private_user:
login: Login login: Login
password: Password password: Password
@ -462,32 +243,6 @@ en:
parent_id: Parent parent_id: Parent
name: Name 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: arch:
name: Name name: Name
created_at: Created created_at: Created
@ -502,48 +257,6 @@ en:
created_at: Created created_at: Created
updated_at: Updated 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: rpm:
name: Name name: Name
arch_id: Arch arch_id: Arch
@ -553,28 +266,6 @@ en:
created_at: Created created_at: Created
updated_at: Updated 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: product_build_list:
id: Id id: Id
product: Product product: Product
@ -588,12 +279,3 @@ en:
distro: Source distro: Source
platform: Platform platform: Platform
counter: Downloads 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

View File

@ -572,11 +572,3 @@ ru:
platform: Архитектура platform: Архитектура
counter: Закачки 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

View File

@ -184,6 +184,8 @@ Rosa::Application.routes.draw do
end end
end end
resources :activity_feeds, :only => [:index]
resources :users, :groups do resources :users, :groups do
resources :platforms, :only => [:new, :create] 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/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 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' match '/forbidden', :to => 'platforms#forbidden', :as => 'forbidden'
end end

View File

@ -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

View File

@ -21,6 +21,14 @@ ActiveRecord::Schema.define(:version => 20120302102734) do
t.datetime "updated_at" t.datetime "updated_at"
end 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| create_table "arches", :force => true do |t|
t.string "name", :null => false t.string "name", :null => false
t.datetime "created_at" t.datetime "created_at"

View File

@ -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, 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}" : '') pbl.product.counter, [], pbl.product.tar.exists? ? "#{pbl.base_url}#{pbl.product.tar.url}" : '')
end 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 end

View File

@ -0,0 +1,5 @@
require 'spec_helper'
describe ActivityFeedsController do
end

View File

@ -0,0 +1,6 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :activity_feed do
end
end

View File

@ -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

View File

@ -0,0 +1,5 @@
require 'spec_helper'
describe ActivityFeedObserver do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'spec_helper'
describe ActivityFeed do
pending "add some examples to (or delete) #{__FILE__}"
end