From a5f56bb83541494311a5f6de93c2bf1e36fcdac0 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 11 Mar 2014 13:39:25 +0600 Subject: [PATCH] [#345] remove observers; use new labmda syntax --- app/controllers/application_controller.rb | 6 +- app/controllers/groups/members_controller.rb | 2 +- .../projects/git/blobs_controller.rb | 2 +- .../projects/git/trees_controller.rb | 6 +- app/models/activity_feed.rb | 11 ++- app/models/advisory.rb | 11 +-- app/models/arch.rb | 2 +- app/models/authentication.rb | 2 +- app/models/avatar.rb | 7 +- app/models/build_list.rb | 69 ++++++++++--------- app/models/build_list/package.rb | 10 +-- app/models/build_list_observer.rb | 30 -------- app/models/comment.rb | 8 +-- app/models/concerns/build_list_observer.rb | 36 ++++++++++ app/models/concerns/event_loggable.rb | 32 +++++++++ .../models/concerns/feed}/build_list.rb | 2 +- .../models/concerns/feed}/comment.rb | 2 +- .../models/concerns/feed}/git.rb | 2 +- .../models/concerns/feed}/issue.rb | 2 +- .../models/concerns/feed}/user.rb | 2 +- app/models/event_log.rb | 4 +- app/models/event_log_observer.rb | 25 ------- app/models/feedback.rb | 10 +-- app/models/flash_notify.rb | 2 +- app/models/git_hook.rb | 7 +- app/models/group.rb | 19 ++--- app/models/hook.rb | 2 +- app/models/issue.rb | 18 ++--- app/models/labeling.rb | 1 - app/models/mass_build.rb | 6 +- app/models/platform.rb | 32 ++++----- app/models/platform_arch_setting.rb | 5 +- app/models/platform_content.rb | 18 +---- app/models/product.rb | 3 +- app/models/product_build_list.rb | 23 ++++--- app/models/project.rb | 57 ++++++++------- app/models/project_import.rb | 4 +- app/models/project_tag.rb | 7 +- app/models/project_to_repository.rb | 10 +-- app/models/pull_request.rb | 8 +-- app/models/register_request.rb | 11 +-- app/models/relation.rb | 13 ++-- app/models/repository.rb | 9 ++- app/models/repository_status.rb | 11 ++- app/models/rpm_build_node.rb | 3 +- app/models/ssh_key.rb | 2 +- app/models/token.rb | 6 +- app/models/user.rb | 38 ++++++---- config/application.rb | 10 +-- config/initializers/devise.rb | 2 + config/routes.rb | 18 ++--- lib/modules/models/acts_like_member.rb | 10 +-- lib/modules/models/commit_and_version.rb | 2 +- lib/modules/models/git.rb | 2 +- lib/modules/models/owner.rb | 2 +- lib/modules/models/time_living.rb | 9 +-- 56 files changed, 344 insertions(+), 309 deletions(-) delete mode 100644 app/models/build_list_observer.rb create mode 100644 app/models/concerns/build_list_observer.rb create mode 100644 app/models/concerns/event_loggable.rb rename {lib/modules/observers/activity_feed => app/models/concerns/feed}/build_list.rb (95%) rename {lib/modules/observers/activity_feed => app/models/concerns/feed}/comment.rb (98%) rename {lib/modules/observers/activity_feed => app/models/concerns/feed}/git.rb (98%) rename {lib/modules/observers/activity_feed => app/models/concerns/feed}/issue.rb (97%) rename {lib/modules/observers/activity_feed => app/models/concerns/feed}/user.rb (86%) delete mode 100644 app/models/event_log_observer.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5c9ea8e62..1c8fe7173 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -7,12 +7,12 @@ class ApplicationController < ActionController::Base layout :layout_by_resource # Hack to prevent token auth on all pages except atom feed: - prepend_before_filter lambda { redirect_to(new_user_session_path) if params[:token] && params[:token].is_a?(String) && params[:format] != 'atom'} + prepend_before_filter -> { redirect_to(new_user_session_path) if params[:token] && params[:token].is_a?(String) && params[:format] != 'atom'} before_filter :set_locale - before_filter lambda { EventLog.current_controller = self }, + before_filter -> { EventLog.current_controller = self }, only: [:create, :destroy, :open_id, :cancel, :publish, :change_visibility] # :update - after_filter lambda { EventLog.current_controller = nil } + after_filter -> { EventLog.current_controller = nil } helper_method :get_owner diff --git a/app/controllers/groups/members_controller.rb b/app/controllers/groups/members_controller.rb index 2493e719f..4b730cf1e 100644 --- a/app/controllers/groups/members_controller.rb +++ b/app/controllers/groups/members_controller.rb @@ -1,5 +1,5 @@ class Groups::MembersController < Groups::BaseController - before_filter lambda { authorize! :manage_members, @group } + before_filter -> { authorize! :manage_members, @group } def index end diff --git a/app/controllers/projects/git/blobs_controller.rb b/app/controllers/projects/git/blobs_controller.rb index 1ab13ab05..a8c6c16f1 100644 --- a/app/controllers/projects/git/blobs_controller.rb +++ b/app/controllers/projects/git/blobs_controller.rb @@ -1,6 +1,6 @@ class Projects::Git::BlobsController < Projects::Git::BaseController before_filter :set_blob - before_filter lambda {authorize! :write, @project}, only: [:edit, :update] + before_filter -> {authorize! :write, @project}, only: [:edit, :update] def show end diff --git a/app/controllers/projects/git/trees_controller.rb b/app/controllers/projects/git/trees_controller.rb index b9ddd2505..95e342a9b 100644 --- a/app/controllers/projects/git/trees_controller.rb +++ b/app/controllers/projects/git/trees_controller.rb @@ -1,10 +1,10 @@ class Projects::Git::TreesController < Projects::Git::BaseController - before_filter lambda{redirect_to @project if params[:treeish] == @project.default_branch and params[:path].blank?}, only: :show + before_filter -> {redirect_to @project if params[:treeish] == @project.default_branch and params[:path].blank?}, only: :show skip_before_filter :set_branch_and_tree, :set_treeish_and_path, only: :archive - before_filter lambda { raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name) }, only: [:branch, :destroy] + before_filter -> { raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name) }, only: [:branch, :destroy] skip_authorize_resource :project, only: [:destroy, :restore_branch, :create] - before_filter lambda { authorize!(:write, @project) }, only: [:destroy, :restore_branch, :create] + before_filter -> { authorize!(:write, @project) }, only: [:destroy, :restore_branch, :create] def show unless request.xhr? diff --git a/app/models/activity_feed.rb b/app/models/activity_feed.rb index 1052250f6..5bee6ecc8 100644 --- a/app/models/activity_feed.rb +++ b/app/models/activity_feed.rb @@ -1,20 +1,19 @@ class ActivityFeed < ActiveRecord::Base - CODE = ['git_delete_branch_notification', 'git_new_push_notification', 'new_comment_commit_notification'] + CODE = ['git_delete_branch_notification', 'git_new_push_notification', 'new_comment_commit_notification'] TRACKER = ['issue_assign_notification', 'new_comment_notification', 'new_issue_notification'] - BUILD = ['build_list_notification'] - WIKI = ['wiki_new_commit_notification'] + BUILD = ['build_list_notification'] + WIKI = ['wiki_new_commit_notification'] belongs_to :user serialize :data - default_scope order("#{table_name}.created_at DESC") - scope :outdated, offset(100) + default_scope { order created_at: :desc } + scope :outdated, -> { offset(100) } self.per_page = 10 def partial 'home/partials/' + self.kind end - end diff --git a/app/models/advisory.rb b/app/models/advisory.rb index 1eaf69d2b..b27fed1a2 100644 --- a/app/models/advisory.rb +++ b/app/models/advisory.rb @@ -1,4 +1,6 @@ class Advisory < ActiveRecord::Base + self.include_root_in_json = false + has_and_belongs_to_many :platforms has_and_belongs_to_many :projects has_many :build_lists @@ -13,14 +15,14 @@ class Advisory < ActiveRecord::Base ID_STRING_TEMPLATE = 'ROSA-%s-%04s:%04s' TYPES = {'security' => 'SA', 'bugfix' => 'A'} - scope :search, lambda { |q| + scope :search, ->(q) { q = q.to_s.strip where("#{table_name}.advisory_id ILIKE :q OR #{table_name}.description ILIKE :q OR build_list_packages.fullname ILIKE :q", q: "%#{q}%"). joins(build_lists: :packages) if q.present? } - scope :search_by_id, lambda { |aid| where("#{table_name}.advisory_id ILIKE ?", "%#{aid.to_s.strip}%") } - scope :by_update_type, lambda { |ut| where(update_type: ut) } - default_scope order("#{table_name}.created_at DESC") + scope :search_by_id, ->(aid) { where("#{table_name}.advisory_id ILIKE ?", "%#{aid.to_s.strip}%") } + scope :by_update_type, ->(ut) { where(update_type: ut) } + default_scope { order(created_at: :desc) } def to_param advisory_id @@ -69,4 +71,3 @@ class Advisory < ActiveRecord::Base end end -Advisory.include_root_in_json = false \ No newline at end of file diff --git a/app/models/arch.rb b/app/models/arch.rb index afe2ce920..3f371ae7e 100644 --- a/app/models/arch.rb +++ b/app/models/arch.rb @@ -5,5 +5,5 @@ class Arch < ActiveRecord::Base validates :name, presence: true, uniqueness: true - scope :recent, order("#{table_name}.name ASC") + scope :recent, -> { order(:name) } end diff --git a/app/models/authentication.rb b/app/models/authentication.rb index 26ee1ebdb..68518b6e4 100644 --- a/app/models/authentication.rb +++ b/app/models/authentication.rb @@ -2,5 +2,5 @@ class Authentication < ActiveRecord::Base belongs_to :user validates :provider, :uid, :user_id, presence: true - validates :uid, uniqueness: {scope: :provider, case_sensitive: false} + validates :uid, uniqueness: { scope: :provider, case_sensitive: false } end diff --git a/app/models/avatar.rb b/app/models/avatar.rb index 81af22c72..9296b1a7f 100644 --- a/app/models/avatar.rb +++ b/app/models/avatar.rb @@ -2,18 +2,19 @@ class Avatar < ActiveRecord::Base self.abstract_class = true MAX_AVATAR_SIZE = 5.megabyte - AVATAR_SIZES = {micro: 16, small: 30, medium: 40, big: 81} + AVATAR_SIZES = { micro: 16, small: 30, medium: 40, big: 81 } AVATAR_SIZES_HASH = {}.tap do |styles| AVATAR_SIZES.each do |name, size| - styles[name] = { geometry: "#{size}x#{size}#", format: :jpg, convert_options: '-strip -background white -flatten -quality 70'} + styles[name] = { geometry: "#{size}x#{size}#", format: :jpg, + convert_options: '-strip -background white -flatten -quality 70' } end end + has_attached_file :avatar, styles: AVATAR_SIZES_HASH validates_attachment_size :avatar, less_than_or_equal_to: MAX_AVATAR_SIZE validates_attachment_content_type :avatar, content_type: /\Aimage/ validates_attachment_file_name :avatar, matches: [ /(png|jpe?g|gif|bmp|tif?f)\z/i ] attr_accessible :avatar - end diff --git a/app/models/build_list.rb b/app/models/build_list.rb index c64cfd968..ad749c2af 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -2,7 +2,9 @@ class BuildList < ActiveRecord::Base include Modules::Models::CommitAndVersion include Modules::Models::FileStoreClean include AbfWorker::ModelHelper - include Modules::Observers::ActivityFeed::BuildList + include Feed::BuildList + include BuildListObserver + include EventLoggable belongs_to :project belongs_to :arch @@ -16,7 +18,7 @@ class BuildList < ActiveRecord::Base belongs_to :mass_build, counter_cache: true, touch: true has_many :items, class_name: '::BuildList::Item', dependent: :destroy has_many :packages, class_name: '::BuildList::Package', dependent: :destroy - has_many :source_packages, class_name: '::BuildList::Package', conditions: {package_type: 'source'} + has_many :source_packages, class_name: '::BuildList::Package', conditions: { package_type: 'source' } UPDATE_TYPES = %w[bugfix security enhancement recommended newpackage] RELEASE_UPDATE_TYPES = %w[bugfix security] @@ -31,28 +33,28 @@ class BuildList < ActiveRecord::Base validates :project_id, :project_version, :arch, :include_repos, :build_for_platform_id, :save_to_platform_id, :save_to_repository_id, presence: true validates_numericality_of :priority, greater_than_or_equal_to: 0 - validates :external_nodes, inclusion: {in: EXTERNAL_NODES}, allow_blank: true - validates :auto_publish_status, inclusion: {in: AUTO_PUBLISH_STATUSES} + validates :external_nodes, inclusion: { in: EXTERNAL_NODES }, allow_blank: true + validates :auto_publish_status, inclusion: { in: AUTO_PUBLISH_STATUSES } validates :update_type, inclusion: UPDATE_TYPES, unless: Proc.new { |b| b.advisory.present? } - validates :update_type, inclusion: {in: RELEASE_UPDATE_TYPES, message: I18n.t('flash.build_list.frozen_platform')}, + validates :update_type, inclusion: { in: RELEASE_UPDATE_TYPES, message: I18n.t('flash.build_list.frozen_platform') }, if: Proc.new { |b| b.advisory.present? } - validate lambda { + validate -> { errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_platform')) if save_to_platform.main? && save_to_platform_id != build_for_platform_id } - validate lambda { + validate -> { errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_build_for_platform')) unless build_for_platform.main? } - validate lambda { + validate -> { errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_repository')) if save_to_repository.platform_id != save_to_platform.id } - validate lambda { + validate -> { errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_include_repos')) if build_for_platform.repositories.where(id: include_repos).count != include_repos.size } - validate lambda { + validate -> { errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_project')) unless save_to_repository.projects.exists?(project_id) } - before_validation lambda { self.include_repos = include_repos.uniq if include_repos.present? }, on: :create + before_validation -> { self.include_repos = include_repos.uniq if include_repos.present? }, on: :create before_validation :prepare_extra_repositories, on: :create before_validation :prepare_extra_build_lists, on: :create before_validation :prepare_extra_params, on: :create @@ -95,40 +97,45 @@ class BuildList < ActiveRecord::Base STATUSES.freeze HUMAN_STATUSES.freeze - scope :recent, order("#{table_name}.updated_at DESC") - scope :for_extra_build_lists, lambda {|ids, current_ability, save_to_platform| + scope :recent, -> { order(updated_at: :desc) } + scope :for_extra_build_lists, ->(ids, current_ability, save_to_platform) { s = scoped s = s.where(id: ids).published_container.accessible_by(current_ability, :read) s = s.where(save_to_platform_id: save_to_platform.id) if save_to_platform && save_to_platform.main? s } - scope :for_status, lambda {|status| where(status: status) if status.present? } - scope :for_user, lambda { |user| where(user_id: user.id) } - scope :not_owned_external_nodes, where("#{table_name}.external_nodes is null OR #{table_name}.external_nodes != ?", :owned) - scope :external_nodes, lambda { |type| where("#{table_name}.external_nodes = ?", type) } - scope :oldest, lambda { where("#{table_name}.updated_at < ?", Time.zone.now - 15.seconds) } - scope :for_platform, lambda { |platform| where(build_for_platform_id: platform) } - scope :by_mass_build, lambda { |mass_build| where(mass_build_id: mass_build) } - scope :scoped_to_arch, lambda {|arch| where(arch_id: arch) if arch.present? } - scope :scoped_to_save_platform, lambda {|pl_id| where(save_to_platform_id: pl_id) if pl_id.present? } - scope :scoped_to_project_version, lambda {|project_version| where(project_version: project_version) if project_version.present? } - scope :scoped_to_is_circle, lambda {|is_circle| where(is_circle: is_circle) } - scope :for_creation_date_period, lambda{|start_date, end_date| + scope :for_status, ->(status) { where(status: status) if status.present? } + scope :for_user, ->(user) { where(user_id: user.id) } + scope :not_owned_external_nodes, -> { where("#{table_name}.external_nodes is null OR #{table_name}.external_nodes != ?", :owned) } + scope :external_nodes, ->(type) { where("#{table_name}.external_nodes = ?", type) } + scope :oldest, -> { where("#{table_name}.updated_at < ?", Time.zone.now - 15.seconds) } + scope :for_platform, ->(platform) { where(build_for_platform_id: platform) } + scope :by_mass_build, ->(mass_build) { where(mass_build_id: mass_build) } + scope :scoped_to_arch, ->(arch) { where(arch_id: arch) if arch.present? } + scope :scoped_to_save_platform, ->(pl_id) { where(save_to_platform_id: pl_id) if pl_id.present? } + scope :scoped_to_project_version, ->(pr_version) { where(project_version: pr_version) if pr_version.present? } + scope :scoped_to_is_circle, ->(is_circle) { { where(is_circle: is_circle) } + scope :for_creation_date_period, ->(start_date, end_date) { s = scoped s = s.where(["#{table_name}.created_at >= ?", start_date]) if start_date s = s.where(["#{table_name}.created_at <= ?", end_date]) if end_date s } - scope :for_notified_date_period, lambda{|start_date, end_date| + scope :for_notified_date_period, ->(start_date, end_date) { s = scoped s = s.where("#{table_name}.updated_at >= ?", start_date) if start_date.present? s = s.where("#{table_name}.updated_at <= ?", end_date) if end_date.present? s } - scope :scoped_to_project_name, lambda {|project_name| joins(:project).where('projects.name LIKE ?', "%#{project_name}%") if project_name.present? } - scope :scoped_to_new_core, lambda {|new_core| where(new_core: new_core)} - scope :outdated, where("#{table_name}.created_at < ? AND #{table_name}.status NOT IN (?) OR #{table_name}.created_at < ?", Time.now - LIVE_TIME, [BUILD_PUBLISHED,BUILD_PUBLISHED_INTO_TESTING], Time.now - MAX_LIVE_TIME) - scope :published_container, where(container_status: BUILD_PUBLISHED) + scope :scoped_to_project_name, ->(project_name) { + joins(:project).where('projects.name LIKE ?', "%#{project_name}%") if project_name.present? + } + scope :scoped_to_new_core, ->(new_core) { where(new_core: new_core) } + scope :outdated, -> { + where("#{table_name}.created_at < ? AND #{table_name}.status NOT IN (?) OR #{table_name}.created_at < ?", + Time.now - LIVE_TIME, [BUILD_PUBLISHED,BUILD_PUBLISHED_INTO_TESTING], Time.now - MAX_LIVE_TIME) + } + scope :published_container, -> { where(container_status: BUILD_PUBLISHED) } serialize :additional_repos serialize :include_repos @@ -157,7 +164,7 @@ class BuildList < ActiveRecord::Base after_transition on: [:published, :fail_publish, :build_error, :tests_failed], do: :notify_users after_transition on: :build_success, do: :notify_users, - unless: lambda { |build_list| build_list.auto_publish? || build_list.auto_publish_into_testing? } + unless: -> { |build_list| build_list.auto_publish? || build_list.auto_publish_into_testing? } event :place_build do transition waiting_for_response: :build_pending diff --git a/app/models/build_list/package.rb b/app/models/build_list/package.rb index 924b5220f..e02404ec0 100644 --- a/app/models/build_list/package.rb +++ b/app/models/build_list/package.rb @@ -16,11 +16,11 @@ class BuildList::Package < ActiveRecord::Base default_scope order("lower(#{table_name}.name) ASC, length(#{table_name}.name) ASC") # Fetches only actual (last publised) packages. - scope :actual, where(actual: true) - scope :by_platform, lambda {|platform| where(platform_id: platform) } - scope :by_name, lambda {|name| where(name: name) } - scope :by_package_type, lambda {|type| where(package_type: type) } - scope :like_name, lambda {|name| where("#{table_name}.name ILIKE ?", "%#{name}%") if name.present?} + scope :actual, -> { where(actual: true) } + scope :by_platform, ->(platform) { where(platform_id: platform) } + scope :by_name, ->(name) { where(name: name) } + scope :by_package_type, ->(type) { where(package_type: type) } + scope :like_name, ->(name) { where("#{table_name}.name ILIKE ?", "%#{name}%") if name.present? } before_create :set_epoch diff --git a/app/models/build_list_observer.rb b/app/models/build_list_observer.rb deleted file mode 100644 index aa4662772..000000000 --- a/app/models/build_list_observer.rb +++ /dev/null @@ -1,30 +0,0 @@ -class BuildListObserver < ActiveRecord::Observer - observe :build_list - - def before_update(record) - if record.status_changed? - record.started_at = Time.now if record.status == BuildList::BUILD_STARTED - if [BuildList::BUILD_ERROR, - BuildList::SUCCESS, - BuildList::BUILD_CANCELING, - BuildList::TESTS_FAILED, - BuildList::BUILD_CANCELED].include? record.status - # stores time interval beetwin build start and finish in seconds - record.duration = record.current_duration if record.started_at - - if record.status == BuildList::SUCCESS - # Update project average build time - begin - statistic = record.project.project_statistics.find_or_create_by_arch_id(record.arch_id) - rescue ActiveRecord::RecordNotUnique - retry - end - build_count = statistic.build_count.to_i - new_av_time = ( statistic.average_build_time * build_count + record.duration.to_i ) / ( build_count + 1 ) - statistic.update_attributes(average_build_time: new_av_time, build_count: build_count + 1) - end - end - end - end # before_update - -end diff --git a/app/models/comment.rb b/app/models/comment.rb index cfcb969e0..d674c38dc 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,5 +1,5 @@ class Comment < ActiveRecord::Base - include Modules::Observers::ActivityFeed::Comment + include 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 @@ -14,10 +14,10 @@ class Comment < ActiveRecord::Base validates :body, :user_id, :commentable_id, :commentable_type, :project_id, presence: true - scope :for_commit, lambda {|c| where(commentable_id: c.id.hex, commentable_type: c.class)} - default_scope order("#{table_name}.created_at") + scope :for_commit, ->(c) { where(commentable_id: c.id.hex, commentable_type: c.class) } + default_scope { order(:created_at) } - after_create :subscribe_on_reply, unless: lambda {|c| c.commit_comment?} + after_create :subscribe_on_reply, unless: -> {|c| c.commit_comment?} after_create :subscribe_users attr_accessible :body, :data diff --git a/app/models/concerns/build_list_observer.rb b/app/models/concerns/build_list_observer.rb new file mode 100644 index 000000000..8061a3c54 --- /dev/null +++ b/app/models/concerns/build_list_observer.rb @@ -0,0 +1,36 @@ +module BuildListObserver + extend ActiveSupport::Concern + + included do + before_update :update_average_build_time + end + + private + + def update_average_build_time + if status_changed? + started_at = Time.now if status == BUILD_STARTED + if [BUILD_ERROR, + SUCCESS, + BUILD_CANCELING, + TESTS_FAILED, + BUILD_CANCELED].include? status + # stores time interval beetwin build start and finish in seconds + duration = current_duration if started_at + + if status == SUCCESS + # Update project average build time + begin + statistic = project.project_statistics.find_or_create_by_arch_id(arch_id) + rescue ActiveRecord::RecordNotUnique + retry + end + build_count = statistic.build_count.to_i + new_av_time = ( statistic.average_build_time * build_count + record.duration.to_i ) / ( build_count + 1 ) + statistic.update_attributes(average_build_time: new_av_time, build_count: build_count + 1) + end + end + end + end + +end diff --git a/app/models/concerns/event_loggable.rb b/app/models/concerns/event_loggable.rb new file mode 100644 index 000000000..ff8b7ecce --- /dev/null +++ b/app/models/concerns/event_loggable.rb @@ -0,0 +1,32 @@ +module EventLoggable + extend ActiveSupport::Concern + + included do + after_create :log_creation_event + after_destroy :log_destroying_event + end + + private + + def log_creation_event + ActiveSupport::Notifications.instrument(self.class.name, eventable: self) + end + + def log_before_update + case self.class.to_s + when 'BuildList' + if status_changed? and [BuildList::BUILD_CANCELED, BuildList::BUILD_PUBLISHED].include?(status) + ActiveSupport::Notifications.instrument("event_log.observer", eventable: self) + end + when 'Platform' + if self.visibility_changed? + ActiveSupport::Notifications.instrument "event_log.observer", eventable: self, + message: I18n.t("activeself.attributes.platform.visibility_types.#{visibility}") + end + end + end + + def destroying_event + ActiveSupport::Notifications.instrument(self.class.name, eventable: self) + end +end diff --git a/lib/modules/observers/activity_feed/build_list.rb b/app/models/concerns/feed/build_list.rb similarity index 95% rename from lib/modules/observers/activity_feed/build_list.rb rename to app/models/concerns/feed/build_list.rb index b2230357f..49f1ad99e 100644 --- a/lib/modules/observers/activity_feed/build_list.rb +++ b/app/models/concerns/feed/build_list.rb @@ -1,4 +1,4 @@ -module Modules::Observers::ActivityFeed::BuildList +module Feed::BuildList extend ActiveSupport::Concern included do diff --git a/lib/modules/observers/activity_feed/comment.rb b/app/models/concerns/feed/comment.rb similarity index 98% rename from lib/modules/observers/activity_feed/comment.rb rename to app/models/concerns/feed/comment.rb index 162e38a98..46b9684cc 100644 --- a/lib/modules/observers/activity_feed/comment.rb +++ b/app/models/concerns/feed/comment.rb @@ -1,4 +1,4 @@ -module Modules::Observers::ActivityFeed::Comment +module Feed::Comment extend ActiveSupport::Concern included do diff --git a/lib/modules/observers/activity_feed/git.rb b/app/models/concerns/feed/git.rb similarity index 98% rename from lib/modules/observers/activity_feed/git.rb rename to app/models/concerns/feed/git.rb index 77edff99e..537baec6b 100644 --- a/lib/modules/observers/activity_feed/git.rb +++ b/app/models/concerns/feed/git.rb @@ -1,4 +1,4 @@ -module Modules::Observers::ActivityFeed::Git +module Feed::Git def self.create_notifications(record) diff --git a/lib/modules/observers/activity_feed/issue.rb b/app/models/concerns/feed/issue.rb similarity index 97% rename from lib/modules/observers/activity_feed/issue.rb rename to app/models/concerns/feed/issue.rb index cb62545ab..b5d090b1e 100644 --- a/lib/modules/observers/activity_feed/issue.rb +++ b/app/models/concerns/feed/issue.rb @@ -1,4 +1,4 @@ -module Modules::Observers::ActivityFeed::Issue +module Feed::Issue extend ActiveSupport::Concern included do diff --git a/lib/modules/observers/activity_feed/user.rb b/app/models/concerns/feed/user.rb similarity index 86% rename from lib/modules/observers/activity_feed/user.rb rename to app/models/concerns/feed/user.rb index 1b7ac6e48..cfc2aed00 100644 --- a/lib/modules/observers/activity_feed/user.rb +++ b/app/models/concerns/feed/user.rb @@ -1,4 +1,4 @@ -module Modules::Observers::ActivityFeed::User +module Feed::User extend ActiveSupport::Concern included do diff --git a/app/models/event_log.rb b/app/models/event_log.rb index 43987869b..d36dd08d3 100644 --- a/app/models/event_log.rb +++ b/app/models/event_log.rb @@ -4,8 +4,8 @@ class EventLog < ActiveRecord::Base # self.per_page = 1 - scope :eager_loading, preload(:user) - scope :default_order, order("#{table_name}.id DESC") # order('created_at DESC') + scope :eager_loading, -> { preload(:user) } + scope :default_order -> { order(id: :desc) } before_create do self.user_name = user.try(:uname) || 'guest' diff --git a/app/models/event_log_observer.rb b/app/models/event_log_observer.rb deleted file mode 100644 index df47381c3..000000000 --- a/app/models/event_log_observer.rb +++ /dev/null @@ -1,25 +0,0 @@ -class EventLogObserver < ActiveRecord::Observer - observe :user, :platform, :repository, :project, :product, :build_list, :product_build_list - - def after_create(record) - ActiveSupport::Notifications.instrument("event_log.observer", eventable: record) - end - - def before_update(record) - case record.class.to_s - when 'BuildList' - if record.status_changed? and [BuildList::BUILD_CANCELED, BuildList::BUILD_PUBLISHED].include?(record.status) - ActiveSupport::Notifications.instrument("event_log.observer", eventable: record) - end - when 'Platform' - if record.visibility_changed? - ActiveSupport::Notifications.instrument "event_log.observer", eventable: record, - message: I18n.t("activerecord.attributes.platform.visibility_types.#{record.visibility}") - end - end - end - - def after_destroy(record) - ActiveSupport::Notifications.instrument("event_log.observer", eventable: record) - end -end diff --git a/app/models/feedback.rb b/app/models/feedback.rb index fc079eaaf..cc383bedd 100644 --- a/app/models/feedback.rb +++ b/app/models/feedback.rb @@ -8,14 +8,16 @@ class Feedback include ActiveModel::MassAssignmentSecurity extend ActiveModel::Naming + self.include_root_in_json = false + attr_accessor :name, :email, :subject, :message attr_accessible :name, :email, :subject, :message validates :name, :subject, :message, presence: true - validates :email, presence: true, - format: { with: /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/, - allow_blank: false } + validates :email, presence: true, + format: { with: /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/, + allow_blank: false } def initialize(args = {}, options = {}) return args.dup if args.is_a? Feedback @@ -99,6 +101,4 @@ class Feedback perform_validation = options[:validate] != false perform_validation ? valid?(options[:context]) : true end - end -Feedback.include_root_in_json = false diff --git a/app/models/flash_notify.rb b/app/models/flash_notify.rb index fe87db69e..62242bcfd 100644 --- a/app/models/flash_notify.rb +++ b/app/models/flash_notify.rb @@ -8,7 +8,7 @@ class FlashNotify < ActiveRecord::Base validates :status, inclusion: {in: STATUSES} validates :body_ru, :body_en, :status, presence: true - scope :published, where(published: true) + scope :published, -> { where(published: true) } def hash_id @digest ||= Digest::MD5.hexdigest("#{self.id}-#{self.updated_at}") diff --git a/app/models/git_hook.rb b/app/models/git_hook.rb index 769159cef..eefcf29df 100644 --- a/app/models/git_hook.rb +++ b/app/models/git_hook.rb @@ -1,12 +1,13 @@ class GitHook + include Feed::Git + include Resque::Plugins::Status + ZERO = '0000000000000000000000000000000000000000' @queue = :hook attr_reader :repo, :newrev, :oldrev, :newrev_type, :oldrev_type, :refname, :change_type, :rev, :rev_type, :refname_type, :owner, :project, :user, :message - include Resque::Plugins::Status - def self.perform(*options) self.process(*options) end @@ -64,7 +65,7 @@ class GitHook end def self.process(*args) - Modules::Observers::ActivityFeed::Git.create_notifications(args.size > 1 ? GitHook.new(*args) : args.first) + create_notifications(args.size > 1 ? GitHook.new(*args) : args.first) end def find_user(user) diff --git a/app/models/group.rb b/app/models/group.rb index 0e69accaa..71ad3fa54 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,4 +1,7 @@ class Group < Avatar + include Modules::Models::ActsLikeMember + include Modules::Models::PersonalRepository + belongs_to :owner, class_name: 'User' has_many :relations, as: :actor, dependent: :destroy, dependent: :destroy @@ -15,10 +18,14 @@ class Group < Avatar validates :uname, presence: true, uniqueness: {case_sensitive: false}, format: {with: /\A[a-z0-9_]+\z/}, reserved_name: true validate { errors.add(:uname, :taken) if User.by_uname(uname).present? } - scope :opened, where('1=1') - scope :by_owner, lambda {|owner| where(owner_id: owner.id)} - scope :by_admin, lambda {|admin| joins(:actors).where(:'relations.role' => 'admin', :'relations.actor_id' => admin.id, :'relations.actor_type' => 'User')} - scope :by_admin_and_writer, lambda {|actor| joins(:actors).where(:'relations.role' => ['admin', 'writer'], :'relations.actor_id' => actor.id, :'relations.actor_type' => 'User')} + scope :opened, -> { scoped } + scope :by_owner, ->(owner) { where(owner_id: owner.id) } + scope :by_admin, ->(admin) { + joins(:actors).where('relations.role' => 'admin', 'relations.actor_id' => admin.id, 'relations.actor_type' => 'User') + } + scope :by_admin_and_writer, ->(actor) { + joins(:actors).where('relations.role' => ['admin', 'writer'], 'relations.actor_id' => actor.id, 'relations.actor_type' => 'User') + } attr_accessible :uname, :description attr_readonly :uname @@ -27,10 +34,6 @@ class Group < Avatar after_create :add_owner_to_members - include Modules::Models::ActsLikeMember - include Modules::Models::PersonalRepository - # include Modules::Models::Owner - def self.can_own_project(user) (by_owner(user) | by_admin_and_writer(user)) end diff --git a/app/models/hook.rb b/app/models/hook.rb index c83b07a9b..755e4147c 100644 --- a/app/models/hook.rb +++ b/app/models/hook.rb @@ -12,7 +12,7 @@ class Hook < ActiveRecord::Base serialize :data, Hash - scope :for_name, lambda {|name| where(name: name) if name.present? } + scope :for_name, ->(name) { where(name: name) if name.present? } def receive_issues(issue, action) pull = issue.pull_request diff --git a/app/models/issue.rb b/app/models/issue.rb index 6a35bae1f..809f5941b 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1,5 +1,5 @@ class Issue < ActiveRecord::Base - include Modules::Observers::ActivityFeed::Issue + include Feed::Issue STATUSES = ['open', 'closed'] belongs_to :project @@ -22,15 +22,17 @@ class Issue < ActiveRecord::Base attr_accessible :labelings_attributes, :title, :body, :assignee_id accepts_nested_attributes_for :labelings, allow_destroy: true - scope :opened, where(status: 'open') - scope :closed, where(status: 'closed') + scope :opened, -> { where(status: 'open') } + scope :closed, -> { where(status: 'closed') } - scope :needed_checking, where(issues: {status: ['open', 'blocked', 'ready', 'already']}) - scope :not_closed_or_merged, needed_checking - scope :closed_or_merged, where(issues: {status: ['closed', 'merged']}) + scope :needed_checking, -> { where(issues: {status: ['open', 'blocked', 'ready', 'already']}) } + scope :not_closed_or_merged, -> { needed_checking } + scope :closed_or_merged, -> { where(issues: {status: ['closed', 'merged']}) } # Using mb_chars for correct transform to lowercase ('Русский Текст'.downcase => "Русский Текст") - scope :search, lambda {|q| where("#{table_name}.title ILIKE ?", "%#{q.mb_chars.downcase}%") if q.present?} - scope :without_pull_requests, where('NOT EXISTS (select null from pull_requests as pr where pr.issue_id = issues.id)') + scope :search, ->(q) { where("#{table_name}.title ILIKE ?", "%#{q.mb_chars.downcase}%") if q.present?} } + scope :without_pull_requests, -> { + where('NOT EXISTS (select null from pull_requests as pr where pr.issue_id = issues.id)') + } def assign_uname assignee.uname if assignee diff --git a/app/models/labeling.rb b/app/models/labeling.rb index d03b0c6b3..972f44342 100644 --- a/app/models/labeling.rb +++ b/app/models/labeling.rb @@ -1,5 +1,4 @@ class Labeling < ActiveRecord::Base belongs_to :issue belongs_to :label - end diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index 0f61b3c95..694bab016 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -7,9 +7,9 @@ class MassBuild < ActiveRecord::Base serialize :extra_repositories, Array serialize :extra_build_lists, Array - scope :recent, order("#{table_name}.created_at DESC") - scope :by_platform, lambda { |platform| where(save_to_platform_id: platform.id) } - scope :outdated, where("#{table_name}.created_at < ?", Time.now + 1.day - BuildList::MAX_LIVE_TIME) + scope :recent, -> { order(created_at: :desc) } + scope :by_platform, ->(platform) { where(save_to_platform_id: platform.id) } + scope :outdated, -> { where("#{table_name}.created_at < ?", Time.now + 1.day - BuildList::MAX_LIVE_TIME) } attr_accessor :arches attr_accessible :arches, :auto_publish, :projects_list, :build_for_platform_id, diff --git a/app/models/platform.rb b/app/models/platform.rb index 9c277627a..7cf7449b0 100644 --- a/app/models/platform.rb +++ b/app/models/platform.rb @@ -4,6 +4,8 @@ class Platform < ActiveRecord::Base include Modules::Models::FileStoreClean include Modules::Models::RegenerationStatus + include Modules::Models::Owner + include EventLoggable AUTOMATIC_METADATA_REGENERATIONS = %w(day week) VISIBILITIES = %w(open hidden) @@ -34,12 +36,12 @@ class Platform < ActiveRecord::Base validates :automatic_metadata_regeneration, inclusion: {in: AUTOMATIC_METADATA_REGENERATIONS}, allow_blank: true validates :name, uniqueness: {case_sensitive: false}, presence: true, format: { with: /\A#{NAME_PATTERN}\z/ } validates :distrib_type, presence: true, inclusion: {in: APP_CONFIG['distr_types']} - validate lambda { + validate -> { if released_was && !released errors.add(:released, I18n.t('flash.platform.released_status_can_not_be_changed')) end } - validate lambda { + validate -> { if personal? && (owner_id_changed? || owner_type_changed?) errors.add :owner, I18n.t('flash.platform.owner_can_not_be_changed') end @@ -51,25 +53,23 @@ class Platform < ActiveRecord::Base after_update :freeze_platform_and_update_repos after_update :update_owner_relation - after_create lambda { symlink_directory unless hidden? } - after_destroy lambda { remove_symlink_directory unless hidden? } + after_create -> { symlink_directory unless hidden? } + after_destroy -> { remove_symlink_directory unless hidden? } - scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC") - scope :search, lambda {|q| where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%")} - scope :by_visibilities, lambda {|v| where(visibility: v)} - scope :opened, where(visibility: 'open') - scope :hidden, where(visibility: 'hidden') - scope :by_type, lambda {|type| where(platform_type: type) if type.present?} - scope :main, by_type('main') - scope :personal, by_type('personal') - scope :waiting_for_regeneration, where(status: WAITING_FOR_REGENERATION) + scope :search_order, -> { order(:name) } + scope :search, ->(q) { where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%") } + scope :by_visibilities, ->(v) { where(visibility: v) } + scope :opened, -> { where(visibility: 'open') } + scope :hidden, -> { where(visibility: 'hidden') } + scope :by_type, ->(type) { where(platform_type: type) if type.present? } + scope :main, -> { by_type('main') } + scope :personal, -> { by_type('personal') } + scope :waiting_for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) } accepts_nested_attributes_for :platform_arch_settings, allow_destroy: true attr_accessible :name, :distrib_type, :parent_platform_id, :platform_type, :owner, :visibility, :description, :released, :platform_arch_settings_attributes, :automatic_metadata_regeneration attr_readonly :name, :distrib_type, :parent_platform_id, :platform_type - include Modules::Models::Owner - state_machine :status, initial: :ready do after_transition on: :ready, do: :notify_users @@ -79,7 +79,7 @@ class Platform < ActiveRecord::Base end event :regenerate do - transition ready: :waiting_for_regeneration, if: lambda{ |p| p.main? } + transition ready: :waiting_for_regeneration, if: -> { |p| p.main? } end event :start_regeneration do diff --git a/app/models/platform_arch_setting.rb b/app/models/platform_arch_setting.rb index d59411205..6d0dbd9fc 100644 --- a/app/models/platform_arch_setting.rb +++ b/app/models/platform_arch_setting.rb @@ -10,9 +10,8 @@ class PlatformArchSetting < ActiveRecord::Base validates :arch_id, :platform_id, presence: true validates :platform_id, :uniqueness => {scope: :arch_id} - scope :by_arch, lambda {|arch| where(arch_id: arch) if arch.present?} - scope :by_default, where(default: true) + scope :by_arch, ->(arch) { where(arch_id: arch) if arch.present? } + scope :by_default, -> { where(default: true) } attr_accessible :arch_id, :platform_id, :default - end diff --git a/app/models/platform_content.rb b/app/models/platform_content.rb index e944181b5..46b26abcc 100644 --- a/app/models/platform_content.rb +++ b/app/models/platform_content.rb @@ -1,15 +1,7 @@ class PlatformContent - # ------------------ - # *** ATTRIBUTES *** - # ------------------ - attr_reader :path - # --------------- - # *** METHODS *** - # --------------- - def initialize(platform, path) @platform, @path = platform, path end @@ -61,21 +53,17 @@ class PlatformContent "#{APP_CONFIG['downloads_url']}/#{@platform.name}#{suffix}" end - # --------------------- - # *** CLASS METHODS *** - # --------------------- - def self.find_by_platform(platform, path, term) # Strip out the non-ascii character term = (term || '').strip.gsub(/[\\\/]+/, '') - .gsub(/[^\w\-\+\.]/, '_') + .gsub(/[^\w\-\+\.]/, '_') path = path.split(File::SEPARATOR).map(&:strip).select(&:present?) .map{ |p| # Strip out the non-ascii character p.gsub(/[\\\/]+/, '') - .gsub(/^[\.]+/, '') - .gsub(/[^\w\-\.]/, '_') + .gsub(/^[\.]+/, '') + .gsub(/[^\w\-\.]/, '_') } .join(File::SEPARATOR) results = Dir.glob(File.join(platform.path, path, "*#{term}*")) diff --git a/app/models/product.rb b/app/models/product.rb index 96d94dbbe..a920545df 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -1,6 +1,7 @@ class Product < ActiveRecord::Base include Modules::Models::TimeLiving include Modules::Models::Autostart + include EventLoggable belongs_to :platform belongs_to :project @@ -10,7 +11,7 @@ class Product < ActiveRecord::Base validates :project_id, presence: true validates :main_script, :params, length: { maximum: 255 } - scope :recent, order("#{table_name}.name ASC") + scope :recent, -> { order(:name) } attr_accessible :name, :description, diff --git a/app/models/product_build_list.rb b/app/models/product_build_list.rb index 4ff19d486..67313c4e2 100644 --- a/app/models/product_build_list.rb +++ b/app/models/product_build_list.rb @@ -4,6 +4,8 @@ class ProductBuildList < ActiveRecord::Base include Modules::Models::FileStoreClean include Modules::Models::UrlHelper include AbfWorker::ModelHelper + include EventLoggable + delegate :url_helpers, to: 'Rails.application.routes' LIVE_TIME = 2.week # for autostart @@ -38,9 +40,9 @@ class ProductBuildList < ActiveRecord::Base belongs_to :user # see: Issue #6 - before_validation lambda { self.arch_id = Arch.find_by_name('x86_64').id }, on: :create + before_validation -> { self.arch_id = Arch.find_by_name('x86_64').id }, on: :create # field "not_delete" can be changed only if build has been completed - before_validation lambda { self.not_delete = false unless build_completed?; true } + before_validation -> { self.not_delete = false unless build_completed?; true } validates :product_id, :status, :project_id, @@ -64,13 +66,16 @@ class ProductBuildList < ActiveRecord::Base serialize :results, Array - scope :default_order, order("#{table_name}.updated_at DESC") - scope :for_status, lambda {|status| where(status: status) } - scope :for_user, lambda { |user| where(user_id: user.id) } - scope :scoped_to_product_name, lambda {|product_name| joins(:product).where('products.name LIKE ?', "%#{product_name}%")} - scope :recent, order("#{table_name}.updated_at DESC") - scope :outdated, where(not_delete: false). - where("(#{table_name}.created_at < ? AND #{table_name}.autostarted is TRUE) OR #{table_name}.created_at < ?", Time.now - LIVE_TIME, Time.now - MAX_LIVE_TIME) + scope :default_order, -> { order(updated_at: desc) } + scope :for_status, ->(status) { where(status: status) } + scope :for_user, ->(user) { where(user_id: user.id) } + scope :scoped_to_product_name, ->(product_name) { joins(:product).where('products.name LIKE ?', "%#{product_name}%") } + scope :recent, -> { order(updated_at: desc) } + scope :outdated, -> { + where(not_delete: false). + where("(#{table_name}.created_at < ? AND #{table_name}.autostarted is TRUE) OR #{table_name}.created_at < ?", + Time.now - LIVE_TIME, Time.now - MAX_LIVE_TIME) + } after_create :add_job_to_abf_worker_queue before_destroy :can_destroy? diff --git a/app/models/project.rb b/app/models/project.rb index 9fc0eacce..910c5cba8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,12 +1,17 @@ class Project < ActiveRecord::Base include Modules::Models::Autostart + include Modules::Models::Owner + include Modules::Models::Git + include Modules::Models::Wiki + include Modules::Models::UrlHelper + include EventLoggable VISIBILITIES = ['open', 'hidden'] MAX_OWN_PROJECTS = 32000 NAME_REGEXP = /[\w\-\+\.]+/ belongs_to :owner, polymorphic: true, counter_cache: :own_projects_count - belongs_to :maintainer, class_name: "User" + belongs_to :maintainer, class_name: 'User' has_many :issues, dependent: :destroy has_many :pull_requests, dependent: :destroy, foreign_key: 'to_project_id' @@ -25,7 +30,7 @@ class Project < ActiveRecord::Base has_many :collaborators, through: :relations, source: :actor, source_type: 'User' has_many :groups, through: :relations, source: :actor, source_type: 'Group' - has_many :packages, class_name: "BuildList::Package", dependent: :destroy + has_many :packages, class_name: 'BuildList::Package', dependent: :destroy has_and_belongs_to_many :advisories # should be without dependent: :destroy validates :name, uniqueness: {scope: [:owner_id, :owner_type], case_sensitive: false}, @@ -53,49 +58,43 @@ class Project < ActiveRecord::Base :autostart_status attr_readonly :owner_id, :owner_type - scope :recent, order("lower(#{table_name}.name) ASC") - scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC") - scope :search, lambda {|q| + scope :recent, -> { order(:name) } + scope :search_order, -> { order('CHAR_LENGTH(projects.name) ASC') } + scope :search, ->(q) { q = q.to_s.strip by_name("%#{q}%").search_order if q.present? } - scope :by_name, lambda {|name| where("#{table_name}.name ILIKE ?", name) if name.present?} - scope :by_owner_and_name, lambda { |*params| + scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? } + scope :by_owner_and_name, ->(*params) { term = params.map(&:strip).join('/').downcase - where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present? + where('lower(concat(owner_uname, '/', name)) ILIKE ?', "%#{term}%") if term.present? } - scope :by_visibilities, lambda {|v| where(visibility: v)} - scope :opened, where(visibility: 'open') - scope :package, where(is_package: true) - scope :addable_to_repository, lambda { |repository_id| where %Q( - projects.id NOT IN ( - SELECT - ptr.project_id - FROM - project_to_repositories AS ptr - WHERE (ptr.repository_id = #{ repository_id }) - ) - ) } - scope :by_owners, lambda { |group_owner_ids, user_owner_ids| - where("(#{table_name}.owner_id in (?) AND #{table_name}.owner_type = 'Group') OR (#{table_name}.owner_id in (?) AND #{table_name}.owner_type = 'User')", group_owner_ids, user_owner_ids) + scope :by_visibilities, ->(v) { where(visibility: v) } + scope :opened, -> { where(visibility: 'open') } + scope :package, -> { where(is_package: true) } + scope :addable_to_repository, ->(repository_id) { + where('projects.id NOT IN ( + SELECT ptr.project_id + FROM project_to_repositories AS ptr + WHERE ptr.repository_id = ?)', repository_id) + } + scope :by_owners, ->(group_owner_ids, user_owner_ids) { + where("projects.owner_id in (?) AND projects.owner_type = 'Group') OR + (projects.owner_id in (?) AND projects.owner_type = 'User')", group_owner_ids, user_owner_ids) } before_validation :truncate_name, on: :create - before_save lambda { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? } + before_save -> { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? } before_create :set_maintainer after_save :attach_to_personal_repository after_update :set_new_git_head - after_update lambda { update_path_to_project(name_was) }, if: :name_changed? + after_update -> { update_path_to_project(name_was) }, if: :name_changed? + before_save :ensure_authentication_token has_ancestry orphan_strategy: :rootify #:adopt not available yet attr_accessor :url, :srpms_list, :mass_import, :add_to_repository_id - include Modules::Models::Owner - include Modules::Models::Git - include Modules::Models::Wiki - include Modules::Models::UrlHelper - class << self def find_by_owner_and_name(owner_name, project_name) where(owner_uname: owner_name, name: project_name).first || diff --git a/app/models/project_import.rb b/app/models/project_import.rb index 0b93b4195..a34949833 100644 --- a/app/models/project_import.rb +++ b/app/models/project_import.rb @@ -5,7 +5,7 @@ class ProjectImport < ActiveRecord::Base validates :name, uniqueness: {scope: :platform_id, case_sensitive: false} validates :name, :platform_id, :version, presence: true - scope :by_name, lambda {|name| where("#{table_name}.name ILIKE ?", name)} + scope :by_name, ->(name) { where("#{table_name}.name ILIKE ?", name) } - after_initialize lambda {|r| r.file_mtime ||= Time.current - 10.years } # default + after_initialize -> {|r| r.file_mtime ||= Time.current - 10.years } # default end diff --git a/app/models/project_tag.rb b/app/models/project_tag.rb index e6c700814..267bf39f2 100644 --- a/app/models/project_tag.rb +++ b/app/models/project_tag.rb @@ -11,14 +11,9 @@ class ProjectTag < ActiveRecord::Base validates :project_id, :commit_id, :sha1, :tag_name, :format_id, presence: true validates :project_id, uniqueness: {scope: [:tag_name, :format_id]} - attr_accessible :project_id, - :commit_id, - :sha1, - :tag_name, - :format_id + attr_accessible :project_id, :commit_id, :sha1, :tag_name, :format_id def sha1_of_file_store_files [sha1] end - end diff --git a/app/models/project_to_repository.rb b/app/models/project_to_repository.rb index d2e0194eb..34e7ef728 100644 --- a/app/models/project_to_repository.rb +++ b/app/models/project_to_repository.rb @@ -6,13 +6,14 @@ class ProjectToRepository < ActiveRecord::Base delegate :path, to: :project - scope :autostart_enabled, lambda { where("autostart_options -> 'enabled' = 'true'") } + scope :autostart_enabled, -> { where("autostart_options -> 'enabled' = 'true'") } - after_destroy lambda { project.destroy_project_from_repository(repository) }, unless: lambda {Thread.current[:skip]} + after_destroy -> { project.destroy_project_from_repository(repository) }, unless: -> { Thread.current[:skip] } validate :one_project_in_platform_repositories, on: :create serialize :autostart_options, ActiveRecord::Coders::Hstore + AUTOSTART_OPTIONS.each do |field| store_accessor :autostart_options, field end @@ -28,7 +29,8 @@ class ProjectToRepository < ActiveRecord::Base protected def one_project_in_platform_repositories - errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project')) if Project.joins(repositories: :platform). - where('platforms.id = ?', repository.platform_id).by_name(project.name).exists? + if Project.joins(repositories: :platform).where('platforms.id = ?', repository.platform_id).by_name(project.name).exists? + errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project')) + end end end diff --git a/app/models/pull_request.rb b/app/models/pull_request.rb index 542e2e6f2..29250a897 100644 --- a/app/models/pull_request.rb +++ b/app/models/pull_request.rb @@ -7,7 +7,7 @@ class PullRequest < ActiveRecord::Base :created_at, :updated_at, :comments, :status=, to: :issue, allow_nil: true validates :from_project, :to_project, presence: true - validate :uniq_merge, if: Proc.new { |pull| pull.to_project.present? } + validate :uniq_merge, if: -> { |pull| pull.to_project.present? } validates_each :from_ref, :to_ref do |record, attr, value| check_ref record, attr, value end @@ -19,9 +19,9 @@ class PullRequest < ActiveRecord::Base accepts_nested_attributes_for :issue attr_accessible :issue_attributes, :to_ref, :from_ref - scope :needed_checking, includes(:issue).where(issues: {status: ['open', 'blocked', 'ready']}) - scope :not_closed_or_merged, needed_checking - scope :closed_or_merged, where(issues: {status: ['closed', 'merged']}) + scope :needed_checking, -> { includes(:issue).where(issues: {status: ['open', 'blocked', 'ready']}) } + scope :not_closed_or_merged, -> { needed_checking } + scope :closed_or_merged, -> { where(issues: {status: ['closed', 'merged']}) } state_machine :status, initial: :open do event :ready do diff --git a/app/models/register_request.rb b/app/models/register_request.rb index 42cff47cd..20e2d04b1 100644 --- a/app/models/register_request.rb +++ b/app/models/register_request.rb @@ -1,12 +1,13 @@ class RegisterRequest < ActiveRecord::Base - default_scope order('created_at ASC') + default_scope { order(:created_at) } - scope :rejected, where(rejected: true) - scope :approved, where(approved: true) - scope :unprocessed, where(approved: false, rejected: false) + scope :rejected, -> { where(rejected: true) } + scope :approved, -> { where(approved: true) } + scope :unprocessed, -> { where(approved: false, rejected: false) } - validates :email, presence: true, uniqueness: {case_sensitive: false}, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } + validates :email, presence: true, uniqueness: {case_sensitive: false}, + format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i } # before_create :generate_token before_update :invite_approve_notification diff --git a/app/models/relation.rb b/app/models/relation.rb index e261a1283..45317bfe8 100644 --- a/app/models/relation.rb +++ b/app/models/relation.rb @@ -1,17 +1,20 @@ class Relation < ActiveRecord::Base + ROLES = %w[reader writer admin] + belongs_to :target, polymorphic: true belongs_to :actor, polymorphic: true, touch: true - ROLES = %w[reader writer admin] validates :role, inclusion: {in: ROLES} # validate { errors.add(:actor, :taken) if Relation.where(actor_type: self.actor_type, actor_id: self.actor_id).present? } before_validation :add_default_role - scope :by_user_through_groups, lambda {|u| where("actor_type = 'User' AND actor_id = ? OR actor_type = 'Group' AND actor_id IN (?)", u.id, u.group_ids)} - scope :by_actor, lambda {|obj| where(actor_id: obj.id, actor_type: obj.class.to_s)} - scope :by_target, lambda {|tar| where(target_id: tar.id, target_type: tar.class.to_s)} - scope :by_role, lambda {|role| where(role: role)} + scope :by_user_through_groups, ->(u) { + where("actor_type = 'User' AND actor_id = ? OR actor_type = 'Group' AND actor_id IN (?)", u.id, u.group_ids) + } + scope :by_actor, ->(obj) { where(actor_id: obj.id, actor_type: obj.class.to_s) } + scope :by_target, ->(tar) { where(target_id: tar.id, target_type: tar.class.to_s) } + scope :by_role, ->(role) { where(role: role) } def self.create_with_role(actor, target, role) r = self.new diff --git a/app/models/repository.rb b/app/models/repository.rb index 26ef77c96..70c628299 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -2,6 +2,8 @@ class Repository < ActiveRecord::Base extend FriendlyId friendly_id :name + include EventLoggable + LOCK_FILE_NAMES = {sync: '.sync.lock', repo: '.repo.lock'} SORT = {'base' => 1, 'main' => 2, 'contrib' => 3, 'non-free' => 4, 'restricted' => 5} @@ -19,10 +21,11 @@ class Repository < ActiveRecord::Base has_many :build_lists, foreign_key: :save_to_repository_id, dependent: :destroy validates :description, presence: true - validates :name, uniqueness: {scope: :platform_id, case_sensitive: false}, presence: true, format: {with: /\A[a-z0-9_\-]+\z/} + validates :name, uniqueness: {scope: :platform_id, case_sensitive: false}, presence: true, + format: {with: /\A[a-z0-9_\-]+\z/} - scope :recent, order("#{table_name}.name ASC") - scope :main, lambda { where(name: %w(main base)) } + scope :recent, -> { order(:name) } + scope :main, -> { where(name: %w(main base)) } before_destroy :detele_directory diff --git a/app/models/repository_status.rb b/app/models/repository_status.rb index eb59ada70..8b1359fc6 100644 --- a/app/models/repository_status.rb +++ b/app/models/repository_status.rb @@ -33,10 +33,10 @@ class RepositoryStatus < ActiveRecord::Base attr_accessible :platform_id, :repository_id - scope :platform_ready, where(platforms: {status: READY}).joins(:platform) - scope :for_regeneration, where(status: WAITING_FOR_REGENERATION) - scope :for_resign, where(status: [WAITING_FOR_RESIGN, WAITING_FOR_RESIGN_AND_REGENERATION]) - scope :not_ready, where('repository_statuses.status != ?', READY) + scope :platform_ready, -> { where(platforms: {status: READY}).joins(:platform) } + scope :for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) } + scope :for_resign, -> { where(status: [WAITING_FOR_RESIGN, WAITING_FOR_RESIGN_AND_REGENERATION]) } + scope :not_ready, -> { where('repository_statuses.status != ?', READY) } state_machine :status, initial: :ready do event :ready do @@ -80,5 +80,4 @@ class RepositoryStatus < ActiveRecord::Base state name, value: code end end - -end \ No newline at end of file +end diff --git a/app/models/rpm_build_node.rb b/app/models/rpm_build_node.rb index c9a95f6bb..493bd348b 100644 --- a/app/models/rpm_build_node.rb +++ b/app/models/rpm_build_node.rb @@ -29,5 +29,4 @@ class RpmBuildNode < Ohm::Model end { systems: systems, others: others, busy: busy } end - -end \ No newline at end of file +end diff --git a/app/models/ssh_key.rb b/app/models/ssh_key.rb index 2921d28c5..e5091da1c 100644 --- a/app/models/ssh_key.rb +++ b/app/models/ssh_key.rb @@ -7,7 +7,7 @@ class SshKey < ActiveRecord::Base belongs_to :user attr_accessible :key, :name - before_validation lambda { self.key = key.strip if key.present? } + before_validation -> { self.key = key.strip if key.present? } before_validation :set_fingerprint validates :name, length: {maximum: 255} diff --git a/app/models/token.rb b/app/models/token.rb index ea867af6a..5525bd774 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -4,10 +4,10 @@ class Token < ActiveRecord::Base belongs_to :updater, class_name: 'User' validates :creator_id, :subject_id, :subject_type, presence: true - validates :authentication_token, presence: true, uniqueness: {case_sensitive: true} + validates :authentication_token, presence: true, uniqueness: { case_sensitive: true } - default_scope order("#{table_name}.created_at desc") - scope :by_active, where(status: 'active') + default_scope { order(created_at: :desc) } + scope :by_active, -> { where(status: 'active') } before_validation :generate_token, on: :create diff --git a/app/models/user.rb b/app/models/user.rb index 969fc622a..321362706 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,11 +1,16 @@ class User < Avatar + include Modules::Models::PersonalRepository + include Modules::Models::ActsLikeMember + include Feed::User + include EventLoggable + ROLES = ['', 'admin', 'banned', 'tester'] EXTENDED_ROLES = ROLES | ['system'] LANGUAGES_FOR_SELECT = [['Russian', 'ru'], ['English', 'en']] LANGUAGES = LANGUAGES_FOR_SELECT.map(&:last) - devise :database_authenticatable, :registerable, :omniauthable, :token_authenticatable,# :encryptable, :timeoutable - :recoverable, :rememberable, :validatable, :lockable, :confirmable#, :reconfirmable, :trackable + devise :database_authenticatable, :registerable, :omniauthable, + :recoverable, :rememberable, :validatable, :lockable, :confirmable devise :omniauthable, omniauth_providers: [:facebook, :google_oauth2, :github] has_one :notifier, class_name: 'SettingsNotifier', dependent: :destroy #:notifier @@ -44,23 +49,19 @@ class User < Avatar attr_readonly :uname attr_accessor :login - scope :opened, where('users.role != \'system\' OR users.role IS NULL') - scope :real, where(role: ['', nil]) + scope :opened, -> { where('users.role != \'system\' OR users.role IS NULL') } + scope :real, -> { where(role: ['', nil]) } EXTENDED_ROLES.select {|type| type.present?}.each do |type| - scope type.to_sym, where(role: type) + scope type.to_sym, -> { where(role: type) } end - scope :member_of_project, lambda {|item| - where "#{table_name}.id IN (?)", item.members.map(&:id).uniq + scope :member_of_project, ->(item) { + where 'users.id IN (?)', item.members.map(&:id).uniq } - after_create lambda { self.create_notifier unless self.system? } + after_create -> { self.create_notifier unless self.system? } before_create :ensure_authentication_token - include Modules::Models::PersonalRepository - include Modules::Models::ActsLikeMember - include Modules::Observers::ActivityFeed::User - def admin? role == 'admin' end @@ -157,6 +158,12 @@ class User < Avatar end end + def ensure_authentication_token + if authentication_token.blank? + self.authentication_token = generate_authentication_token + end + end + protected def target_roles target @@ -173,4 +180,11 @@ class User < Avatar roles.map(&:role).uniq end + def generate_authentication_token + loop do + token = Devise.friendly_token + break token unless User.where(authentication_token: token).first + end + end + end diff --git a/config/application.rb b/config/application.rb index 46b6c2547..f012ad1b4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -3,12 +3,17 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' require './lib/api_defender' +# Prevent deprecation warning +I18n.config.enforce_available_locales = true + # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. Bundler.require(:default, Rails.env) module Rosa class Application < Rails::Application + config.i18n.enforce_available_locales = true + # Rate limit config.middleware.insert_after Rack::Lock, ApiDefender @@ -27,9 +32,6 @@ module Rosa # :all can be used as a placeholder for all plugins not explicitly named. # config.plugins = [ :exception_notification, :ssl_requirement, :all ] - # Activate observers that should always be running. - 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. # config.time_zone = 'Central Time (US & Canada)' @@ -50,7 +52,5 @@ module Rosa # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' - - I18n.enforce_available_locales = false end end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 1517e6c7d..ea5b6c38a 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -204,4 +204,6 @@ Devise.setup do |config| # manager.intercept_401 = false # manager.default_strategies(:scope => :user).unshift :some_external_strategy # end + + config.secret_key = '4a8a8e28e63a3d1f4ec3be11df2f6d40e7baa99bbd6da601622150c99cb9d77f98c1baed3e5871c646b12738d07e6e76d5bb537ef407a02e4ca6de579c0e8a57' end diff --git a/config/routes.rb b/config/routes.rb index 6b4369d0d..a7ee50163 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -132,7 +132,9 @@ Rosa::Application.routes.draw do authenticated do root to: 'home#activity' end - root to: 'home#root' + unauthenticated do + root to: 'home#root', as: :authenticated_root + end else root to: 'home#activity' end @@ -179,7 +181,7 @@ Rosa::Application.routes.draw do end resources :contents, only: [:index] - match '/contents/*path' => 'contents#index', format: false + get '/contents/*path' => 'contents#index', format: false resources :mass_builds, only: [:create, :new, :index] do member do @@ -363,10 +365,10 @@ Rosa::Application.routes.draw do get '/tags' => "git/trees#tags", as: :tags # Branches get '/branches' => "git/trees#branches", as: :branches - get '/branches/:treeish' => "git/trees#branches", as: :branch - delete '/branches/:treeish' => "git/trees#destroy", as: :branch - put '/branches/:treeish' => "git/trees#restore_branch", as: :branch - post '/branches' => "git/trees#create", as: :branches + get '/branches/:treeish' => "git/trees#branches", as: :treeish_branch + delete '/branches/:treeish' => "git/trees#destroy", as: :destroy_branch + put '/branches/:treeish' => "git/trees#restore_branch", as: :restore_branch + post '/branches' => "git/trees#create", as: :create_branch # Commits get '/commits/:treeish(/*path)' => "git/commits#index", as: :commits, format: false get '/commit/:id(.:format)' => "git/commits#show", as: :commit @@ -402,12 +404,12 @@ Rosa::Application.routes.draw do get '/' => 'users/profile#show', as: :user end constraints Rosa::Constraints::Owner.new(Group, true) do - get '/' => 'groups/profile#show', as: :group + #get '/' => 'groups/profile#show', as: :group end end # As of Rails 3.0.1, using rescue_from in your ApplicationController to # recover from a routing error is broken! # see: https://rails.lighthouseapp.com/projects/8994/tickets/4444-can-no-longer-rescue_from-actioncontrollerroutingerror - match '*a', to: 'application#render_404' + get '*a', to: 'application#render_404' end diff --git a/lib/modules/models/acts_like_member.rb b/lib/modules/models/acts_like_member.rb index 653431588..372f4eed4 100644 --- a/lib/modules/models/acts_like_member.rb +++ b/lib/modules/models/acts_like_member.rb @@ -4,7 +4,7 @@ module Modules extend ActiveSupport::Concern included do - scope :not_member_of, lambda {|item| + scope :not_member_of, -> {|item| where(" #{table_name}.id NOT IN ( SELECT relations.actor_id @@ -17,10 +17,10 @@ module Modules ) ") } - scope :search_order, order("CHAR_LENGTH(uname) ASC") - scope :without, lambda {|a| where("#{table_name}.id NOT IN (?)", a)} - scope :by_uname, lambda {|n| where("#{table_name}.uname ILIKE ?", n)} - scope :search, lambda {|q| by_uname("%#{q.to_s.strip}%")} + scope :search_order, { order('CHAR_LENGTH(#{table_name}.uname) ASC') } + scope :without, ->(a) { where("#{table_name}.id NOT IN (?)", a) } + scope :by_uname, ->(n) { where("#{table_name}.uname ILIKE ?", n) } + scope :search, ->(q) { by_uname("%#{q.to_s.strip}%") } end def to_param diff --git a/lib/modules/models/commit_and_version.rb b/lib/modules/models/commit_and_version.rb index d34863e11..fac090b08 100644 --- a/lib/modules/models/commit_and_version.rb +++ b/lib/modules/models/commit_and_version.rb @@ -5,7 +5,7 @@ module Modules included do - validate lambda { + validate -> { if project && (commit_hash.blank? || project.repo.commit(commit_hash).blank?) errors.add :commit_hash, I18n.t('flash.build_list.wrong_commit_hash', commit_hash: commit_hash) end diff --git a/lib/modules/models/git.rb b/lib/modules/models/git.rb index 026880e96..a1d56afa3 100644 --- a/lib/modules/models/git.rb +++ b/lib/modules/models/git.rb @@ -16,7 +16,7 @@ module Modules after_commit(on: :create) {|p| p.fork_git_repo unless p.is_root?} # later with resque after_commit(on: :create) {|p| p.import_attached_srpm if p.srpm?} # later with resque # should be after create_git_repo after_destroy :destroy_git_repo - # after_rollback lambda { destroy_git_repo rescue true if new_record? } + # after_rollback -> { destroy_git_repo rescue true if new_record? } later :import_attached_srpm, queue: :fork_import later :fork_git_repo, queue: :fork_import diff --git a/lib/modules/models/owner.rb b/lib/modules/models/owner.rb index 953fa39d6..d9e8a6423 100644 --- a/lib/modules/models/owner.rb +++ b/lib/modules/models/owner.rb @@ -5,7 +5,7 @@ module Modules included do validates :owner, presence: true - after_create lambda { relations.create actor_id: owner.id, actor_type: owner.class.to_s, role: 'admin' } + after_create -> { relations.create actor_id: owner.id, actor_type: owner.class.to_s, role: 'admin' } end end diff --git a/lib/modules/models/time_living.rb b/lib/modules/models/time_living.rb index d0ac003a4..fde28e5e8 100644 --- a/lib/modules/models/time_living.rb +++ b/lib/modules/models/time_living.rb @@ -9,22 +9,19 @@ module Modules only_integer: true }, presence: true - validate lambda { + validate -> { # MIN_TIME_LIVING <= time_living <= MAX_TIME_LIVING or # 2 min <= time_living <= 12 hours # time_living in seconds min = self.class.const_defined?(:MIN_TIME_LIVING) ? self.class::MIN_TIME_LIVING : 120 max = self.class.const_defined?(:MAX_TIME_LIVING) ? self.class::MAX_TIME_LIVING : 43200 if min > time_living.to_i || time_living.to_i > max - errors.add :time_living, I18n.t('flash.time_living.numericality_error', - min: (min / 60), - max: (max / 60) - ) + errors.add :time_living, + I18n.t('flash.time_living.numericality_error', min: (min / 60), max: (max / 60)) end } before_validation :convert_time_living - attr_accessible :time_living end