From ecd4498484f44a62d604fddba2cf668b89a7ae25 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Tue, 19 Jun 2012 02:49:17 +0400 Subject: [PATCH 01/48] [issue #428] Changes in advisories. * Added Many2Many relation between advisories and projects. * Added autocompletion to build list's advisory * Bootstrap's JS moved to vendor/ --- app/assets/javascripts/application.js | 2 +- .../views/build_list_advisories_view.js | 18 +- app/assets/javascripts/lib/lib.js | 3 - app/assets/stylesheets/design/custom.scss | 14 + app/controllers/advisories_controller.rb | 19 +- .../projects/build_lists_controller.rb | 4 +- app/models/advisory.rb | 2 +- app/models/project.rb | 2 +- app/views/advisories/_packages_info.html.haml | 20 + app/views/advisories/show.html.haml | 7 +- app/views/projects/build_lists/show.html.haml | 5 +- ...7153342_add_many_projects_to_advisories.rb | 40 + db/schema.rb | 76 +- vendor/assets/images/chosen/chosen-sprite.png | Bin 0 -> 559 bytes .../assets/javascripts}/bootstrap-popover.js | 0 .../assets/javascripts}/bootstrap-tooltip.js | 0 vendor/assets/javascripts/chosen.jquery.js | 1003 +++++++++++++++++ vendor/assets/javascripts/vendor.js | 3 + vendor/assets/stylesheets/chosen.scss | 396 +++++++ vendor/assets/stylesheets/vendor.scss | 3 +- 20 files changed, 1568 insertions(+), 49 deletions(-) delete mode 100644 app/assets/javascripts/lib/lib.js create mode 100644 app/views/advisories/_packages_info.html.haml create mode 100644 db/migrate/20120607153342_add_many_projects_to_advisories.rb create mode 100755 vendor/assets/images/chosen/chosen-sprite.png rename {app/assets/javascripts/lib => vendor/assets/javascripts}/bootstrap-popover.js (100%) rename {app/assets/javascripts/lib => vendor/assets/javascripts}/bootstrap-tooltip.js (100%) create mode 100755 vendor/assets/javascripts/chosen.jquery.js create mode 100755 vendor/assets/stylesheets/chosen.scss diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 9d8340566..e89ed7d79 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -4,9 +4,9 @@ //= require autocomplete-rails //= require vendor //= require jquery.dataTables_ext -//= require lib/lib //= require_tree ./design //= require_tree ./extra +//= require_tree ./lib //= require underscore //= require backbone diff --git a/app/assets/javascripts/backbone/views/build_list_advisories_view.js b/app/assets/javascripts/backbone/views/build_list_advisories_view.js index 7a47f0797..13cd34d56 100644 --- a/app/assets/javascripts/backbone/views/build_list_advisories_view.js +++ b/app/assets/javascripts/backbone/views/build_list_advisories_view.js @@ -2,28 +2,32 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ initialize: function() { _.bindAll(this, 'popoverTitle', 'popoverDesc', 'showAdvisory', 'changeAdvisoryList', 'showPreview', 'showForm', 'hideAll'); + $('.chzn-select').chosen(); this.$el = $('#advisory_block'); this._$form = this.$('#new_advisory_form'); this._$preview = this.$('#advisory_preview'); this._$type_select = $('#build_list_update_type'); this._$selector = this.$('#attach_advisory'); + this._header_text = this._$preview.children('h3').html(); this._$selector.on('change', this.showAdvisory); this._$type_select.on('change', this.changeAdvisoryList); }, changeAdvisoryList: function() { - this._$selector.children('.popoverable').hide(); - this._$selector.children('.popoverable.' + this._$type_select.val()).show(); - this._$selector.val('no').trigger('change'); + this.$('.popoverable').hide(); + this.$('.popoverable.' + this._$type_select.val()).show(); + this._$selector.val('no').trigger("liszd:updated").trigger('change'); }, popoverTitle: function(el) { - return el.val(); + console.log(el); + console.log(el.html()); + return el.html(); }, popoverDesc: function(el) { - return this.collection.get(el.val()).get('popover_desc'); + return this.collection.get(el.html()).get('popover_desc'); }, showAdvisory: function(el) { @@ -46,7 +50,7 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ } var adv = this.collection.get(id); var prev = this._$preview; - prev.children('h3').html(prev.children('h3').html() + ' ' + adv.get('advisory_id')); + prev.children('h3').html(this._header_text + ' ' + adv.get('advisory_id')); prev.children('.descr').html(adv.get('description')); prev.children('.refs').html(adv.get('references')); if (!this._$preview.is(':visible')) { @@ -76,7 +80,7 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ var title = this.popoverTitle; var description = this.popoverDesc; this.changeAdvisoryList(); - this.$('#attach_advisory > .popoverable').popover({ + this.$('.popoverable').popover({ title: function() { return title($(this)); }, content: function() { return description($(this)); } }); diff --git a/app/assets/javascripts/lib/lib.js b/app/assets/javascripts/lib/lib.js deleted file mode 100644 index 2d346835e..000000000 --- a/app/assets/javascripts/lib/lib.js +++ /dev/null @@ -1,3 +0,0 @@ -//= require ./jquery.placeholder -//= require ./bootstrap-tooltip -//= require ./bootstrap-popover diff --git a/app/assets/stylesheets/design/custom.scss b/app/assets/stylesheets/design/custom.scss index 4766fb536..4475219a4 100644 --- a/app/assets/stylesheets/design/custom.scss +++ b/app/assets/stylesheets/design/custom.scss @@ -1080,3 +1080,17 @@ form.mass_build section.left { form.mass_build section.right { margin-right: 50px; } + +.chzn-select { + width: 350px; +} + +.packages_info_container ul { + list-style-type: none; + padding-left: 25px; + margin: 5px 0; +} + +.packages_info_container ul.platforms { + padding: 0; +} diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 979712412..5510e1526 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -1,20 +1,23 @@ # -*- encoding : utf-8 -*- +require 'pp' class AdvisoriesController < ApplicationController before_filter :authenticate_user! - before_filter :find_advisory, :only => [:show] skip_before_filter :authenticate_user! if APP_CONFIG['anonymous_access'] - load_and_authorize_resource + load_resource :find_by => :advisory_id + authorize_resource def index - @advisories = @advisories.paginate(:page => params[:page]) + @advisories = @advisories.scoped(:include => :projects).paginate(:page => params[:page]) end def show + @packages_info = Hash.new { |h, k| h[k] = {} } + @advisory.build_lists.find_in_batches(:include => [:save_to_platform, :packages, :project]) do |batch| + batch.each do |build_list| + h = { build_list.project => build_list.packages } + @packages_info[build_list.save_to_platform].merge!(h) { |pr, old, new| (old + new).compact!.uniq! } + end + end end - protected - - def find_advisory - @advisory = Advisory.where(:advisory_id => params[:id]).limit(1).first if params[:id].present? - end end diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index 2f3629532..59059cef7 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -70,7 +70,7 @@ class Projects::BuildListsController < Projects::BaseController def show @item_groups = @build_list.items.group_by_level - @advisories = @build_list.project.advisories + @advisories = Advisories.all end def update @@ -177,7 +177,7 @@ class Projects::BuildListsController < Projects::BaseController if params[:attach_advisory].present? and params[:attach_advisory] != 'no' and !@build_list.advisory if params[:attach_advisory] == 'new' # create new advisory - if !@build_list.build_advisory(params[:build_list][:advisory]) do |a| + unless @build_list.build_advisory(params[:build_list][:advisory]) do |a| a.update_type = @build_list.update_type a.project = @build_list.project a.platforms << @build_list.save_to_platform unless a.platforms.include? @build_list.save_to_platform diff --git a/app/models/advisory.rb b/app/models/advisory.rb index c643f333b..e41b1c665 100644 --- a/app/models/advisory.rb +++ b/app/models/advisory.rb @@ -1,7 +1,7 @@ class Advisory < ActiveRecord::Base has_and_belongs_to_many :platforms + has_and_belongs_to_many :projects has_many :build_lists - belongs_to :project validates :description, :update_type, :presence => true diff --git a/app/models/project.rb b/app/models/project.rb index 61a0f10a9..2f656be2c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -18,8 +18,8 @@ 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 :advisories # should be without :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}, :presence => true, :format => {:with => /^#{NAME_REGEXP}$/, :message => I18n.t("activerecord.errors.project.uname")} validates :owner, :presence => true diff --git a/app/views/advisories/_packages_info.html.haml b/app/views/advisories/_packages_info.html.haml new file mode 100644 index 000000000..245ba3f13 --- /dev/null +++ b/app/views/advisories/_packages_info.html.haml @@ -0,0 +1,20 @@ +.packages_info_container + %h3= t('layout.advisories.affected_versions') + %ul.platforms + - @packages_info.each_pair do |platform, projects| + %li + %p= raw "#{t('activerecord.models.platform')} #{ link_to platform.name, platform_path(platform) }" + %ul + - projects.each_pair do |project, packages| + %li + %p= raw "#{ t('activerecord.models.project') } #{ link_to project.name, project_path(project) }" + %ul + %li + %p= "SRPM:" + %ul + %li= project.srpm_file_name + %li + %p= "RPM:" + %ul + - packages.each do |package| + %li= package.fullname diff --git a/app/views/advisories/show.html.haml b/app/views/advisories/show.html.haml index 483ba81a9..ba1886964 100644 --- a/app/views/advisories/show.html.haml +++ b/app/views/advisories/show.html.haml @@ -4,7 +4,10 @@ %h3= "#{t("activerecord.models.advisory")} #{@advisory.advisory_id}".html_safe .leftlist= "#{t("layout.advisories.project_name")}:".html_safe -.rightlist= link_to @advisory.project.name, project_path(@advisory.project) +.rightlist + - @advisory.projects.each do |project| + = link_to project.name, project_path(project) + %br .both .leftlist= "#{t("activerecord.attributes.advisory.created_at")}:".html_safe @@ -33,5 +36,7 @@ %br .both += render :partial => 'packages_info' + :javascript $('article .all').addClass('bigpadding'); diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index 4e4f68ad7..afdc6524f 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -32,7 +32,7 @@ .leftlist= t("activerecord.attributes.build_list.update_type") .rightlist - if @build_list.can_publish? and can?(:publish, @build_list) - = f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type) + = f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type), {}, :class => 'chzn-select' - else = @build_list.update_type .both @@ -74,7 +74,8 @@ - if @build_list.can_publish? and @build_list.save_to_platform.released and @build_list.advisory.nil? #advisory_block .leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory") - .rightlist= select_tag :attach_advisory, advisories_select_options(@advisories) + .rightlist + = select_tag :attach_advisory, advisories_select_options(@advisories), :class => 'chzn-select' .both #new_advisory_form diff --git a/db/migrate/20120607153342_add_many_projects_to_advisories.rb b/db/migrate/20120607153342_add_many_projects_to_advisories.rb new file mode 100644 index 000000000..80ed9ad62 --- /dev/null +++ b/db/migrate/20120607153342_add_many_projects_to_advisories.rb @@ -0,0 +1,40 @@ +class AddManyProjectsToAdvisories < ActiveRecord::Migration + def up + create_table :advisories_projects, :id => false do |t| + t.integer :advisory_id + t.integer :project_id + end + add_index :advisories_projects, :advisory_id + add_index :advisories_projects, :project_id + add_index :advisories_projects, [:advisory_id, :project_id], :name => :advisory_project_index, :unique => true + + Advisory.find_in_batches do |b| + b.each do |advisory| + advisory.projects << Project.find(advisory.project_id) + advisory.save + end + end + + change_table :advisories do |t| + t.remove :project_id + end + end + + def down + change_table :advisories do |t| + t.integer :project_id + end + + Advisory.find_in_batches do |b| + b.each do |advisory| + advisory.project_id = advisory.projects.first.id + advisory.save + end + end + + remove_index :advisories_projects, :column => :advisory_id + remove_index :advisories_projects, :column => :project_id + remove_index :advisories_projects, :name => :advisory_project_index + drop_table :advisories_projects + end +end diff --git a/db/schema.rb b/db/schema.rb index d02f68ff8..beb20f8b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,19 +11,18 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120529130537) do +ActiveRecord::Schema.define(:version => 20120607153342) do 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" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "advisories", :force => true do |t| t.string "advisory_id" - t.integer "project_id" t.text "description", :default => "" t.text "references", :default => "" t.text "update_type", :default => "" @@ -32,7 +31,6 @@ ActiveRecord::Schema.define(:version => 20120529130537) do end add_index "advisories", ["advisory_id"], :name => "index_advisories_on_advisory_id", :unique => true - add_index "advisories", ["project_id"], :name => "index_advisories_on_project_id" add_index "advisories", ["update_type"], :name => "index_advisories_on_update_type" create_table "advisories_platforms", :id => false, :force => true do |t| @@ -44,6 +42,15 @@ ActiveRecord::Schema.define(:version => 20120529130537) do add_index "advisories_platforms", ["advisory_id", "platform_id"], :name => "advisory_platform_index", :unique => true add_index "advisories_platforms", ["platform_id"], :name => "index_advisories_platforms_on_platform_id" + create_table "advisories_projects", :id => false, :force => true do |t| + t.integer "advisory_id" + t.integer "project_id" + end + + add_index "advisories_projects", ["advisory_id"], :name => "index_advisories_projects_on_advisory_id" + add_index "advisories_projects", ["advisory_id", "project_id"], :name => "advisory_project_index", :unique => true + add_index "advisories_projects", ["project_id"], :name => "index_advisories_projects_on_project_id" + create_table "arches", :force => true do |t| t.string "name", :null => false t.datetime "created_at" @@ -102,29 +109,53 @@ ActiveRecord::Schema.define(:version => 20120529130537) do t.datetime "notified_at" t.datetime "created_at" t.datetime "updated_at" - t.boolean "is_circle", :default => false + t.boolean "is_circle" t.text "additional_repos" t.string "name" - t.boolean "build_requires", :default => false + t.boolean "build_requires" t.string "update_type" t.integer "build_for_platform_id" t.integer "save_to_platform_id" t.text "include_repos" t.integer "user_id" - t.boolean "auto_publish", :default => true + t.boolean "auto_publish" t.string "package_version" t.string "commit_hash" - t.integer "priority", :default => 0, :null => false + t.integer "priority", :null => false t.datetime "started_at" t.integer "duration" t.integer "advisory_id" t.integer "mass_build_id" end - add_index "build_lists", ["advisory_id"], :name => "index_build_lists_on_advisory_id" - add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id" - add_index "build_lists", ["bs_id"], :name => "index_build_lists_on_bs_id", :unique => true - add_index "build_lists", ["project_id"], :name => "index_build_lists_on_project_id" + create_table "build_lists_copy", :id => false, :force => true do |t| + t.integer "id", :null => false + t.integer "bs_id" + t.string "container_path" + t.integer "status" + t.string "project_version" + t.integer "project_id" + t.integer "arch_id" + t.datetime "notified_at" + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "is_circle" + t.text "additional_repos" + t.string "name" + t.boolean "build_requires" + t.string "update_type" + t.integer "build_for_platform_id" + t.integer "save_to_platform_id" + t.text "include_repos" + t.integer "user_id" + t.boolean "auto_publish" + t.string "package_version" + t.string "commit_hash" + t.integer "priority", :null => false + t.datetime "started_at" + t.integer "duration" + t.integer "advisory_id" + end create_table "comments", :force => true do |t| t.string "commentable_type" @@ -233,7 +264,7 @@ ActiveRecord::Schema.define(:version => 20120529130537) do t.string "owner_type" t.string "visibility", :default => "open", :null => false t.string "platform_type", :default => "main", :null => false - t.string "distrib_type", :null => false + t.string "distrib_type" end add_index "platforms", ["name"], :name => "index_platforms_on_name", :unique => true, :case_sensitive => false @@ -315,20 +346,21 @@ ActiveRecord::Schema.define(:version => 20120529130537) do t.integer "build_count", :default => 0, :null => false end + add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false + create_table "register_requests", :force => true do |t| t.string "name" t.string "email" t.string "token" t.boolean "approved", :default => false t.boolean "rejected", :default => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "interest" t.text "more" end add_index "register_requests", ["email"], :name => "index_register_requests_on_email", :unique => true, :case_sensitive => false - add_index "register_requests", ["token"], :name => "index_register_requests_on_token", :unique => true, :case_sensitive => false create_table "relations", :force => true do |t| t.integer "actor_id" @@ -376,19 +408,16 @@ ActiveRecord::Schema.define(:version => 20120529130537) do t.string "name" t.string "email", :default => "", :null => false t.string "encrypted_password", :limit => 128, :default => "", :null => false - t.string "password_salt", :default => "", :null => false t.string "reset_password_token" + t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.datetime "created_at" t.datetime "updated_at" + t.text "ssh_key" t.string "uname" t.string "role" t.string "language", :default => "en" - t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" t.integer "own_projects_count", :default => 0, :null => false - t.datetime "reset_password_sent_at" t.text "professional_experience" t.string "site" t.string "company" @@ -400,6 +429,9 @@ ActiveRecord::Schema.define(:version => 20120529130537) do t.integer "failed_attempts", :default => 0 t.string "unlock_token" t.datetime "locked_at" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" t.string "authentication_token" t.integer "build_priority", :default => 50 end diff --git a/vendor/assets/images/chosen/chosen-sprite.png b/vendor/assets/images/chosen/chosen-sprite.png new file mode 100755 index 0000000000000000000000000000000000000000..113dc9885a6b864ac154b266f024b4597f5c6ae7 GIT binary patch literal 559 zcmV+~0?_@5P)7_w9?!Y=&fGw`Tn=~{*Ton1uJA6{0|TOO2&BQ5HsK)1f-8_= zX_7tWzO=>&TSAbor(8d*in_8nYza}~$VhQ@!VyE5(mbqHI3iLyW7NYng`2gyw{w@M zv1lD|8e5_--EQGNFyBI9Dm%P2^&4|~A8h_6JOwVrJdj*~F_*$UV4Lqxwour8q(n*7 zkflFi+GT_()i#XZnd?O10H>gQ&_n|%z37lBGo2_bA2`{-9A0pctz^q&lZEfVJs1{! zF;D>4e-);bob|{m{RT>)$kHVH!F`36uG0Us4@ZUIJNV@Kb5+!py=js37mE_FMvAKw zj*G~aIL$}23dcoCzleIVN?OtPaAnbY' + option.html + ''; + } else { + return ""; + } + }; + + AbstractChosen.prototype.results_update_field = function() { + if (!this.is_multiple) this.results_reset_cleanup(); + this.result_clear_highlight(); + this.result_single_selected = null; + return this.results_build(); + }; + + AbstractChosen.prototype.results_toggle = function() { + if (this.results_showing) { + return this.results_hide(); + } else { + return this.results_show(); + } + }; + + AbstractChosen.prototype.results_search = function(evt) { + if (this.results_showing) { + return this.winnow_results(); + } else { + return this.results_show(); + } + }; + + AbstractChosen.prototype.keyup_checker = function(evt) { + var stroke, _ref; + stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; + this.search_field_scale(); + switch (stroke) { + case 8: + if (this.is_multiple && this.backstroke_length < 1 && this.choices > 0) { + return this.keydown_backstroke(); + } else if (!this.pending_backstroke) { + this.result_clear_highlight(); + return this.results_search(); + } + break; + case 13: + evt.preventDefault(); + if (this.results_showing) return this.result_select(evt); + break; + case 27: + if (this.results_showing) this.results_hide(); + return true; + case 9: + case 38: + case 40: + case 16: + case 91: + case 17: + break; + default: + return this.results_search(); + } + }; + + AbstractChosen.prototype.generate_field_id = function() { + var new_id; + new_id = this.generate_random_id(); + this.form_field.id = new_id; + return new_id; + }; + + AbstractChosen.prototype.generate_random_char = function() { + var chars, newchar, rand; + chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + rand = Math.floor(Math.random() * chars.length); + return newchar = chars.substring(rand, rand + 1); + }; + + return AbstractChosen; + + })(); + + root.AbstractChosen = AbstractChosen; + +}).call(this); + +/* +Chosen source: generate output using 'cake build' +Copyright (c) 2011 by Harvest +*/ + +(function() { + var $, Chosen, get_side_border_padding, root, + __hasProp = Object.prototype.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; + + root = this; + + $ = jQuery; + + $.fn.extend({ + chosen: function(options) { + if ($.browser.msie && ($.browser.version === "6.0" || $.browser.version === "7.0")) { + return this; + } + return this.each(function(input_field) { + var $this; + $this = $(this); + if (!$this.hasClass("chzn-done")) { + return $this.data('chosen', new Chosen(this, options)); + } + }); + } + }); + + Chosen = (function(_super) { + + __extends(Chosen, _super); + + function Chosen() { + Chosen.__super__.constructor.apply(this, arguments); + } + + Chosen.prototype.setup = function() { + this.form_field_jq = $(this.form_field); + this.current_value = this.form_field_jq.val(); + return this.is_rtl = this.form_field_jq.hasClass("chzn-rtl"); + }; + + Chosen.prototype.finish_setup = function() { + return this.form_field_jq.addClass("chzn-done"); + }; + + Chosen.prototype.set_up_html = function() { + var container_div, dd_top, dd_width, sf_width; + this.container_id = this.form_field.id.length ? this.form_field.id.replace(/[^\w]/g, '_') : this.generate_field_id(); + this.container_id += "_chzn"; + this.f_width = this.form_field_jq.outerWidth(); + container_div = $("
", { + id: this.container_id, + "class": "chzn-container" + (this.is_rtl ? ' chzn-rtl' : ''), + style: 'width: ' + this.f_width + 'px;' + }); + if (this.is_multiple) { + container_div.html('
    '); + } else { + container_div.html('' + this.default_text + '
      '); + } + this.form_field_jq.hide().after(container_div); + this.container = $('#' + this.container_id); + this.container.addClass("chzn-container-" + (this.is_multiple ? "multi" : "single")); + this.dropdown = this.container.find('div.chzn-drop').first(); + dd_top = this.container.height(); + dd_width = this.f_width - get_side_border_padding(this.dropdown); + this.dropdown.css({ + "width": dd_width + "px", + "top": dd_top + "px" + }); + this.search_field = this.container.find('input').first(); + this.search_results = this.container.find('ul.chzn-results').first(); + this.search_field_scale(); + this.search_no_results = this.container.find('li.no-results').first(); + if (this.is_multiple) { + this.search_choices = this.container.find('ul.chzn-choices').first(); + this.search_container = this.container.find('li.search-field').first(); + } else { + this.search_container = this.container.find('div.chzn-search').first(); + this.selected_item = this.container.find('.chzn-single').first(); + sf_width = dd_width - get_side_border_padding(this.search_container) - get_side_border_padding(this.search_field); + this.search_field.css({ + "width": sf_width + "px" + }); + } + this.results_build(); + this.set_tab_index(); + return this.form_field_jq.trigger("liszt:ready", { + chosen: this + }); + }; + + Chosen.prototype.register_observers = function() { + var _this = this; + this.container.mousedown(function(evt) { + return _this.container_mousedown(evt); + }); + this.container.mouseup(function(evt) { + return _this.container_mouseup(evt); + }); + this.container.mouseenter(function(evt) { + return _this.mouse_enter(evt); + }); + this.container.mouseleave(function(evt) { + return _this.mouse_leave(evt); + }); + this.search_results.mouseup(function(evt) { + return _this.search_results_mouseup(evt); + }); + this.search_results.mouseover(function(evt) { + return _this.search_results_mouseover(evt); + }); + this.search_results.mouseout(function(evt) { + return _this.search_results_mouseout(evt); + }); + this.form_field_jq.bind("liszt:updated", function(evt) { + return _this.results_update_field(evt); + }); + this.search_field.blur(function(evt) { + return _this.input_blur(evt); + }); + this.search_field.keyup(function(evt) { + return _this.keyup_checker(evt); + }); + this.search_field.keydown(function(evt) { + return _this.keydown_checker(evt); + }); + if (this.is_multiple) { + this.search_choices.click(function(evt) { + return _this.choices_click(evt); + }); + return this.search_field.focus(function(evt) { + return _this.input_focus(evt); + }); + } else { + return this.container.click(function(evt) { + return evt.preventDefault(); + }); + } + }; + + Chosen.prototype.search_field_disabled = function() { + this.is_disabled = this.form_field_jq[0].disabled; + if (this.is_disabled) { + this.container.addClass('chzn-disabled'); + this.search_field[0].disabled = true; + if (!this.is_multiple) { + this.selected_item.unbind("focus", this.activate_action); + } + return this.close_field(); + } else { + this.container.removeClass('chzn-disabled'); + this.search_field[0].disabled = false; + if (!this.is_multiple) { + return this.selected_item.bind("focus", this.activate_action); + } + } + }; + + Chosen.prototype.container_mousedown = function(evt) { + var target_closelink; + if (!this.is_disabled) { + target_closelink = evt != null ? ($(evt.target)).hasClass("search-choice-close") : false; + if (evt && evt.type === "mousedown" && !this.results_showing) { + evt.stopPropagation(); + } + if (!this.pending_destroy_click && !target_closelink) { + if (!this.active_field) { + if (this.is_multiple) this.search_field.val(""); + $(document).click(this.click_test_action); + this.results_show(); + } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chzn-single").length)) { + evt.preventDefault(); + this.results_toggle(); + } + return this.activate_field(); + } else { + return this.pending_destroy_click = false; + } + } + }; + + Chosen.prototype.container_mouseup = function(evt) { + if (evt.target.nodeName === "ABBR" && !this.is_disabled) { + return this.results_reset(evt); + } + }; + + Chosen.prototype.blur_test = function(evt) { + if (!this.active_field && this.container.hasClass("chzn-container-active")) { + return this.close_field(); + } + }; + + Chosen.prototype.close_field = function() { + $(document).unbind("click", this.click_test_action); + if (!this.is_multiple) { + this.selected_item.attr("tabindex", this.search_field.attr("tabindex")); + this.search_field.attr("tabindex", -1); + } + this.active_field = false; + this.results_hide(); + this.container.removeClass("chzn-container-active"); + this.winnow_results_clear(); + this.clear_backstroke(); + this.show_search_field_default(); + return this.search_field_scale(); + }; + + Chosen.prototype.activate_field = function() { + if (!this.is_multiple && !this.active_field) { + this.search_field.attr("tabindex", this.selected_item.attr("tabindex")); + this.selected_item.attr("tabindex", -1); + } + this.container.addClass("chzn-container-active"); + this.active_field = true; + this.search_field.val(this.search_field.val()); + return this.search_field.focus(); + }; + + Chosen.prototype.test_active_click = function(evt) { + if ($(evt.target).parents('#' + this.container_id).length) { + return this.active_field = true; + } else { + return this.close_field(); + } + }; + + Chosen.prototype.results_build = function() { + var content, data, _i, _len, _ref; + this.parsing = true; + this.results_data = root.SelectParser.select_to_array(this.form_field); + if (this.is_multiple && this.choices > 0) { + this.search_choices.find("li.search-choice").remove(); + this.choices = 0; + } else if (!this.is_multiple) { + this.selected_item.addClass("chzn-default").find("span").text(this.default_text); + if (this.form_field.options.length <= this.disable_search_threshold) { + this.container.addClass("chzn-container-single-nosearch"); + } else { + this.container.removeClass("chzn-container-single-nosearch"); + } + } + content = ''; + _ref = this.results_data; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + data = _ref[_i]; + if (data.group) { + content += this.result_add_group(data); + } else if (!data.empty) { + content += this.result_add_option(data); + if (data.selected && this.is_multiple) { + this.choice_build(data); + } else if (data.selected && !this.is_multiple) { + this.selected_item.removeClass("chzn-default").find("span").text(data.text); + if (this.allow_single_deselect) this.single_deselect_control_build(); + } + } + } + this.search_field_disabled(); + this.show_search_field_default(); + this.search_field_scale(); + this.search_results.html(content); + return this.parsing = false; + }; + + Chosen.prototype.result_add_group = function(group) { + if (!group.disabled) { + group.dom_id = this.container_id + "_g_" + group.array_index; + return '
    • ' + $("
      ").text(group.label).html() + '
    • '; + } else { + return ""; + } + }; + + Chosen.prototype.result_do_highlight = function(el) { + var high_bottom, high_top, maxHeight, visible_bottom, visible_top; + if (el.length) { + this.result_clear_highlight(); + this.result_highlight = el; + this.result_highlight.addClass("highlighted"); + maxHeight = parseInt(this.search_results.css("maxHeight"), 10); + visible_top = this.search_results.scrollTop(); + visible_bottom = maxHeight + visible_top; + high_top = this.result_highlight.position().top + this.search_results.scrollTop(); + high_bottom = high_top + this.result_highlight.outerHeight(); + if (high_bottom >= visible_bottom) { + return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0); + } else if (high_top < visible_top) { + return this.search_results.scrollTop(high_top); + } + } + }; + + Chosen.prototype.result_clear_highlight = function() { + if (this.result_highlight) this.result_highlight.removeClass("highlighted"); + return this.result_highlight = null; + }; + + Chosen.prototype.results_show = function() { + var dd_top; + if (!this.is_multiple) { + this.selected_item.addClass("chzn-single-with-drop"); + if (this.result_single_selected) { + this.result_do_highlight(this.result_single_selected); + } + } else if (this.max_selected_options <= this.choices) { + this.form_field_jq.trigger("liszt:maxselected", { + chosen: this + }); + return false; + } + dd_top = this.is_multiple ? this.container.height() : this.container.height() - 1; + this.form_field_jq.trigger("liszt:showing_dropdown", { + chosen: this + }); + this.dropdown.css({ + "top": dd_top + "px", + "left": 0 + }); + this.results_showing = true; + this.search_field.focus(); + this.search_field.val(this.search_field.val()); + return this.winnow_results(); + }; + + Chosen.prototype.results_hide = function() { + if (!this.is_multiple) { + this.selected_item.removeClass("chzn-single-with-drop"); + } + this.result_clear_highlight(); + this.form_field_jq.trigger("liszt:hiding_dropdown", { + chosen: this + }); + this.dropdown.css({ + "left": "-9000px" + }); + return this.results_showing = false; + }; + + Chosen.prototype.set_tab_index = function(el) { + var ti; + if (this.form_field_jq.attr("tabindex")) { + ti = this.form_field_jq.attr("tabindex"); + this.form_field_jq.attr("tabindex", -1); + if (this.is_multiple) { + return this.search_field.attr("tabindex", ti); + } else { + this.selected_item.attr("tabindex", ti); + return this.search_field.attr("tabindex", -1); + } + } + }; + + Chosen.prototype.show_search_field_default = function() { + if (this.is_multiple && this.choices < 1 && !this.active_field) { + this.search_field.val(this.default_text); + return this.search_field.addClass("default"); + } else { + this.search_field.val(""); + return this.search_field.removeClass("default"); + } + }; + + Chosen.prototype.search_results_mouseup = function(evt) { + var target; + target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); + if (target.length) { + this.result_highlight = target; + return this.result_select(evt); + } + }; + + Chosen.prototype.search_results_mouseover = function(evt) { + var target; + target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); + if (target) return this.result_do_highlight(target); + }; + + Chosen.prototype.search_results_mouseout = function(evt) { + if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) { + return this.result_clear_highlight(); + } + }; + + Chosen.prototype.choices_click = function(evt) { + evt.preventDefault(); + if (this.active_field && !($(evt.target).hasClass("search-choice" || $(evt.target).parents('.search-choice').first)) && !this.results_showing) { + return this.results_show(); + } + }; + + Chosen.prototype.choice_build = function(item) { + var choice_id, link, + _this = this; + if (this.is_multiple && this.max_selected_options <= this.choices) { + this.form_field_jq.trigger("liszt:maxselected", { + chosen: this + }); + return false; + } + choice_id = this.container_id + "_c_" + item.array_index; + this.choices += 1; + this.search_container.before('
    • ' + item.html + '
    • '); + link = $('#' + choice_id).find("a").first(); + return link.click(function(evt) { + return _this.choice_destroy_link_click(evt); + }); + }; + + Chosen.prototype.choice_destroy_link_click = function(evt) { + evt.preventDefault(); + if (!this.is_disabled) { + this.pending_destroy_click = true; + return this.choice_destroy($(evt.target)); + } else { + return evt.stopPropagation; + } + }; + + Chosen.prototype.choice_destroy = function(link) { + this.choices -= 1; + this.show_search_field_default(); + if (this.is_multiple && this.choices > 0 && this.search_field.val().length < 1) { + this.results_hide(); + } + this.result_deselect(link.attr("rel")); + return link.parents('li').first().remove(); + }; + + Chosen.prototype.results_reset = function() { + this.form_field.options[0].selected = true; + this.selected_item.find("span").text(this.default_text); + if (!this.is_multiple) this.selected_item.addClass("chzn-default"); + this.show_search_field_default(); + this.results_reset_cleanup(); + this.form_field_jq.trigger("change"); + if (this.active_field) return this.results_hide(); + }; + + Chosen.prototype.results_reset_cleanup = function() { + return this.selected_item.find("abbr").remove(); + }; + + Chosen.prototype.result_select = function(evt) { + var high, high_id, item, position; + if (this.result_highlight) { + high = this.result_highlight; + high_id = high.attr("id"); + this.result_clear_highlight(); + if (this.is_multiple) { + this.result_deactivate(high); + } else { + this.search_results.find(".result-selected").removeClass("result-selected"); + this.result_single_selected = high; + this.selected_item.removeClass("chzn-default"); + } + high.addClass("result-selected"); + position = high_id.substr(high_id.lastIndexOf("_") + 1); + item = this.results_data[position]; + item.selected = true; + this.form_field.options[item.options_index].selected = true; + if (this.is_multiple) { + this.choice_build(item); + } else { + this.selected_item.find("span").first().text(item.text); + if (this.allow_single_deselect) this.single_deselect_control_build(); + } + if (!(evt.metaKey && this.is_multiple)) this.results_hide(); + this.search_field.val(""); + if (this.is_multiple || this.form_field_jq.val() !== this.current_value) { + this.form_field_jq.trigger("change", { + 'selected': this.form_field.options[item.options_index].value + }); + } + this.current_value = this.form_field_jq.val(); + return this.search_field_scale(); + } + }; + + Chosen.prototype.result_activate = function(el) { + return el.addClass("active-result"); + }; + + Chosen.prototype.result_deactivate = function(el) { + return el.removeClass("active-result"); + }; + + Chosen.prototype.result_deselect = function(pos) { + var result, result_data; + result_data = this.results_data[pos]; + result_data.selected = false; + this.form_field.options[result_data.options_index].selected = false; + result = $("#" + this.container_id + "_o_" + pos); + result.removeClass("result-selected").addClass("active-result").show(); + this.result_clear_highlight(); + this.winnow_results(); + this.form_field_jq.trigger("change", { + deselected: this.form_field.options[result_data.options_index].value + }); + return this.search_field_scale(); + }; + + Chosen.prototype.single_deselect_control_build = function() { + if (this.allow_single_deselect && this.selected_item.find("abbr").length < 1) { + return this.selected_item.find("span").first().after(""); + } + }; + + Chosen.prototype.winnow_results = function() { + var found, option, part, parts, regex, regexAnchor, result, result_id, results, searchText, startpos, text, zregex, _i, _j, _len, _len2, _ref; + this.no_results_clear(); + results = 0; + searchText = this.search_field.val() === this.default_text ? "" : $('
      ').text($.trim(this.search_field.val())).html(); + regexAnchor = this.search_contains ? "" : "^"; + regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); + zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); + _ref = this.results_data; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + option = _ref[_i]; + if (!option.disabled && !option.empty) { + if (option.group) { + $('#' + option.dom_id).css('display', 'none'); + } else if (!(this.is_multiple && option.selected)) { + found = false; + result_id = option.dom_id; + result = $("#" + result_id); + if (regex.test(option.html)) { + found = true; + results += 1; + } else if (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0) { + parts = option.html.replace(/\[|\]/g, "").split(" "); + if (parts.length) { + for (_j = 0, _len2 = parts.length; _j < _len2; _j++) { + part = parts[_j]; + if (regex.test(part)) { + found = true; + results += 1; + } + } + } + } + if (found) { + if (searchText.length) { + startpos = option.html.search(zregex); + text = option.html.substr(0, startpos + searchText.length) + '' + option.html.substr(startpos + searchText.length); + text = text.substr(0, startpos) + '' + text.substr(startpos); + } else { + text = option.html; + } + result.html(text); + this.result_activate(result); + if (option.group_array_index != null) { + $("#" + this.results_data[option.group_array_index].dom_id).css('display', 'list-item'); + } + } else { + if (this.result_highlight && result_id === this.result_highlight.attr('id')) { + this.result_clear_highlight(); + } + this.result_deactivate(result); + } + } + } + } + if (results < 1 && searchText.length) { + return this.no_results(searchText); + } else { + return this.winnow_results_set_highlight(); + } + }; + + Chosen.prototype.winnow_results_clear = function() { + var li, lis, _i, _len, _results; + this.search_field.val(""); + lis = this.search_results.find("li"); + _results = []; + for (_i = 0, _len = lis.length; _i < _len; _i++) { + li = lis[_i]; + li = $(li); + if (li.hasClass("group-result")) { + _results.push(li.css('display', 'auto')); + } else if (!this.is_multiple || !li.hasClass("result-selected")) { + _results.push(this.result_activate(li)); + } else { + _results.push(void 0); + } + } + return _results; + }; + + Chosen.prototype.winnow_results_set_highlight = function() { + var do_high, selected_results; + if (!this.result_highlight) { + selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : []; + do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first(); + if (do_high != null) return this.result_do_highlight(do_high); + } + }; + + Chosen.prototype.no_results = function(terms) { + var no_results_html; + no_results_html = $('
    • ' + this.results_none_found + ' ""
    • '); + no_results_html.find("span").first().html(terms); + return this.search_results.append(no_results_html); + }; + + Chosen.prototype.no_results_clear = function() { + return this.search_results.find(".no-results").remove(); + }; + + Chosen.prototype.keydown_arrow = function() { + var first_active, next_sib; + if (!this.result_highlight) { + first_active = this.search_results.find("li.active-result").first(); + if (first_active) this.result_do_highlight($(first_active)); + } else if (this.results_showing) { + next_sib = this.result_highlight.nextAll("li.active-result").first(); + if (next_sib) this.result_do_highlight(next_sib); + } + if (!this.results_showing) return this.results_show(); + }; + + Chosen.prototype.keyup_arrow = function() { + var prev_sibs; + if (!this.results_showing && !this.is_multiple) { + return this.results_show(); + } else if (this.result_highlight) { + prev_sibs = this.result_highlight.prevAll("li.active-result"); + if (prev_sibs.length) { + return this.result_do_highlight(prev_sibs.first()); + } else { + if (this.choices > 0) this.results_hide(); + return this.result_clear_highlight(); + } + } + }; + + Chosen.prototype.keydown_backstroke = function() { + if (this.pending_backstroke) { + this.choice_destroy(this.pending_backstroke.find("a").first()); + return this.clear_backstroke(); + } else { + this.pending_backstroke = this.search_container.siblings("li.search-choice").last(); + if (this.single_backstroke_delete) { + return this.keydown_backstroke(); + } else { + return this.pending_backstroke.addClass("search-choice-focus"); + } + } + }; + + Chosen.prototype.clear_backstroke = function() { + if (this.pending_backstroke) { + this.pending_backstroke.removeClass("search-choice-focus"); + } + return this.pending_backstroke = null; + }; + + Chosen.prototype.keydown_checker = function(evt) { + var stroke, _ref; + stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; + this.search_field_scale(); + if (stroke !== 8 && this.pending_backstroke) this.clear_backstroke(); + switch (stroke) { + case 8: + this.backstroke_length = this.search_field.val().length; + break; + case 9: + if (this.results_showing && !this.is_multiple) this.result_select(evt); + this.mouse_on_container = false; + break; + case 13: + evt.preventDefault(); + break; + case 38: + evt.preventDefault(); + this.keyup_arrow(); + break; + case 40: + this.keydown_arrow(); + break; + } + }; + + Chosen.prototype.search_field_scale = function() { + var dd_top, div, h, style, style_block, styles, w, _i, _len; + if (this.is_multiple) { + h = 0; + w = 0; + style_block = "position:absolute; left: -1000px; top: -1000px; display:none;"; + styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing']; + for (_i = 0, _len = styles.length; _i < _len; _i++) { + style = styles[_i]; + style_block += style + ":" + this.search_field.css(style) + ";"; + } + div = $('
      ', { + 'style': style_block + }); + div.text(this.search_field.val()); + $('body').append(div); + w = div.width() + 25; + div.remove(); + if (w > this.f_width - 10) w = this.f_width - 10; + this.search_field.css({ + 'width': w + 'px' + }); + dd_top = this.container.height(); + return this.dropdown.css({ + "top": dd_top + "px" + }); + } + }; + + Chosen.prototype.generate_random_id = function() { + var string; + string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char(); + while ($("#" + string).length > 0) { + string += this.generate_random_char(); + } + return string; + }; + + return Chosen; + + })(AbstractChosen); + + get_side_border_padding = function(elmt) { + var side_border_padding; + return side_border_padding = elmt.outerWidth() - elmt.width(); + }; + + root.get_side_border_padding = get_side_border_padding; + +}).call(this); diff --git a/vendor/assets/javascripts/vendor.js b/vendor/assets/javascripts/vendor.js index 1cdbc55b5..aafbbfbed 100644 --- a/vendor/assets/javascripts/vendor.js +++ b/vendor/assets/javascripts/vendor.js @@ -10,5 +10,8 @@ //= require bootstrap-modal //= require bootstrap-button //= require bootstrap-dropdown +//= require bootstrap-tooltip +//= require bootstrap-popover +//= require chosen.jquery // require html5shiv // require_tree . diff --git a/vendor/assets/stylesheets/chosen.scss b/vendor/assets/stylesheets/chosen.scss new file mode 100755 index 000000000..ddb4d7036 --- /dev/null +++ b/vendor/assets/stylesheets/chosen.scss @@ -0,0 +1,396 @@ +/* @group Base */ +.chzn-container { + font-size: 13px; + position: relative; + display: inline-block; + zoom: 1; + *display: inline; +} +.chzn-container .chzn-drop { + background: #fff; + border: 1px solid #aaa; + border-top: 0; + position: absolute; + top: 29px; + left: 0; + -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15); + -moz-box-shadow : 0 4px 5px rgba(0,0,0,.15); + -o-box-shadow : 0 4px 5px rgba(0,0,0,.15); + box-shadow : 0 4px 5px rgba(0,0,0,.15); + z-index: 1010; +} +/* @end */ + +/* @group Single Chosen */ +.chzn-container-single .chzn-single { + background-color: #ffffff; + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0 ); + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4)); + background-image: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: -ms-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + background-image: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); + -webkit-border-radius: 5px; + -moz-border-radius : 5px; + border-radius : 5px; + -moz-background-clip : padding; + -webkit-background-clip: padding-box; + background-clip : padding-box; + border: 1px solid #aaaaaa; + -webkit-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1); + -moz-box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1); + box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1); + display: block; + overflow: hidden; + white-space: nowrap; + position: relative; + height: 23px; + line-height: 24px; + padding: 0 0 0 8px; + color: #444444; + text-decoration: none; +} +.chzn-container-single .chzn-default { + color: #999; +} +.chzn-container-single .chzn-single span { + margin-right: 26px; + display: block; + overflow: hidden; + white-space: nowrap; + -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.chzn-container-single .chzn-single abbr { + display: block; + position: absolute; + right: 26px; + top: 6px; + width: 12px; + height: 13px; + font-size: 1px; + background: image-url('chosen/chosen-sprite.png') right top no-repeat; +} +.chzn-container-single .chzn-single abbr:hover { + background-position: right -11px; +} +.chzn-container-single.chzn-disabled .chzn-single abbr:hover { + background-position: right top; +} +.chzn-container-single .chzn-single div { + position: absolute; + right: 0; + top: 0; + display: block; + height: 100%; + width: 18px; +} +.chzn-container-single .chzn-single div b { + background: image-url('chosen/chosen-sprite.png') no-repeat 0 0; + display: block; + width: 100%; + height: 100%; +} +.chzn-container-single .chzn-search { + padding: 3px 4px; + position: relative; + margin: 0; + white-space: nowrap; + z-index: 1010; +} +.chzn-container-single .chzn-search input { + background: #fff image-url('chosen/chosen-sprite.png') no-repeat 100% -22px; + background: image-url('chosen/chosen-sprite.png') no-repeat 100% -22px, -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); + background: image-url('chosen/chosen-sprite.png') no-repeat 100% -22px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat 100% -22px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat 100% -22px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat 100% -22px, -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat 100% -22px, linear-gradient(top, #eeeeee 1%, #ffffff 15%); + margin: 1px 0; + padding: 4px 20px 4px 5px; + outline: 0; + border: 1px solid #aaa; + font-family: sans-serif; + font-size: 1em; +} +.chzn-container-single .chzn-drop { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius : 0 0 4px 4px; + border-radius : 0 0 4px 4px; + -moz-background-clip : padding; + -webkit-background-clip: padding-box; + background-clip : padding-box; +} +/* @end */ + +.chzn-container-single-nosearch .chzn-search input { + position: absolute; + left: -9000px; +} + +/* @group Multi Chosen */ +.chzn-container-multi .chzn-choices { + background-color: #fff; + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); + background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%); + border: 1px solid #aaa; + margin: 0; + padding: 0; + cursor: text; + overflow: hidden; + height: auto !important; + height: 1%; + position: relative; +} +.chzn-container-multi .chzn-choices li { + float: left; + list-style: none; +} +.chzn-container-multi .chzn-choices .search-field { + white-space: nowrap; + margin: 0; + padding: 0; +} +.chzn-container-multi .chzn-choices .search-field input { + color: #666; + background: transparent !important; + border: 0 !important; + font-family: sans-serif; + font-size: 100%; + height: 15px; + padding: 5px; + margin: 1px 0; + outline: 0; + -webkit-box-shadow: none; + -moz-box-shadow : none; + -o-box-shadow : none; + box-shadow : none; +} +.chzn-container-multi .chzn-choices .search-field .default { + color: #999; +} +.chzn-container-multi .chzn-choices .search-choice { + -webkit-border-radius: 3px; + -moz-border-radius : 3px; + border-radius : 3px; + -moz-background-clip : padding; + -webkit-background-clip: padding-box; + background-clip : padding-box; + background-color: #e4e4e4; + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 ); + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); + background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); + -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); + -moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); + box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); + color: #333; + border: 1px solid #aaaaaa; + line-height: 13px; + padding: 3px 20px 3px 5px; + margin: 3px 0 3px 5px; + position: relative; + cursor: default; +} +.chzn-container-multi .chzn-choices .search-choice-focus { + background: #d4d4d4; +} +.chzn-container-multi .chzn-choices .search-choice .search-choice-close { + display: block; + position: absolute; + right: 3px; + top: 4px; + width: 12px; + height: 13px; + font-size: 1px; + background: image-url('chosen/chosen-sprite.png') right top no-repeat; +} +.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { + background-position: right -11px; +} +.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close { + background-position: right -11px; +} +/* @end */ + +/* @group Results */ +.chzn-container .chzn-results { + margin: 0 4px 4px 0; + max-height: 240px; + padding: 0 0 0 4px; + position: relative; + overflow-x: hidden; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} +.chzn-container-multi .chzn-results { + margin: -1px 0 0; + padding: 0; +} +.chzn-container .chzn-results li { + display: none; + line-height: 15px; + padding: 5px 6px; + margin: 0; + list-style: none; +} +.chzn-container .chzn-results .active-result { + cursor: pointer; + display: list-item; +} +.chzn-container .chzn-results .highlighted { + background-color: #3875d7; + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3875d7', endColorstr='#2a62bc', GradientType=0 ); + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc)); + background-image: -webkit-linear-gradient(top, #3875d7 20%, #2a62bc 90%); + background-image: -moz-linear-gradient(top, #3875d7 20%, #2a62bc 90%); + background-image: -o-linear-gradient(top, #3875d7 20%, #2a62bc 90%); + background-image: -ms-linear-gradient(top, #3875d7 20%, #2a62bc 90%); + background-image: linear-gradient(top, #3875d7 20%, #2a62bc 90%); + color: #fff; +} +.chzn-container .chzn-results li em { + background: #feffde; + font-style: normal; +} +.chzn-container .chzn-results .highlighted em { + background: transparent; +} +.chzn-container .chzn-results .no-results { + background: #f4f4f4; + display: list-item; +} +.chzn-container .chzn-results .group-result { + cursor: default; + color: #999; + font-weight: bold; +} +.chzn-container .chzn-results .group-option { + padding-left: 15px; +} +.chzn-container-multi .chzn-drop .result-selected { + display: none; +} +.chzn-container .chzn-results-scroll { + background: white; + margin: 0 4px; + position: absolute; + text-align: center; + width: 321px; /* This should by dynamic with js */ + z-index: 1; +} +.chzn-container .chzn-results-scroll span { + display: inline-block; + height: 17px; + text-indent: -5000px; + width: 9px; +} +.chzn-container .chzn-results-scroll-down { + bottom: 0; +} +.chzn-container .chzn-results-scroll-down span { + background: image-url('chosen/chosen-sprite.png') no-repeat -4px -3px; +} +.chzn-container .chzn-results-scroll-up span { + background: image-url('chosen/chosen-sprite.png') no-repeat -22px -3px; +} +/* @end */ + +/* @group Active */ +.chzn-container-active .chzn-single { + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); + -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); + -o-box-shadow : 0 0 5px rgba(0,0,0,.3); + box-shadow : 0 0 5px rgba(0,0,0,.3); + border: 1px solid #5897fb; +} +.chzn-container-active .chzn-single-with-drop { + border: 1px solid #aaa; + -webkit-box-shadow: 0 1px 0 #fff inset; + -moz-box-shadow : 0 1px 0 #fff inset; + -o-box-shadow : 0 1px 0 #fff inset; + box-shadow : 0 1px 0 #fff inset; + background-color: #eee; + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0 ); + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff)); + background-image: -webkit-linear-gradient(top, #eeeeee 20%, #ffffff 80%); + background-image: -moz-linear-gradient(top, #eeeeee 20%, #ffffff 80%); + background-image: -o-linear-gradient(top, #eeeeee 20%, #ffffff 80%); + background-image: -ms-linear-gradient(top, #eeeeee 20%, #ffffff 80%); + background-image: linear-gradient(top, #eeeeee 20%, #ffffff 80%); + -webkit-border-bottom-left-radius : 0; + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomleft : 0; + -moz-border-radius-bottomright: 0; + border-bottom-left-radius : 0; + border-bottom-right-radius: 0; +} +.chzn-container-active .chzn-single-with-drop div { + background: transparent; + border-left: none; +} +.chzn-container-active .chzn-single-with-drop div b { + background-position: -18px 1px; +} +.chzn-container-active .chzn-choices { + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); + -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); + -o-box-shadow : 0 0 5px rgba(0,0,0,.3); + box-shadow : 0 0 5px rgba(0,0,0,.3); + border: 1px solid #5897fb; +} +.chzn-container-active .chzn-choices .search-field input { + color: #111 !important; +} +/* @end */ + +/* @group Disabled Support */ +.chzn-disabled { + cursor: default; + opacity:0.5 !important; +} +.chzn-disabled .chzn-single { + cursor: default; +} +.chzn-disabled .chzn-choices .search-choice .search-choice-close { + cursor: default; +} + +/* @group Right to Left */ +.chzn-rtl { text-align: right; } +.chzn-rtl .chzn-single { padding: 0 8px 0 0; overflow: visible; } +.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; direction: rtl; } + +.chzn-rtl .chzn-single div { left: 3px; right: auto; } +.chzn-rtl .chzn-single abbr { + left: 26px; + right: auto; +} +.chzn-rtl .chzn-choices .search-field input { direction: rtl; } +.chzn-rtl .chzn-choices li { float: right; } +.chzn-rtl .chzn-choices .search-choice { padding: 3px 5px 3px 19px; margin: 3px 5px 3px 0; } +.chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 4px; right: auto; background-position: right top;} +.chzn-rtl.chzn-container-single .chzn-results { margin: 0 0 4px 4px; padding: 0 4px 0 0; } +.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 15px; } +.chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; } +.chzn-rtl .chzn-search input { + background: #fff image-url('chosen/chosen-sprite.png') no-repeat -38px -22px; + background: image-url('chosen/chosen-sprite.png') no-repeat -38px -22px, -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); + background: image-url('chosen/chosen-sprite.png') no-repeat -38px -22px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat -38px -22px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat -38px -22px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat -38px -22px, -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%); + background: image-url('chosen/chosen-sprite.png') no-repeat -38px -22px, linear-gradient(top, #eeeeee 1%, #ffffff 15%); + padding: 4px 5px 4px 20px; + direction: rtl; +} +/* @end */ diff --git a/vendor/assets/stylesheets/vendor.scss b/vendor/assets/stylesheets/vendor.scss index 9bac4e7b0..8c3767f62 100644 --- a/vendor/assets/stylesheets/vendor.scss +++ b/vendor/assets/stylesheets/vendor.scss @@ -13,4 +13,5 @@ @import "codemirror/modes/rpm-spec"; @import "codemirror/modes/tiddlywiki"; -@import "bootstrap" +@import "bootstrap"; +@import "chosen.scss"; From 60f1f68ce1fedc58a2f4aa80c6e097c1ee4cae3b Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 20 Jun 2012 00:04:33 +0400 Subject: [PATCH 02/48] [issue #428] Fixed schema.rb . Removed debug code. --- app/controllers/advisories_controller.rb | 1 - db/schema.rb | 144 ++++++++++------------- 2 files changed, 61 insertions(+), 84 deletions(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 5510e1526..6a8f6b3a2 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -1,5 +1,4 @@ # -*- encoding : utf-8 -*- -require 'pp' class AdvisoriesController < ApplicationController before_filter :authenticate_user! skip_before_filter :authenticate_user! if APP_CONFIG['anonymous_access'] diff --git a/db/schema.rb b/db/schema.rb index d2af06b79..535ffe778 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -53,8 +53,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do create_table "arches", :force => true do |t| t.string "name", :null => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "arches", ["name"], :name => "index_arches_on_name", :unique => true @@ -63,8 +63,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.integer "user_id" t.string "provider" t.string "uid" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "authentications", ["provider", "uid"], :name => "index_authentications_on_provider_and_uid", :unique => true @@ -75,8 +75,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.integer "level" t.integer "status" t.integer "build_list_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "version" end @@ -107,62 +107,38 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.integer "project_id" t.integer "arch_id" t.datetime "notified_at" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "is_circle" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "is_circle", :default => false t.text "additional_repos" t.string "name" - t.boolean "build_requires" + t.boolean "build_requires", :default => false t.string "update_type" t.integer "build_for_platform_id" t.integer "save_to_platform_id" t.text "include_repos" t.integer "user_id" - t.boolean "auto_publish" + t.boolean "auto_publish", :default => true t.string "package_version" t.string "commit_hash" - t.integer "priority", :null => false + t.integer "priority", :default => 0, :null => false t.datetime "started_at" t.integer "duration" t.integer "advisory_id" t.integer "mass_build_id" end - create_table "build_lists_copy", :id => false, :force => true do |t| - t.integer "id", :null => false - t.integer "bs_id" - t.string "container_path" - t.integer "status" - t.string "project_version" - t.integer "project_id" - t.integer "arch_id" - t.datetime "notified_at" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "is_circle" - t.text "additional_repos" - t.string "name" - t.boolean "build_requires" - t.string "update_type" - t.integer "build_for_platform_id" - t.integer "save_to_platform_id" - t.text "include_repos" - t.integer "user_id" - t.boolean "auto_publish" - t.string "package_version" - t.string "commit_hash" - t.integer "priority", :null => false - t.datetime "started_at" - t.integer "duration" - t.integer "advisory_id" - end + add_index "build_lists", ["advisory_id"], :name => "index_build_lists_on_advisory_id" + add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id" + add_index "build_lists", ["bs_id"], :name => "index_build_lists_on_bs_id", :unique => true + add_index "build_lists", ["project_id"], :name => "index_build_lists_on_project_id" create_table "comments", :force => true do |t| t.string "commentable_type" t.integer "user_id" t.text "body" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.decimal "commentable_id", :precision => 50, :scale => 0 t.integer "project_id" end @@ -179,14 +155,14 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.string "controller" t.string "action" t.text "message" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "groups", :force => true do |t| t.integer "owner_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "uname" t.integer "own_projects_count", :default => 0, :null => false t.text "description" @@ -199,8 +175,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.string "title" t.text "body" t.string "status", :default => "open" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "user_id" t.datetime "closed_at" t.integer "closed_by" @@ -241,8 +217,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.string "description" t.string "name", :null => false t.integer "parent_platform_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "released", :default => false, :null => false t.integer "owner_id" t.string "owner_type" @@ -257,8 +233,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.integer "platform_id" t.string "login" t.string "password" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "user_id" end @@ -266,8 +242,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.integer "product_id" t.integer "status", :default => 2, :null => false t.datetime "notified_at" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end add_index "product_build_lists", ["product_id"], :name => "index_product_build_lists_on_product_id" @@ -275,8 +251,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do create_table "products", :force => true do |t| t.string "name", :null => false t.integer "platform_id", :null => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.text "build_script" t.text "counter" t.text "ks" @@ -295,8 +271,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.string "name" t.string "version" t.datetime "file_mtime" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "platform_id" end @@ -305,14 +281,14 @@ ActiveRecord::Schema.define(:version => 20120609163454) do create_table "project_to_repositories", :force => true do |t| t.integer "project_id" t.integer "repository_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "projects", :force => true do |t| t.string "name" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "owner_id" t.string "owner_type" t.string "visibility", :default => "open" @@ -338,29 +314,30 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.string "token" t.boolean "approved", :default => false t.boolean "rejected", :default => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "interest" t.text "more" end add_index "register_requests", ["email"], :name => "index_register_requests_on_email", :unique => true, :case_sensitive => false + add_index "register_requests", ["token"], :name => "index_register_requests_on_token", :unique => true, :case_sensitive => false create_table "relations", :force => true do |t| t.integer "actor_id" t.string "actor_type" t.integer "target_id" t.string "target_type" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "role" end create_table "repositories", :force => true do |t| t.string "description", :null => false t.integer "platform_id", :null => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "name", :null => false end @@ -371,8 +348,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.boolean "new_comment_reply", :default => true t.boolean "new_issue", :default => true t.boolean "issue_assign", :default => true - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "new_comment_commit_owner", :default => true t.boolean "new_comment_commit_repo_owner", :default => true t.boolean "new_comment_commit_commentor", :default => true @@ -381,8 +358,8 @@ ActiveRecord::Schema.define(:version => 20120609163454) do create_table "subscribes", :force => true do |t| t.string "subscribeable_type" t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "status", :default => true t.integer "project_id" t.decimal "subscribeable_id", :precision => 50, :scale => 0 @@ -390,17 +367,21 @@ ActiveRecord::Schema.define(:version => 20120609163454) do create_table "users", :force => true do |t| t.string "name" - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :default => "", :null => false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "ssh_key" t.string "uname" t.string "role" - t.string "language", :default => "en" - t.integer "own_projects_count", :default => 0, :null => false + t.string "language", :default => "en" + t.integer "own_projects_count", :default => 0, :null => false + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" t.text "professional_experience" t.string "site" t.string "company" @@ -409,14 +390,11 @@ ActiveRecord::Schema.define(:version => 20120609163454) do t.string "avatar_content_type" t.integer "avatar_file_size" t.datetime "avatar_updated_at" - t.integer "failed_attempts", :default => 0 + t.integer "failed_attempts", :default => 0 t.string "unlock_token" t.datetime "locked_at" - t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" t.string "authentication_token" - t.integer "build_priority", :default => 50 + t.integer "build_priority", :default => 50 end add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token" From 01b8f3b5c556c269c3a0caf26811360957f05053 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 20 Jun 2012 00:32:56 +0400 Subject: [PATCH 03/48] [issue #428] Fixed typo --- app/controllers/projects/build_lists_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index a3c27b724..758b584e9 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -70,7 +70,7 @@ class Projects::BuildListsController < Projects::BaseController def show @item_groups = @build_list.items.group_by_level - @advisories = Advisories.all + @advisories = Advisory.all end def update From 3d38adcb94df3a1387893b548637be3a06706f24 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 20 Jun 2012 18:07:07 +0400 Subject: [PATCH 04/48] [issue #428] Added Atom feed to advisories. --- app/controllers/advisories_controller.rb | 6 +++++- app/models/advisory.rb | 1 + app/views/advisories/_feed_partial.haml | 8 ++++++++ app/views/advisories/_packages_info.html.haml | 2 +- app/views/advisories/index.atom.builder | 14 ++++++++++++++ app/views/advisories/index.html.haml | 4 ++++ config/locales/models/advisory.en.yml | 2 ++ config/locales/models/advisory.ru.yml | 2 ++ 8 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 app/views/advisories/_feed_partial.haml create mode 100644 app/views/advisories/index.atom.builder diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 6a8f6b3a2..69e73cc96 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -6,7 +6,11 @@ class AdvisoriesController < ApplicationController authorize_resource def index - @advisories = @advisories.scoped(:include => :projects).paginate(:page => params[:page]) + @advisories = @advisories.scoped(:include => :platforms).paginate(:page => params[:page]) + respond_to do |format| + format.html + format.atom + end end def show diff --git a/app/models/advisory.rb b/app/models/advisory.rb index e41b1c665..2dc3a3110 100644 --- a/app/models/advisory.rb +++ b/app/models/advisory.rb @@ -12,6 +12,7 @@ class Advisory < ActiveRecord::Base TYPES = {'security' => 'SA', 'bugfix' => 'A'} scope :by_project, lambda {|p| where('project_id' => p.try(:id) || p)} + default_scope order('created_at DESC') def to_param advisory_id diff --git a/app/views/advisories/_feed_partial.haml b/app/views/advisories/_feed_partial.haml new file mode 100644 index 000000000..421dbd53d --- /dev/null +++ b/app/views/advisories/_feed_partial.haml @@ -0,0 +1,8 @@ +%h3= t("activerecord.attributes.advisory.description") +%p= simple_format advisory.description + +%h3= t("activerecord.attributes.advisory.references") +%p + - advisory.references.gsub(/\r| /, '').split("\n").each do |ref| + = construct_ref_link(ref) + %br diff --git a/app/views/advisories/_packages_info.html.haml b/app/views/advisories/_packages_info.html.haml index 245ba3f13..1ff955701 100644 --- a/app/views/advisories/_packages_info.html.haml +++ b/app/views/advisories/_packages_info.html.haml @@ -1,5 +1,5 @@ .packages_info_container - %h3= t('layout.advisories.affected_versions') + %h3= t('layout.advisories.affected_in') %ul.platforms - @packages_info.each_pair do |platform, projects| %li diff --git a/app/views/advisories/index.atom.builder b/app/views/advisories/index.atom.builder new file mode 100644 index 000000000..1a27b5c32 --- /dev/null +++ b/app/views/advisories/index.atom.builder @@ -0,0 +1,14 @@ +atom_feed do |feed| + feed.title(t("layout.advisories.atom_title")) + feed.updated(@advisories.first.created_at) if @advisories.length > 0 + + @advisories.each do |advisory| + feed.entry(advisory, :url => advisory_url(advisory)) do |entry| + content = raw(render(:inline => true, :partial => 'feed_partial', :locals => { :advisory => advisory })) + + entry.title("#{t("activerecord.models.advisory")} #{advisory.advisory_id}") + entry.content(content, :type => 'html') + + end + end +end diff --git a/app/views/advisories/index.html.haml b/app/views/advisories/index.html.haml index 431a3e919..3e73c2095 100644 --- a/app/views/advisories/index.html.haml +++ b/app/views/advisories/index.html.haml @@ -1,4 +1,8 @@ - set_meta_tags :title => t('layout.advisories.list_header') - render :partial => 'submenu' +%h3.fix + = t("layout.advisories.list_header") + = link_to image_tag("rss.ico", :width => '15px', :height => '15px', :class => 'atom_icon'), + APP_CONFIG['anonymous_access'] ? advisories_path(:format => 'atom') : advisories_path(:format => 'atom', :token => current_user.authentication_token) = render :partial => 'list', :object => @advisories = will_paginate @advisories diff --git a/config/locales/models/advisory.en.yml b/config/locales/models/advisory.en.yml index dd9ee79b5..dcd4b133d 100644 --- a/config/locales/models/advisory.en.yml +++ b/config/locales/models/advisory.en.yml @@ -1,10 +1,12 @@ en: layout: advisories: + atom_header: Advisories list_header: Advisories form_header: New advisory project_name: Project affected_versions: Affected versions + affected_in: Affected in ref_comment: Add links one by row no_: No new: New diff --git a/config/locales/models/advisory.ru.yml b/config/locales/models/advisory.ru.yml index f0914a12d..749b5622e 100644 --- a/config/locales/models/advisory.ru.yml +++ b/config/locales/models/advisory.ru.yml @@ -1,10 +1,12 @@ ru: layout: advisories: + atom_title: Бюллетени list_header: Бюллетени form_header: Новый бюллетень project_name: Проект affected_versions: Применен в версиях + affected_in: Применен в ref_comment: Вставляйте ссылки по одной на строку no_: Нет new: Новый From e4f62ea5925f86b09b2b1acaff4b69db70fb0600 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 20 Jun 2012 21:51:08 +0400 Subject: [PATCH 05/48] [issue #428] Added filter by advisory_id to Advisories --- app/assets/stylesheets/design/custom.scss | 22 +++++++++++++++++++ app/controllers/advisories_controller.rb | 4 +++- app/models/advisory.rb | 1 + app/views/advisories/_list.html.haml | 26 ++++++++++++++++++++++- config/locales/layout.en.yml | 1 + config/locales/layout.ru.yml | 1 + config/locales/layout/search.en.yml | 1 + config/locales/layout/search.ru.yml | 1 + config/locales/models/advisory.en.yml | 1 + config/locales/models/advisory.ru.yml | 1 + 10 files changed, 57 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/design/custom.scss b/app/assets/stylesheets/design/custom.scss index 4475219a4..9746f9b30 100644 --- a/app/assets/stylesheets/design/custom.scss +++ b/app/assets/stylesheets/design/custom.scss @@ -1094,3 +1094,25 @@ form.mass_build section.right { .packages_info_container ul.platforms { padding: 0; } + +/* remove this lines after change to backbone */ +table.tablesorter.advisories thead tr.search th { + padding: 0 5px; +} + +table.tablesorter.advisories thead tr.search th input[type='text'] { + width: 640px; +} + +table.tablesorter.advisories thead tr.search th form { + float: left; +} + +table.tablesorter.advisories thead tr.search th form.button_to { + padding: 3px 0 0 7px; +} + +table.tablesorter tr td.no_results { + text-align: center; +} +/* end */ diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 69e73cc96..c0a6dbe23 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -6,7 +6,9 @@ class AdvisoriesController < ApplicationController authorize_resource def index - @advisories = @advisories.scoped(:include => :platforms).paginate(:page => params[:page]) + @advisories = @advisories.scoped(:include => :platforms) + @advisories = @advisories.search_by_id(params[:q]) if params[:q] + @advisories = @advisories.paginate(:page => params[:page]) respond_to do |format| format.html format.atom diff --git a/app/models/advisory.rb b/app/models/advisory.rb index 2dc3a3110..facedbb91 100644 --- a/app/models/advisory.rb +++ b/app/models/advisory.rb @@ -12,6 +12,7 @@ class Advisory < ActiveRecord::Base TYPES = {'security' => 'SA', 'bugfix' => 'A'} scope :by_project, lambda {|p| where('project_id' => p.try(:id) || p)} + scope :search_by_id, lambda { |aid| where('advisory_id ILIKE ?', "%#{aid.to_s.strip}%") } default_scope order('created_at DESC') def to_param diff --git a/app/views/advisories/_list.html.haml b/app/views/advisories/_list.html.haml index b6d80ebc9..c19ff66b9 100644 --- a/app/views/advisories/_list.html.haml +++ b/app/views/advisories/_list.html.haml @@ -4,5 +4,29 @@ %th.th1= t("activerecord.attributes.advisory.advisory_id") %th.th2= t("layout.advisories.affected_versions") %th.th3= t("activerecord.attributes.advisory.description") + %tr.search + -# TODO: change filter to Backbone.js + %th{:colspan => 3, :rowspan => 1} + = form_tag advisories_path, :method => :get do |f| + = text_field_tag('q', params[:q], :placeholder => t("layout.advisories.search_by_id"), :class => params[:q].present? ? 'black' : 'gray') + %input{:type => 'submit', :value => t("layout.search.header")} + =# link_to t('layout.back'), advisories_path, :class => 'button' + = button_to t('layout.clear'), {:action => :index} , :method => :get + %tbody - = render :partial => 'list_item', :collection => list, :as => :advisory + - if list.size > 0 + = render :partial => 'list_item', :collection => list, :as => :advisory + - else + %tr.odd + %td.no_results{:colspan => 3} + = t("layout.search.no_results", :query => params[:q]) + +:javascript + $(function() { + var $search = $('tr.search > th input[type="text"]'); + $search.on('blur focus', function() { + if ($search.val() === '') { + $search.toggleClass('gray black'); + } + }); + }); diff --git a/config/locales/layout.en.yml b/config/locales/layout.en.yml index 3e1625958..d5ff40b31 100644 --- a/config/locales/layout.en.yml +++ b/config/locales/layout.en.yml @@ -14,6 +14,7 @@ en: read_access: read-only by: by + clear: Clear remove: Remove diff --git a/config/locales/layout.ru.yml b/config/locales/layout.ru.yml index ba70c945d..a9782afcd 100644 --- a/config/locales/layout.ru.yml +++ b/config/locales/layout.ru.yml @@ -14,6 +14,7 @@ ru: read_access: только чтение by: '' + clear: Очистить remove: Убрать diff --git a/config/locales/layout/search.en.yml b/config/locales/layout/search.en.yml index 91a1a7a63..177ee6cba 100644 --- a/config/locales/layout/search.en.yml +++ b/config/locales/layout/search.en.yml @@ -4,6 +4,7 @@ en: header: Search advanced: Advanced search all: Show All + no_results: Nothing found for "%{query}". types: all: All projects: Projects diff --git a/config/locales/layout/search.ru.yml b/config/locales/layout/search.ru.yml index 2850bd5bd..53df60bcd 100644 --- a/config/locales/layout/search.ru.yml +++ b/config/locales/layout/search.ru.yml @@ -4,6 +4,7 @@ ru: header: Поиск advanced: Расширенный поиск all: Показать все + no_results: По запросу "%{query}" ничего не найдено. types: all: Все projects: Проекты diff --git a/config/locales/models/advisory.en.yml b/config/locales/models/advisory.en.yml index dcd4b133d..40e2228a0 100644 --- a/config/locales/models/advisory.en.yml +++ b/config/locales/models/advisory.en.yml @@ -10,6 +10,7 @@ en: ref_comment: Add links one by row no_: No new: New + search_by_id: Search advisory by it's ID flash: advisories: diff --git a/config/locales/models/advisory.ru.yml b/config/locales/models/advisory.ru.yml index 749b5622e..1cb0e5a4b 100644 --- a/config/locales/models/advisory.ru.yml +++ b/config/locales/models/advisory.ru.yml @@ -10,6 +10,7 @@ ru: ref_comment: Вставляйте ссылки по одной на строку no_: Нет new: Новый + search_by_id: Искать бюллетень по его ID flash: advisories: From ce163f89a939553cce5f18fe5d02c44e458eccf5 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Thu, 28 Jun 2012 19:23:33 +0400 Subject: [PATCH 06/48] [refs #442] Add rep_name field. Add cancel builds ability --- app/controllers/platforms/platforms_controller.rb | 7 +++++++ app/models/mass_build.rb | 12 +++++++++--- app/views/platforms/platforms/build_all.html.haml | 5 +++++ config/locales/models/mass_build.en.yml | 3 +++ config/locales/models/mass_build.ru.yml | 3 +++ config/locales/models/platform.en.yml | 1 + config/locales/models/platform.ru.yml | 1 + config/routes.rb | 1 + .../20120622092725_add_counters_to_mass_builds.rb | 12 ++++++------ .../20120628142723_add_rep_names_to_mass_builds.rb | 5 +++++ db/schema.rb | 3 ++- 11 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20120628142723_add_rep_names_to_mass_builds.rb diff --git a/app/controllers/platforms/platforms_controller.rb b/app/controllers/platforms/platforms_controller.rb index 14058ba36..5f77f09f2 100644 --- a/app/controllers/platforms/platforms_controller.rb +++ b/app/controllers/platforms/platforms_controller.rb @@ -31,6 +31,13 @@ class Platforms::PlatformsController < Platforms::BaseController render :action => :build_all end + def cancel_mass_build + @mass_build = MassBuild.find params[:mass_build_id] + @mass_build.cancel_all + flash[:notice] = t("flash.platform.cancel_mass_build") + redirect_to mass_builds_platform_path(@mass_build.platform) + end + def failed_builds_list @mass_build = MassBuild.find params[:mass_build_id] render :text => @mass_build.generate_failed_builds_list diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index 3c13d754a..eac383a10 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -7,7 +7,7 @@ class MassBuild < ActiveRecord::Base attr_accessor :repositories, :arches - validates :platform_id, :arch_names, :name, :user_id, :repositories, :presence => true + validates :platform_id, :arch_names, :name, :user_id, :repositories, :rep_names, :presence => true validates_inclusion_of :auto_publish, :in => [true, false] after_create :build_all @@ -25,8 +25,8 @@ class MassBuild < ActiveRecord::Base super if new_record? - rep_names = Repository.where(:id => self.repositories).map(&:name).join(", ") - self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{platform.name}(#{rep_names})" + self.rep_names = Repository.where(:id => self.repositories).map(&:name).join(", ") + self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{platform.name}" self.arch_names = Arch.where(:id => self.arches).map(&:name).join(", ") end end @@ -50,4 +50,10 @@ class MassBuild < ActiveRecord::Base end report end + + def cancel_all + self.build_lists.find_each do |bl| + bl.cancel + end + end end diff --git a/app/views/platforms/platforms/build_all.html.haml b/app/views/platforms/platforms/build_all.html.haml index 67b275ac9..412613607 100644 --- a/app/views/platforms/platforms/build_all.html.haml +++ b/app/views/platforms/platforms/build_all.html.haml @@ -32,6 +32,7 @@ %th.lpadding16= t('activerecord.attributes.mass_build.name') %th.lpadding16= t("layout.mass_builds.statuses") %th.lpadding16= t("layout.mass_builds.failed_builds_list") + %th.lpadding16= t("layout.mass_builds.cancel_mass_build") %th.lpadding16= t("layout.mass_builds.extended_data") - @mass_builds.each do |mass_build| %tr @@ -43,12 +44,16 @@ = mass_build.read_attribute "#{status}_count" .both %td= link_to t("layout.mass_builds.failed_builds_list"), failed_builds_list_platforms_path(:mass_build_id => mass_build.id), :target => "_blank" + %td= link_to t("layout.mass_builds.cancel_mass_build"), cancel_mass_build_platforms_path(:mass_build_id => mass_build.id), :method => :post, :confirm => t("layout.mass_builds.cancel_confirm") %td %a.toggle_btn{:href => "#toggle_#{ mass_build.id }", :'data-target' => "#toggle_#{ mass_build.id }"}= t("layout.mass_builds.extended_data") .toggle{:id => "toggle_#{ mass_build.id }"} = t('activerecord.attributes.mass_build.arch_names') + ": " = mass_build.arch_names .both + = t('activerecord.attributes.mass_build.rep_names') + ": " + = mass_build.rep_names + .both = t('activerecord.attributes.mass_build.user') + ": " = link_to mass_build.user.fullname, mass_build.user .both diff --git a/config/locales/models/mass_build.en.yml b/config/locales/models/mass_build.en.yml index 508bc8507..39419e928 100644 --- a/config/locales/models/mass_build.en.yml +++ b/config/locales/models/mass_build.en.yml @@ -5,6 +5,8 @@ en: extended_data: Extended data failed_builds_list: Failed Builds List statuses: Statuses + cancel_mass_build: Cancel + cancel_confirm: Are you sure you want to cancel all builds? activerecord: models: mass_build: Mass Build @@ -18,3 +20,4 @@ en: user: User auto_publish: Auto Publish repositories: Repositories + rep_names: Repository names diff --git a/config/locales/models/mass_build.ru.yml b/config/locales/models/mass_build.ru.yml index b5d0fee6f..e4144b94e 100644 --- a/config/locales/models/mass_build.ru.yml +++ b/config/locales/models/mass_build.ru.yml @@ -5,6 +5,8 @@ ru: extended_data: Параметры задания failed_builds_list: Список ошибок сборок statuses: Статусы + cancel_mass_build: Отмена + cancel_confirm: Вы уверены, что хотите отменить все сборки? activerecord: models: mass_build: Массовая Сборка @@ -18,3 +20,4 @@ ru: user: Пользователь auto_publish: Авто Публикация repositories: Репозитории + rep_names: Названия репозиториев diff --git a/config/locales/models/platform.en.yml b/config/locales/models/platform.en.yml index af51cd808..cf44b6550 100644 --- a/config/locales/models/platform.en.yml +++ b/config/locales/models/platform.en.yml @@ -59,6 +59,7 @@ en: destroyed: Platform deleted build_all_success: All project build in progress build_all_error: Mass build failed + cancel_mass_build: Mass build canceled clone_success: Cloned successfully members: already_added: "%{name} is already a member of platform" diff --git a/config/locales/models/platform.ru.yml b/config/locales/models/platform.ru.yml index 387b2c0f9..6c04bbca8 100644 --- a/config/locales/models/platform.ru.yml +++ b/config/locales/models/platform.ru.yml @@ -59,6 +59,7 @@ ru: destroyed: Платформа успешно удалена build_all_success: Все проекты успешно отправлены на сборку build_all_error: Сборка не удалась! + cancel_mass_build: Массовая сборка отменена clone_success: Клонирование успешно members: already_added: "%{name} уже является участником платформы" diff --git a/config/routes.rb b/config/routes.rb index f6fec3ff7..2fe9dbf92 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -57,6 +57,7 @@ Rosa::Application.routes.draw do end collection do get :failed_builds_list + post :cancel_mass_build end get :autocomplete_user_uname, :on => :collection resources :repositories do diff --git a/db/migrate/20120622092725_add_counters_to_mass_builds.rb b/db/migrate/20120622092725_add_counters_to_mass_builds.rb index 5b0ed2e73..afed190ac 100644 --- a/db/migrate/20120622092725_add_counters_to_mass_builds.rb +++ b/db/migrate/20120622092725_add_counters_to_mass_builds.rb @@ -1,10 +1,10 @@ class AddCountersToMassBuilds < ActiveRecord::Migration def change - add_column :mass_builds, :build_lists_count, :integer, :default => 0 - add_column :mass_builds, :build_published_count, :integer, :default => 0 - add_column :mass_builds, :build_pending_count, :integer, :default => 0 - add_column :mass_builds, :build_started_count, :integer, :default => 0 - add_column :mass_builds, :build_publish_count, :integer, :default => 0 - add_column :mass_builds, :build_error_count, :integer, :default => 0 + add_column :mass_builds, :build_lists_count, :integer, :default => 0, :null => false + add_column :mass_builds, :build_published_count, :integer, :default => 0, :null => false + add_column :mass_builds, :build_pending_count, :integer, :default => 0, :null => false + add_column :mass_builds, :build_started_count, :integer, :default => 0, :null => false + add_column :mass_builds, :build_publish_count, :integer, :default => 0, :null => false + add_column :mass_builds, :build_error_count, :integer, :default => 0, :null => false end end diff --git a/db/migrate/20120628142723_add_rep_names_to_mass_builds.rb b/db/migrate/20120628142723_add_rep_names_to_mass_builds.rb new file mode 100644 index 000000000..12fdc158d --- /dev/null +++ b/db/migrate/20120628142723_add_rep_names_to_mass_builds.rb @@ -0,0 +1,5 @@ +class AddRepNamesToMassBuilds < ActiveRecord::Migration + def change + add_column :mass_builds, :rep_names, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 06ac06651..db00a3068 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120622092725) do +ActiveRecord::Schema.define(:version => 20120628142723) do create_table "activity_feeds", :force => true do |t| t.integer "user_id", :null => false @@ -210,6 +210,7 @@ ActiveRecord::Schema.define(:version => 20120622092725) do t.integer "build_started_count", :default => 0 t.integer "build_publish_count", :default => 0 t.integer "build_error_count", :default => 0 + t.string "rep_names" end create_table "platforms", :force => true do |t| From 561ebb872842afdae7e591835ba974ed01855cb8 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 29 Jun 2012 19:17:25 +0400 Subject: [PATCH 07/48] [refs #442] Add stop_build field --- app/models/mass_build.rb | 4 +-- app/models/platform.rb | 2 ++ ...629134216_add_stop_build_to_mass_builds.rb | 5 ++++ db/schema.rb | 26 +++++++++---------- 4 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 db/migrate/20120629134216_add_stop_build_to_mass_builds.rb diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index eac383a10..c588c1698 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -52,8 +52,6 @@ class MassBuild < ActiveRecord::Base end def cancel_all - self.build_lists.find_each do |bl| - bl.cancel - end + self.update_attribute(:stop_build, true) end end diff --git a/app/models/platform.rb b/app/models/platform.rb index 95cc24ba2..892a093e7 100644 --- a/app/models/platform.rb +++ b/app/models/platform.rb @@ -167,6 +167,7 @@ class Platform < ActiveRecord::Base auto_publish = opts[:auto_publish] || false user = opts[:user] mass_build_id = opts[:mass_build_id] + mass_build = MassBuild.find mass_build_id repositories.each do |rep| rep.projects.find_in_batches(:batch_size => 2) do |group| @@ -174,6 +175,7 @@ class Platform < ActiveRecord::Base group.each do |p| arches.map(&:name).each do |arch| begin + return if mass_build.reload.stop_build p.build_for(self, user, arch, auto_publish, mass_build_id) rescue RuntimeError, Exception # p.async(:build_for, self, user, arch, auto_publish, mass_build_id) # TODO need this? diff --git a/db/migrate/20120629134216_add_stop_build_to_mass_builds.rb b/db/migrate/20120629134216_add_stop_build_to_mass_builds.rb new file mode 100644 index 000000000..1e92dbc34 --- /dev/null +++ b/db/migrate/20120629134216_add_stop_build_to_mass_builds.rb @@ -0,0 +1,5 @@ +class AddStopBuildToMassBuilds < ActiveRecord::Migration + def change + add_column :mass_builds, :stop_build, :boolean, :null => false, :default => false + end +end diff --git a/db/schema.rb b/db/schema.rb index e102143c7..f2b1060c5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,14 +11,14 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120628165702) do +ActiveRecord::Schema.define(:version => 20120629134216) do create_table "activity_feeds", :force => true do |t| t.integer "user_id", :null => false t.string "kind" t.text "data" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" end create_table "advisories", :force => true do |t| @@ -211,6 +211,7 @@ ActiveRecord::Schema.define(:version => 20120628165702) do t.integer "build_publish_count", :default => 0 t.integer "build_error_count", :default => 0 t.string "rep_names" + t.boolean "stop_build", :default => false, :null => false end create_table "platforms", :force => true do |t| @@ -224,7 +225,7 @@ ActiveRecord::Schema.define(:version => 20120628165702) do t.string "owner_type" t.string "visibility", :default => "open", :null => false t.string "platform_type", :default => "main", :null => false - t.string "distrib_type", :null => false + t.string "distrib_type" end add_index "platforms", ["name"], :name => "index_platforms_on_name", :unique => true, :case_sensitive => false @@ -294,27 +295,25 @@ ActiveRecord::Schema.define(:version => 20120628165702) do t.text "description" t.string "ancestry" t.boolean "has_issues", :default => true + t.boolean "has_wiki", :default => false t.string "srpm_file_name" t.string "srpm_content_type" t.integer "srpm_file_size" t.datetime "srpm_updated_at" - t.boolean "has_wiki", :default => false t.string "default_branch", :default => "master" t.boolean "is_package", :default => true, :null => false t.integer "average_build_time", :default => 0, :null => false t.integer "build_count", :default => 0, :null => false end - add_index "projects", ["owner_id"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true - create_table "register_requests", :force => true do |t| t.string "name" t.string "email" t.string "token" t.boolean "approved", :default => false t.boolean "rejected", :default => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "interest" t.text "more" end @@ -368,6 +367,7 @@ ActiveRecord::Schema.define(:version => 20120628165702) do t.string "name" t.string "email", :default => "", :null => false t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "password_salt", :default => "", :null => false t.string "reset_password_token" t.datetime "remember_created_at" t.datetime "created_at" @@ -375,8 +375,11 @@ ActiveRecord::Schema.define(:version => 20120628165702) do t.string "uname" t.string "role" t.string "language", :default => "en" - t.datetime "reset_password_sent_at" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" t.integer "own_projects_count", :default => 0, :null => false + t.datetime "reset_password_sent_at" t.text "professional_experience" t.string "site" t.string "company" @@ -388,9 +391,6 @@ ActiveRecord::Schema.define(:version => 20120628165702) do t.integer "failed_attempts", :default => 0 t.string "unlock_token" t.datetime "locked_at" - t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" t.string "authentication_token" t.integer "build_priority", :default => 50 end From 9c07879dc2d8ac22f2bc23b478e3eb0bbd2cfdf2 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 29 Jun 2012 20:01:32 +0400 Subject: [PATCH 08/48] [refs #442] Add forgotten cancel --- app/models/mass_build.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index c588c1698..2a7afb094 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -53,5 +53,8 @@ class MassBuild < ActiveRecord::Base def cancel_all self.update_attribute(:stop_build, true) + self.build_lists.find_each do |bl| + bl.cancel + end end end From 160bdca0c8157690ec2c7a15ff1c1af505ba0985 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 29 Jun 2012 22:08:33 +0400 Subject: [PATCH 09/48] [refs #442] Add cancel_all to background. Add ownership and fix status links --- app/models/mass_build.rb | 1 + app/views/platforms/platforms/build_all.html.haml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index 2a7afb094..ff3124678 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -57,4 +57,5 @@ class MassBuild < ActiveRecord::Base bl.cancel end end + later :cancel_all, :loner => true, :queue => :clone_build end diff --git a/app/views/platforms/platforms/build_all.html.haml b/app/views/platforms/platforms/build_all.html.haml index 412613607..4a055dda9 100644 --- a/app/views/platforms/platforms/build_all.html.haml +++ b/app/views/platforms/platforms/build_all.html.haml @@ -40,7 +40,7 @@ %td= link_to mass_build.name, build_lists_path(:filter => {:mass_build_id => mass_build.id}) %td.min_width_120 - MassBuild::COUNT_STATUSES.each do |status| - = link_to t("layout.build_lists.statuses.#{status}") + ": ", build_lists_path(:filter => {:status => status, :mass_build_id => mass_build.id}) + = link_to t("layout.build_lists.statuses.#{status}") + ": ", build_lists_path(:filter => {:mass_build_id => mass_build.id, :ownership => 'index'}.merge(status != :build_lists ? {:status => status} : {})) = mass_build.read_attribute "#{status}_count" .both %td= link_to t("layout.mass_builds.failed_builds_list"), failed_builds_list_platforms_path(:mass_build_id => mass_build.id), :target => "_blank" From 8cfe262045bfbf89e5fd68f3fad1f2d7f25341b6 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 29 Jun 2012 22:31:40 +0400 Subject: [PATCH 10/48] [refs #442] Fix status filter --- app/models/build_list.rb | 4 ++++ app/views/platforms/platforms/build_all.html.haml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/build_list.rb b/app/models/build_list.rb index 14ccd466d..a02638635 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -219,6 +219,10 @@ class BuildList < ActiveRecord::Base self.class.human_status(status) end + def self.status_by_human(human) + BuildList::HUMAN_STATUSES.each { |k,v| return k if v == human } + end + def set_items(items_hash) self.items = [] diff --git a/app/views/platforms/platforms/build_all.html.haml b/app/views/platforms/platforms/build_all.html.haml index 4a055dda9..072151269 100644 --- a/app/views/platforms/platforms/build_all.html.haml +++ b/app/views/platforms/platforms/build_all.html.haml @@ -40,7 +40,7 @@ %td= link_to mass_build.name, build_lists_path(:filter => {:mass_build_id => mass_build.id}) %td.min_width_120 - MassBuild::COUNT_STATUSES.each do |status| - = link_to t("layout.build_lists.statuses.#{status}") + ": ", build_lists_path(:filter => {:mass_build_id => mass_build.id, :ownership => 'index'}.merge(status != :build_lists ? {:status => status} : {})) + = link_to t("layout.build_lists.statuses.#{status}") + ": ", build_lists_path(:filter => {:mass_build_id => mass_build.id, :ownership => 'index'}.merge(status != :build_lists ? {:status => BuildList.status_by_human(status)} : {})) = mass_build.read_attribute "#{status}_count" .both %td= link_to t("layout.mass_builds.failed_builds_list"), failed_builds_list_platforms_path(:mass_build_id => mass_build.id), :target => "_blank" From 004f603e02909edbd5711a0a106250307f062b59 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 29 Jun 2012 23:10:18 +0400 Subject: [PATCH 11/48] [refs #442] Add new actions rights. Cancel build list btn rights fix --- app/models/ability.rb | 4 ++-- app/views/projects/build_lists/_build_list.html.haml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 893b2643d..68b5d7375 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -83,7 +83,7 @@ class Ability can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform} can([:update, :members], Platform) {|platform| local_admin? platform} - can([:destroy, :members, :add_member, :remove_member, :remove_members, :build_all, :mass_builds] , Platform) {|platform| owner? platform} + can([:destroy, :members, :add_member, :remove_member, :remove_members, :build_all, :mass_builds, :cancel_mass_build, :failed_builds_list] , Platform) {|platform| owner? platform} can [:autocomplete_user_uname, :read_advisories, :advisories], Platform can [:read, :projects_list], Repository, :platform => {:visibility => 'open'} @@ -127,7 +127,7 @@ class Ability cannot [:members, :add_member, :remove_member, :remove_members], Platform, :platform_type => 'personal' cannot [:create, :update, :destroy, :clone], Product, :platform => {:platform_type => 'personal'} - cannot [:clone, :build_all, :mass_builds], Platform, :platform_type => 'personal' + cannot [:clone, :build_all, :mass_builds, :cancel_mass_build, :failed_builds_list], Platform, :platform_type => 'personal' can :create, Subscribe do |subscribe| !subscribe.subscribeable.subscribes.exists?(:user_id => user.id) diff --git a/app/views/projects/build_lists/_build_list.html.haml b/app/views/projects/build_lists/_build_list.html.haml index 9eb7b1380..abb5f43b8 100644 --- a/app/views/projects/build_lists/_build_list.html.haml +++ b/app/views/projects/build_lists/_build_list.html.haml @@ -6,5 +6,5 @@ %td= link_to build_list.project_version, "#" %td= build_list.arch.name %td= link_to build_list.user.try(:fullname), build_list.user - %td= link_to image_tag('x.png', :class => 'delete-row', :id => "delete-row#{build_list_counter}"), cancel_build_list_path(build_list), :method => :put, :confirm => t('layout.confirm') if can?(:cancel, build_list) + %td= link_to image_tag('x.png', :class => 'delete-row', :id => "delete-row#{build_list_counter}"), cancel_build_list_path(build_list), :method => :put, :confirm => t('layout.confirm') if build_list.can_cancel? and can?(:cancel, build_list) %td= build_list.updated_at From 8f9a6ee2d25011952a87cedef3808967fd7ee68a Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Mon, 2 Jul 2012 18:50:47 +0400 Subject: [PATCH 12/48] [refs #442] Change cancel btn. Move some actions to mass_builds controller. Add more ability rights --- app/controllers/mass_builds_controller.rb | 15 +++++++++++++++ app/controllers/platforms/platforms_controller.rb | 12 ------------ app/models/ability.rb | 8 ++++++-- app/models/mass_build.rb | 2 +- app/views/platforms/platforms/build_all.html.haml | 4 ++-- config/routes.rb | 10 +++++++--- 6 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 app/controllers/mass_builds_controller.rb diff --git a/app/controllers/mass_builds_controller.rb b/app/controllers/mass_builds_controller.rb new file mode 100644 index 000000000..441b04503 --- /dev/null +++ b/app/controllers/mass_builds_controller.rb @@ -0,0 +1,15 @@ +class MassBuildsController < ApplicationController + before_filter :authenticate_user! + + load_and_authorize_resource + + def cancel_mass_build + @mass_build.cancel_all + flash[:notice] = t("flash.platform.cancel_mass_build") + redirect_to mass_builds_platform_path(@mass_build.platform) + end + + def failed_builds_list + render :text => @mass_build.generate_failed_builds_list + end +end diff --git a/app/controllers/platforms/platforms_controller.rb b/app/controllers/platforms/platforms_controller.rb index 5f77f09f2..09dde90c3 100644 --- a/app/controllers/platforms/platforms_controller.rb +++ b/app/controllers/platforms/platforms_controller.rb @@ -31,18 +31,6 @@ class Platforms::PlatformsController < Platforms::BaseController render :action => :build_all end - def cancel_mass_build - @mass_build = MassBuild.find params[:mass_build_id] - @mass_build.cancel_all - flash[:notice] = t("flash.platform.cancel_mass_build") - redirect_to mass_builds_platform_path(@mass_build.platform) - end - - def failed_builds_list - @mass_build = MassBuild.find params[:mass_build_id] - render :text => @mass_build.generate_failed_builds_list - end - def index @platforms = @platforms.accessible_by(current_ability, :related).paginate(:page => params[:page], :per_page => 20) end diff --git a/app/models/ability.rb b/app/models/ability.rb index 68b5d7375..6a4642878 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -83,7 +83,9 @@ class Ability can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform} can([:update, :members], Platform) {|platform| local_admin? platform} - can([:destroy, :members, :add_member, :remove_member, :remove_members, :build_all, :mass_builds, :cancel_mass_build, :failed_builds_list] , Platform) {|platform| owner? platform} + can([:destroy, :members, :add_member, :remove_member, :remove_members, :build_all, :mass_builds] , Platform) {|platform| owner?(platform) || local_admin?(platform) } + can(:failed_builds_list, MassBuild) {|mass_build| owner?(mass_build.platform) || local_admin?(mass_build.platform) } + can(:cancel_mass_build, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build } can [:autocomplete_user_uname, :read_advisories, :advisories], Platform can [:read, :projects_list], Repository, :platform => {:visibility => 'open'} @@ -127,7 +129,9 @@ class Ability cannot [:members, :add_member, :remove_member, :remove_members], Platform, :platform_type => 'personal' cannot [:create, :update, :destroy, :clone], Product, :platform => {:platform_type => 'personal'} - cannot [:clone, :build_all, :mass_builds, :cancel_mass_build, :failed_builds_list], Platform, :platform_type => 'personal' + cannot [:clone, :build_all, :mass_builds], Platform, :platform_type => 'personal' + cannot(:failed_builds_list, MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal'} + cannot(:cancel_mass_build, MassBuild) { |mass_build| mass_build.platform.platform_type == 'personal' && mass_build.stop_build } can :create, Subscribe do |subscribe| !subscribe.subscribeable.subscribes.exists?(:user_id => user.id) diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index ff3124678..b8a2a8fde 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -57,5 +57,5 @@ class MassBuild < ActiveRecord::Base bl.cancel end end - later :cancel_all, :loner => true, :queue => :clone_build + later :cancel_all, :queue => :clone_build end diff --git a/app/views/platforms/platforms/build_all.html.haml b/app/views/platforms/platforms/build_all.html.haml index 072151269..a02cff527 100644 --- a/app/views/platforms/platforms/build_all.html.haml +++ b/app/views/platforms/platforms/build_all.html.haml @@ -43,8 +43,8 @@ = link_to t("layout.build_lists.statuses.#{status}") + ": ", build_lists_path(:filter => {:mass_build_id => mass_build.id, :ownership => 'index'}.merge(status != :build_lists ? {:status => BuildList.status_by_human(status)} : {})) = mass_build.read_attribute "#{status}_count" .both - %td= link_to t("layout.mass_builds.failed_builds_list"), failed_builds_list_platforms_path(:mass_build_id => mass_build.id), :target => "_blank" - %td= link_to t("layout.mass_builds.cancel_mass_build"), cancel_mass_build_platforms_path(:mass_build_id => mass_build.id), :method => :post, :confirm => t("layout.mass_builds.cancel_confirm") + %td= link_to t("layout.mass_builds.failed_builds_list"), failed_builds_list_platform_mass_build_path(@platform, mass_build.id), :target => "_blank" if can?(:failed_builds_list, mass_build) + %td= link_to image_tag('x.png'), cancel_mass_build_platform_mass_build_path(@platform, mass_build.id), :method => :post, :confirm => t("layout.mass_builds.cancel_confirm") if can?(:cancel_mass_build, mass_build) %td %a.toggle_btn{:href => "#toggle_#{ mass_build.id }", :'data-target' => "#toggle_#{ mass_build.id }"}= t("layout.mass_builds.extended_data") .toggle{:id => "toggle_#{ mass_build.id }"} diff --git a/config/routes.rb b/config/routes.rb index d9186bbd2..c777392b3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -55,10 +55,14 @@ Rosa::Application.routes.draw do get :mass_builds get :advisories end - collection do - get :failed_builds_list - post :cancel_mass_build + + resources :mass_builds do + member do + get :failed_builds_list + post :cancel_mass_build + end end + get :autocomplete_user_uname, :on => :collection resources :repositories do member do From c7232c53e991dce3fcec311af9b86afb05604d6a Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 3 Jul 2012 12:44:51 +0400 Subject: [PATCH 13/48] [refs #442] Fix some locales. Fix batch_size --- app/models/mass_build.rb | 2 +- config/locales/models/mass_build.en.yml | 4 ++-- config/locales/models/mass_build.ru.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index b8a2a8fde..70e3a86c7 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -53,7 +53,7 @@ class MassBuild < ActiveRecord::Base def cancel_all self.update_attribute(:stop_build, true) - self.build_lists.find_each do |bl| + self.build_lists.find_each(:batch_size => 100) do |bl| bl.cancel end end diff --git a/config/locales/models/mass_build.en.yml b/config/locales/models/mass_build.en.yml index 39419e928..734172bcc 100644 --- a/config/locales/models/mass_build.en.yml +++ b/config/locales/models/mass_build.en.yml @@ -6,7 +6,7 @@ en: failed_builds_list: Failed Builds List statuses: Statuses cancel_mass_build: Cancel - cancel_confirm: Are you sure you want to cancel all builds? + cancel_confirm: Are you sure you want to cancel mass build? activerecord: models: mass_build: Mass Build @@ -20,4 +20,4 @@ en: user: User auto_publish: Auto Publish repositories: Repositories - rep_names: Repository names + rep_names: Repositories diff --git a/config/locales/models/mass_build.ru.yml b/config/locales/models/mass_build.ru.yml index e4144b94e..5e7cc7c38 100644 --- a/config/locales/models/mass_build.ru.yml +++ b/config/locales/models/mass_build.ru.yml @@ -6,7 +6,7 @@ ru: failed_builds_list: Список ошибок сборок statuses: Статусы cancel_mass_build: Отмена - cancel_confirm: Вы уверены, что хотите отменить все сборки? + cancel_confirm: Вы уверены, что хотите отменить массовую сборку? activerecord: models: mass_build: Массовая Сборка @@ -20,4 +20,4 @@ ru: user: Пользователь auto_publish: Авто Публикация repositories: Репозитории - rep_names: Названия репозиториев + rep_names: Репозитории From dbbe4cef1f9cbf15dd2a036d2f2cf115c620fc52 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 3 Jul 2012 14:24:14 +0400 Subject: [PATCH 14/48] [refs #442] Slice counters migration on two parts --- .../20120622092725_add_counters_to_mass_builds.rb | 12 ++++++------ ...01719_add_null_false_to_mass_builds_counters.rb | 10 ++++++++++ db/schema.rb | 14 +++++++------- 3 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 db/migrate/20120703101719_add_null_false_to_mass_builds_counters.rb diff --git a/db/migrate/20120622092725_add_counters_to_mass_builds.rb b/db/migrate/20120622092725_add_counters_to_mass_builds.rb index afed190ac..5b0ed2e73 100644 --- a/db/migrate/20120622092725_add_counters_to_mass_builds.rb +++ b/db/migrate/20120622092725_add_counters_to_mass_builds.rb @@ -1,10 +1,10 @@ class AddCountersToMassBuilds < ActiveRecord::Migration def change - add_column :mass_builds, :build_lists_count, :integer, :default => 0, :null => false - add_column :mass_builds, :build_published_count, :integer, :default => 0, :null => false - add_column :mass_builds, :build_pending_count, :integer, :default => 0, :null => false - add_column :mass_builds, :build_started_count, :integer, :default => 0, :null => false - add_column :mass_builds, :build_publish_count, :integer, :default => 0, :null => false - add_column :mass_builds, :build_error_count, :integer, :default => 0, :null => false + add_column :mass_builds, :build_lists_count, :integer, :default => 0 + add_column :mass_builds, :build_published_count, :integer, :default => 0 + add_column :mass_builds, :build_pending_count, :integer, :default => 0 + add_column :mass_builds, :build_started_count, :integer, :default => 0 + add_column :mass_builds, :build_publish_count, :integer, :default => 0 + add_column :mass_builds, :build_error_count, :integer, :default => 0 end end diff --git a/db/migrate/20120703101719_add_null_false_to_mass_builds_counters.rb b/db/migrate/20120703101719_add_null_false_to_mass_builds_counters.rb new file mode 100644 index 000000000..6ae37a904 --- /dev/null +++ b/db/migrate/20120703101719_add_null_false_to_mass_builds_counters.rb @@ -0,0 +1,10 @@ +class AddNullFalseToMassBuildsCounters < ActiveRecord::Migration + def change + change_column :mass_builds, :build_lists_count, :integer, :default => 0, :null => false + change_column :mass_builds, :build_published_count, :integer, :default => 0, :null => false + change_column :mass_builds, :build_pending_count, :integer, :default => 0, :null => false + change_column :mass_builds, :build_started_count, :integer, :default => 0, :null => false + change_column :mass_builds, :build_publish_count, :integer, :default => 0, :null => false + change_column :mass_builds, :build_error_count, :integer, :default => 0, :null => false + end +end diff --git a/db/schema.rb b/db/schema.rb index f2b1060c5..ce770d06a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120629134216) do +ActiveRecord::Schema.define(:version => 20120703101719) do create_table "activity_feeds", :force => true do |t| t.integer "user_id", :null => false @@ -204,12 +204,12 @@ ActiveRecord::Schema.define(:version => 20120629134216) do t.string "arch_names" t.integer "user_id" t.boolean "auto_publish", :default => false, :null => false - t.integer "build_lists_count", :default => 0 - t.integer "build_published_count", :default => 0 - t.integer "build_pending_count", :default => 0 - t.integer "build_started_count", :default => 0 - t.integer "build_publish_count", :default => 0 - t.integer "build_error_count", :default => 0 + t.integer "build_lists_count", :default => 0, :null => false + t.integer "build_published_count", :default => 0, :null => false + t.integer "build_pending_count", :default => 0, :null => false + t.integer "build_started_count", :default => 0, :null => false + t.integer "build_publish_count", :default => 0, :null => false + t.integer "build_error_count", :default => 0, :null => false t.string "rep_names" t.boolean "stop_build", :default => false, :null => false end From 0827cf5100224a3a779d8979bfa047c1f4577920 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 3 Jul 2012 18:34:07 +0400 Subject: [PATCH 15/48] [refs #442] Add other mass builds action to mass_builds controller. Rename cancel_mass_builds action --- app/controllers/mass_builds_controller.rb | 37 ++++++++++++++++++- .../platforms/platforms_controller.rb | 24 ------------ app/models/ability.rb | 12 +++--- .../index.html.haml} | 8 ++-- app/views/platforms/base/_sidebar.html.haml | 6 +-- config/routes.rb | 6 +-- 6 files changed, 50 insertions(+), 43 deletions(-) rename app/views/{platforms/platforms/build_all.html.haml => mass_builds/index.html.haml} (88%) diff --git a/app/controllers/mass_builds_controller.rb b/app/controllers/mass_builds_controller.rb index 441b04503..8f2ec3770 100644 --- a/app/controllers/mass_builds_controller.rb +++ b/app/controllers/mass_builds_controller.rb @@ -1,12 +1,45 @@ class MassBuildsController < ApplicationController before_filter :authenticate_user! + load_and_authorize_resource :platform load_and_authorize_resource - def cancel_mass_build + skip_load_and_authorize_resource :only => [:index, :create] + skip_load_and_authorize_resource :platform, :only => [:cancel, :failed_builds_list] + skip_authorize_resource :platform, :only => [:create, :index] + + def create + mass_build = MassBuild.new( + :platform => @platform, + :user => current_user, + :repositories => params[:repositories], + :arches => params[:arches], + :auto_publish => params[:auto_publish] || false + ) + authorize! :create, mass_build + + if mass_build.save + redirect_to(platform_mass_builds_path(@platform), :notice => t("flash.platform.build_all_success")) + else + @auto_publish_selected = params[:auto_publish].present? + @mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20) + flash[:warning] = mass_build.errors.full_messages.join('. ') + flash[:error] = t("flash.platform.build_all_error") + render :action => :index + end + end + + def index + authorize! :edit, @platform + + @mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20) + @auto_publish_selected = true + end + + def cancel @mass_build.cancel_all flash[:notice] = t("flash.platform.cancel_mass_build") - redirect_to mass_builds_platform_path(@mass_build.platform) + redirect_to platform_mass_builds_path(@mass_build.platform) end def failed_builds_list diff --git a/app/controllers/platforms/platforms_controller.rb b/app/controllers/platforms/platforms_controller.rb index 09dde90c3..5a948d06e 100644 --- a/app/controllers/platforms/platforms_controller.rb +++ b/app/controllers/platforms/platforms_controller.rb @@ -7,30 +7,6 @@ class Platforms::PlatformsController < Platforms::BaseController autocomplete :user, :uname - def build_all - mass_build = MassBuild.new( - :platform => @platform, - :user => current_user, - :repositories => params[:repositories], - :arches => params[:arches], - :auto_publish => params[:auto_publish] || false - ) - if mass_build.save - redirect_to(mass_builds_platform_path(@platform), :notice => t("flash.platform.build_all_success")) - else - @auto_publish_selected = params[:auto_publish].present? - @mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20) - flash[:warning] = mass_build.errors.full_messages.join('. ') - flash[:error] = t("flash.platform.build_all_error") - end - end - - def mass_builds - @mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20) - @auto_publish_selected = true - render :action => :build_all - end - def index @platforms = @platforms.accessible_by(current_ability, :related).paginate(:page => params[:page], :per_page => 20) end diff --git a/app/models/ability.rb b/app/models/ability.rb index 6a4642878..f087ce699 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -83,9 +83,9 @@ class Ability can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform} can([:update, :members], Platform) {|platform| local_admin? platform} - can([:destroy, :members, :add_member, :remove_member, :remove_members, :build_all, :mass_builds] , Platform) {|platform| owner?(platform) || local_admin?(platform) } - can(:failed_builds_list, MassBuild) {|mass_build| owner?(mass_build.platform) || local_admin?(mass_build.platform) } - can(:cancel_mass_build, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build } + can([:destroy, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) } + can([:failed_builds_list, :create], MassBuild) {|mass_build| owner?(mass_build.platform) || local_admin?(mass_build.platform) } + can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build } can [:autocomplete_user_uname, :read_advisories, :advisories], Platform can [:read, :projects_list], Repository, :platform => {:visibility => 'open'} @@ -129,9 +129,9 @@ class Ability cannot [:members, :add_member, :remove_member, :remove_members], Platform, :platform_type => 'personal' cannot [:create, :update, :destroy, :clone], Product, :platform => {:platform_type => 'personal'} - cannot [:clone, :build_all, :mass_builds], Platform, :platform_type => 'personal' - cannot(:failed_builds_list, MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal'} - cannot(:cancel_mass_build, MassBuild) { |mass_build| mass_build.platform.platform_type == 'personal' && mass_build.stop_build } + cannot [:clone], Platform, :platform_type => 'personal' + cannot([:failed_builds_list, :create], MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal'} + cannot(:cancel, MassBuild) { |mass_build| mass_build.platform.platform_type == 'personal' && mass_build.stop_build } can :create, Subscribe do |subscribe| !subscribe.subscribeable.subscribes.exists?(:user_id => user.id) diff --git a/app/views/platforms/platforms/build_all.html.haml b/app/views/mass_builds/index.html.haml similarity index 88% rename from app/views/platforms/platforms/build_all.html.haml rename to app/views/mass_builds/index.html.haml index a02cff527..15ba91f7a 100644 --- a/app/views/platforms/platforms/build_all.html.haml +++ b/app/views/mass_builds/index.html.haml @@ -1,7 +1,7 @@ -= render 'submenu' -= render 'sidebar' += render 'platforms/base/submenu' += render 'platforms/base/sidebar' -= form_for :build, :url => build_all_platform_path(@platform), :html => { :class => 'form mass_build', :method => :post } do |f| += form_for :build, :url => platform_mass_builds_path(@platform), :html => { :class => 'form mass_build', :method => :post } do |f| %section.left %h3= t("layout.mass_builds.repositories") - @platform.repositories.each do |rep| @@ -44,7 +44,7 @@ = mass_build.read_attribute "#{status}_count" .both %td= link_to t("layout.mass_builds.failed_builds_list"), failed_builds_list_platform_mass_build_path(@platform, mass_build.id), :target => "_blank" if can?(:failed_builds_list, mass_build) - %td= link_to image_tag('x.png'), cancel_mass_build_platform_mass_build_path(@platform, mass_build.id), :method => :post, :confirm => t("layout.mass_builds.cancel_confirm") if can?(:cancel_mass_build, mass_build) + %td= link_to image_tag('x.png'), cancel_platform_mass_build_path(@platform, mass_build.id), :method => :post, :confirm => t("layout.mass_builds.cancel_confirm") if can?(:cancel, mass_build) %td %a.toggle_btn{:href => "#toggle_#{ mass_build.id }", :'data-target' => "#toggle_#{ mass_build.id }"}= t("layout.mass_builds.extended_data") .toggle{:id => "toggle_#{ mass_build.id }"} diff --git a/app/views/platforms/base/_sidebar.html.haml b/app/views/platforms/base/_sidebar.html.haml index 2ba6c1279..434e2ad43 100644 --- a/app/views/platforms/base/_sidebar.html.haml +++ b/app/views/platforms/base/_sidebar.html.haml @@ -10,9 +10,9 @@ = link_to t("layout.platforms.about"), platform_path(@platform) %li{:class => (contr == :repositories) ? 'active' : ''} = link_to t("layout.repositories.list_header"), platform_repositories_path(@platform) - - if can? :mass_builds, @platform - %li{:class => (contr == :platforms && [:mass_builds, :build_all].include?(act)) ? 'active' : ''} - = link_to t("layout.platforms.mass_build"), mass_builds_platform_path(@platform) + - if can? :edit, @platform + %li{:class => (contr == :mass_builds && [:index, :create].include?(act)) ? 'active' : ''} + = link_to t("layout.platforms.mass_build"), platform_mass_builds_path(@platform) - if can? :read, @platform.products.build %li{:class => (contr == :products) ? 'active' : ''} = link_to t("layout.products.list_header"), platform_products_path(@platform) diff --git a/config/routes.rb b/config/routes.rb index c777392b3..4370d907e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -51,15 +51,13 @@ Rosa::Application.routes.draw do delete :remove_member post :add_member post :make_clone - post :build_all - get :mass_builds get :advisories end - resources :mass_builds do + resources :mass_builds, :only => [:create, :index] do member do get :failed_builds_list - post :cancel_mass_build + post :cancel end end From 094f25c0493803f19bfd136dff3d64dacfdcddfa Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 02:52:13 +0400 Subject: [PATCH 16/48] [issue #428] Changed attaching advisory to BuildList. Removed Chosen. Added text field with incremental search. --- .../javascripts/backbone/models/advisory.js | 86 ++++++++- .../routers/build_lists_advisories_router.js | 3 +- .../views/build_list_advisories_view.js | 170 +++++++++++++----- app/assets/stylesheets/design/custom.scss | 47 ++++- app/controllers/advisories_controller.rb | 9 + app/helpers/advisories_helper.rb | 10 +- app/models/advisory.rb | 5 +- app/views/projects/build_lists/show.html.haml | 22 ++- config/locales/models/advisory.en.yml | 8 + config/locales/models/advisory.ru.yml | 8 + config/routes.rb | 4 +- vendor/assets/javascripts/vendor.js | 4 +- 12 files changed, 317 insertions(+), 59 deletions(-) diff --git a/app/assets/javascripts/backbone/models/advisory.js b/app/assets/javascripts/backbone/models/advisory.js index 654ac09c6..74e15fb21 100644 --- a/app/assets/javascripts/backbone/models/advisory.js +++ b/app/assets/javascripts/backbone/models/advisory.js @@ -3,7 +3,91 @@ Rosa.Models.Advisory = Backbone.Model.extend({ id: null, description: null, references: null, - update_type: null + update_type: null, + found: false + }, + + initialize: function() { + _.bindAll(this, 'findByAdvisoryID'); + + this.url = '/advisories'; + }, + + findByAdvisoryID: function(id, bl_type, options) { + var self = this; + + var urlError = function() { + throw new Error("A 'url' property or function must be specified"); + }; + + var typeError = function() { + throw new Error("A 'bl_type' must be 'security' or 'bugfix'"); + }; + + var idError = function() { + throw new Error("A 'id' must be a string at least 4 characters long"); + }; + + if ( (typeof(id) != "string") || (id.length < 4) ) { + idError(); + } + + if ( (bl_type == undefined) || (bl_type == null) || ((bl_type != 'security') && (bl_type != 'bugfix')) ) { + typeError(); + } + + options |= {}; + var data = _.extend({ + query: id, + bl_type: bl_type + }, {}); + + var params = _.extend({ + type: 'GET', + dataType: 'json', + beforeSend: function( xhr ) { + var token = $('meta[name="csrf-token"]').attr('content'); + if (token) xhr.setRequestHeader('X-CSRF-Token', token); + + self.trigger('search:start'); + } + }, options); + + if (!params.url) { + params.url = ((_.isFunction(this.url) ? this.url() : this.url) + '/search') || urlError(); + } + + params.data = data; + + var complete = options.complete; + params.complete = function(jqXHR, textStatus) { + //console.log(jqXHR); + + switch (jqXHR.status) { + case 200: + self.set(_.extend({ + found: true + }, JSON.parse(jqXHR.responseText)), {silent: true}); + self.trigger('search:end'); + break + + case 404: + self.set(self.defaults, {silent: true}); + self.trigger('search:end'); + break + + default: + self.set(self.defaults, {silent: true}); + self.trigger('search:failed'); + } + + if (complete) complete(jqXHR, textStatus); + } + + $.ajax(params); + + return this; + } }); diff --git a/app/assets/javascripts/backbone/routers/build_lists_advisories_router.js b/app/assets/javascripts/backbone/routers/build_lists_advisories_router.js index bf20ecfa0..950db332d 100644 --- a/app/assets/javascripts/backbone/routers/build_lists_advisories_router.js +++ b/app/assets/javascripts/backbone/routers/build_lists_advisories_router.js @@ -2,8 +2,7 @@ Rosa.Routers.BuildListsAdvisoriesRouter = Backbone.Router.extend({ routes: {}, initialize: function() { - this.advisoriesCollection = new Rosa.Collections.AdvisoriesCollection(Rosa.bootstrapedData.advisories); - this.advisoriesView = new Rosa.Views.BuildListAdvisoriesView({ collection: this.advisoriesCollection }); + this.advisoriesView = new Rosa.Views.BuildListAdvisoriesView({ model: new Rosa.Models.Advisory() }); this.advisoriesView.render(); } diff --git a/app/assets/javascripts/backbone/views/build_list_advisories_view.js b/app/assets/javascripts/backbone/views/build_list_advisories_view.js index 13cd34d56..260c8e60d 100644 --- a/app/assets/javascripts/backbone/views/build_list_advisories_view.js +++ b/app/assets/javascripts/backbone/views/build_list_advisories_view.js @@ -1,37 +1,42 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ initialize: function() { - _.bindAll(this, 'popoverTitle', 'popoverDesc', 'showAdvisory', - 'changeAdvisoryList', 'showPreview', 'showForm', 'hideAll'); - $('.chzn-select').chosen(); - this.$el = $('#advisory_block'); - this._$form = this.$('#new_advisory_form'); - this._$preview = this.$('#advisory_preview'); - this._$type_select = $('#build_list_update_type'); - this._$selector = this.$('#attach_advisory'); + _.bindAll(this, 'showAdvisory', 'showPreview', 'showForm', + 'showSearch', 'hideAll', 'displayStatus', 'processSearch'); + this.$el = $('#advisory_block'); + this._$type_select = $('#build_list_update_type'); + this._$publish_button = $('input[type="submit"][name="publish"]'); + + this._$form = this.$('#new_advisory_form'); + this._$preview = this.$('#advisory_preview'); + + this._$search = this.$('#advisory_search_block'); + this._$search_field = this.$('#advisory_search'); + this._$not_found = this.$('#advisory_search_block > .advisory_not_found'); + this._$server_error = this.$('#advisory_search_block > .server_error'); + this._$continue_input = this.$('#advisory_search_block > .continue_input'); + this._search_timer = null; + + this._$selector = this.$('#attach_advisory'); + this._header_text = this._$preview.children('h3').html(); this._$selector.on('change', this.showAdvisory); - this._$type_select.on('change', this.changeAdvisoryList); + this._$search_field.on('input keyup', this.processSearch); + var self = this; + this._$type_select.on('change', function() { + self._$search_field.trigger('input'); + }); + + this.model.on('search:start', function() { + this._$publish_button.prop({disabled: true}); + }, this); + this.model.on('search:end', this.showPreview, this); + this.model.on('search:failed', this.handleSearchError, this); }, - changeAdvisoryList: function() { - this.$('.popoverable').hide(); - this.$('.popoverable.' + this._$type_select.val()).show(); - this._$selector.val('no').trigger("liszd:updated").trigger('change'); - }, - - popoverTitle: function(el) { - console.log(el); - console.log(el.html()); - return el.html(); - }, - - popoverDesc: function(el) { - return this.collection.get(el.html()).get('popover_desc'); - }, - - showAdvisory: function(el) { + showAdvisory: function(ev) { var adv_id = this._$selector.val(); + this._$publish_button.prop({disabled: false}); switch (adv_id) { case 'no': this.hideAll(); @@ -40,21 +45,70 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ this.showForm(); break default: - this.showPreview(adv_id); + this.showSearch(); + this._$publish_button.prop({disabled: true}); } }, + processSearch: function(ev) { + if (ev.type == "keyup") { + if (ev.keyCode != 13) { + return + } else { + ev.preventDefault(); + } + } + + var TIMER_INTERVAL = 500; + + var self = this; + + var timerCallback = function() { + if (self._$search_field.val().length > 3) { + // real search + self.model.findByAdvisoryID(self._$search_field.val(), self._$type_select.val()); + } else { + // hide preview if nothing to show + if (self._$preview.is(':visible')) { + self._$preview.slideUp(); + } + self.displayStatus('found'); + } + }; + + if (this.model.get('advisory_id') == this._$search_field.val()) { + this.showPreview(); + return; + } + // timeout before real AJAX request + clearTimeout(this._search_timer); + this._search_timer = setTimeout(timerCallback, TIMER_INTERVAL); + }, + showPreview: function(id) { + this._$publish_button.prop({disabled: false}); if (this._$form.is(':visible')) { this._$form.slideUp(); } - var adv = this.collection.get(id); var prev = this._$preview; - prev.children('h3').html(this._header_text + ' ' + adv.get('advisory_id')); - prev.children('.descr').html(adv.get('description')); - prev.children('.refs').html(adv.get('references')); - if (!this._$preview.is(':visible')) { - this._$preview.slideDown(); + var adv = this.model; + if (adv.get('found')) { + this._$selector.children('option.advisory_id').val(adv.get('advisory_id')); + + prev.children('h3').html(this._header_text + ' ' + adv.get('advisory_id')); + prev.children('.descr').html(adv.get('description')); + prev.children('.refs').html(adv.get('references')); + if (!this._$preview.is(':visible')) { + this._$preview.slideDown(); + } + this.displayStatus('found'); + } else { + if (this._$preview.is(':visible')) { + this._$preview.slideUp(); + } + this._$publish_button.prop({disabled: true}); + this.displayStatus('not_found'); + this._$selector.children('option.advisory_id').val(''); } }, @@ -62,12 +116,27 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ if (this._$preview.is(':visible')) { this._$preview.slideUp(); } + if (this._$search.is(':visible')) { + this._$search.slideUp(); + } if (!this._$form.is(':visible')) { this._$form.slideDown(); } }, - hideAll: function() { + showSearch: function() { + if (this._$form.is(':visible')) { + this._$form.slideUp(); + } + if (!this._$search.is(':visible')) { + this._$search.slideDown(); + this._$search_field.trigger('input'); + } + }, + + handleSearchError: function() { + this._$publish_button.prop({disabled: true}); + this.displayStatus('error'); if (this._$preview.is(':visible')) { this._$preview.slideUp(); } @@ -76,14 +145,33 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ } }, + hideAll: function() { + if (this._$preview.is(':visible')) { + this._$preview.slideUp(); + } + if (this._$search.is(':visible')) { + this._$search.slideUp(); + } + if (this._$form.is(':visible')) { + this._$form.slideUp(); + } + }, + + displayStatus: function(st) { + var ELEMS = { + 'found': this._$continue_input, + 'not_found': this._$not_found, + 'error': this._$server_error + }; + + this._$continue_input.hide(); + this._$not_found.hide(); + this._$server_error.hide(); + + ELEMS[st].show(); + }, + render: function() { - var title = this.popoverTitle; - var description = this.popoverDesc; - this.changeAdvisoryList(); - this.$('.popoverable').popover({ - title: function() { return title($(this)); }, - content: function() { return description($(this)); } - }); this.showAdvisory(); return this; } diff --git a/app/assets/stylesheets/design/custom.scss b/app/assets/stylesheets/design/custom.scss index 9746f9b30..65fd753f7 100644 --- a/app/assets/stylesheets/design/custom.scss +++ b/app/assets/stylesheets/design/custom.scss @@ -954,10 +954,55 @@ form.mass_build input[type="checkbox"] { height: 11px; } -div#new_advisory_form, div#advisory_preview { +div#new_advisory_form, +div#advisory_preview, +div#advisory_search_block, +div#advisory_search_block div.info { display: none; } +div#advisory_search_block { + padding-bottom: 15px; +} + +p.hint_text { + color: #666666; + font-size: 0.9em; + padding: 0; +} + +div#advisory_search_block p.hint_text { + display: block; + width: 350px; +} + +div#advisory_search_block div.info { + width: 565px; + border: solid 1px; + border-radius: 5px; +} + +div#advisory_search_block div.info p { + text-align: center; + margin: 0.5em 2em 0.7em; +} + +div#advisory_search_block div.advisory_not_found { + background-color: #B7CFFF; + border-color: #6666FF; +} + +div#advisory_search_block div.server_error { + background-color: #FACFCF; + border-color: #FF7777; +} + +div#advisory_search_block div.continue_input { + background-color: #CFFACF; + border-color: #00CF00; + display: block; +} + /*=============== popovers ===============*/ .popover { diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index c0a6dbe23..3440fb3d0 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -25,4 +25,13 @@ class AdvisoriesController < ApplicationController end end + def search + puts params[:bl_type] + @advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).limit(1).first + raise ActionController::RoutingError.new('Not Found') if @advisory.nil? + respond_to do |format| + format.json { render :json => @advisory } + end + end + end diff --git a/app/helpers/advisories_helper.rb b/app/helpers/advisories_helper.rb index 62a940bb7..42634b590 100644 --- a/app/helpers/advisories_helper.rb +++ b/app/helpers/advisories_helper.rb @@ -1,9 +1,13 @@ # -*- encoding : utf-8 -*- module AdvisoriesHelper def advisories_select_options(advisories, opts = {:class => 'popoverable'}) - def_values = [[t("layout.advisories.no_"), 'no'], [t("layout.advisories.new"), 'new']] - options_for_select(def_values, def_values.first) + - options_for_select(advisories.map { |a| [a.advisory_id, :class => "#{opts[:class]} #{a.update_type}"] }) + def_values = [[t("layout.advisories.no_"), 'no'], [t("layout.advisories.new"), 'new'], [t("layout.advisories.existing"), 'existing', {:class => 'advisory_id'}]] + options_for_select(def_values, def_values.first) + end + + def advisory_id_for_hint + sprintf(Advisory::ID_STRING_TEMPLATE, :type => "{#{Advisory::TYPES.values.join(',')}}", + :year => 'YYYY', :id => 'XXXX') end def construct_ref_link(ref) diff --git a/app/models/advisory.rb b/app/models/advisory.rb index facedbb91..636ba519e 100644 --- a/app/models/advisory.rb +++ b/app/models/advisory.rb @@ -8,11 +8,12 @@ class Advisory < ActiveRecord::Base after_create :generate_advisory_id before_save :normalize_references, :if => :references_changed? - ID_TEMPLATE = 'ROSA-%s-%d:%04d' + ID_TEMPLATE = 'ROSA-%s-%d:%04d' + ID_STRING_TEMPLATE = 'ROSA-%s-%04s:%04s' TYPES = {'security' => 'SA', 'bugfix' => 'A'} - scope :by_project, lambda {|p| where('project_id' => p.try(:id) || p)} scope :search_by_id, lambda { |aid| where('advisory_id ILIKE ?', "%#{aid.to_s.strip}%") } + scope :by_update_type, lambda { |ut| where(:update_type => ut) } default_scope order('created_at DESC') def to_param diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index afdc6524f..2861b8ae7 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -32,7 +32,7 @@ .leftlist= t("activerecord.attributes.build_list.update_type") .rightlist - if @build_list.can_publish? and can?(:publish, @build_list) - = f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type), {}, :class => 'chzn-select' + = f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type) - else = @build_list.update_type .both @@ -75,9 +75,23 @@ #advisory_block .leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory") .rightlist - = select_tag :attach_advisory, advisories_select_options(@advisories), :class => 'chzn-select' + = select_tag :attach_advisory, advisories_select_options(@advisories) .both + #advisory_search_block + %h3= t("layout.advisories.search_by_id") + .leftlist= label_tag :advisory_search, t("layout.advisories.search_hint") + .rightlist + %input#advisory_search{:type => 'text'} + %p.hint_text= t("layout.advisories.advisory_id_info", :advisory_format => advisory_id_for_hint) + .both + .info.advisory_not_found + %p= t("layout.advisories.banners.advisory_not_found") + .info.server_error + %p= t("layout.advisories.banners.server_error") + .info.continue_input + %p= t("layout.advisories.banners.continue_input") + #new_advisory_form = f.fields_for @build_list.build_advisory do |f| = render :partial => 'advisories/form', :locals => {:f => f} @@ -92,11 +106,8 @@ .leftlist= t("activerecord.attributes.advisory.references") .rightlist.refs   .both - :javascript $(function() { - Rosa.bootstrapedData.advisories = #{ render 'advisories/advisories.json.jbuilder', - :advisories => @advisories }; var r = new Rosa.Routers.BuildListsAdvisoriesRouter(); }); @@ -108,7 +119,6 @@ - if @item_groups.blank? %h4.nomargin= t("layout.build_lists.no_items_data") - @item_groups.each_with_index do |group, level| - -#%h4.nomargin= "#{group} ##{level}" - group.each do |item| %h4.nomargin= "#{item.name} ##{level}" %table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"} diff --git a/config/locales/models/advisory.en.yml b/config/locales/models/advisory.en.yml index 40e2228a0..55e3befbe 100644 --- a/config/locales/models/advisory.en.yml +++ b/config/locales/models/advisory.en.yml @@ -10,7 +10,15 @@ en: ref_comment: Add links one by row no_: No new: New + existing: Existing search_by_id: Search advisory by it's ID + search_hint: Paste full AdvisoryID into text field or enter there its uniq part. + advisory_id_info: AdvisoryID is a string %{advisory_format}, where 'XXXX' (at least 4 symbols) is a uniq part. + + banners: + advisory_not_found: Couldn't find advisory with given ID for this type of Build List. + server_error: Server problem. Please try again later. + continue_input: Continue input while needed Advisory appears in preview. flash: advisories: diff --git a/config/locales/models/advisory.ru.yml b/config/locales/models/advisory.ru.yml index 1cb0e5a4b..e9a12b74d 100644 --- a/config/locales/models/advisory.ru.yml +++ b/config/locales/models/advisory.ru.yml @@ -10,7 +10,15 @@ ru: ref_comment: Вставляйте ссылки по одной на строку no_: Нет new: Новый + existing: Существующий search_by_id: Искать бюллетень по его ID + search_hint: Скопируйте в поле ввода полный AdvisoryID или введите его уникальную часть + advisory_id_info: AdvisoryID имеет формат %{advisory_format}, где 'XXXX' (минимум 4 символа) - это уникальная часть. + + banners: + advisory_not_found: Не удалось найти запрашиваемый бюллетень для сборочного листа этого типа. + server_error: Произошла ошибка сервера. Попробуйте позже. + continue_input: Продолжайте вводить ID до тех пор, пока не найдется нужный бюллетень. flash: advisories: diff --git a/config/routes.rb b/config/routes.rb index 569a0f939..385e002e0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -38,7 +38,9 @@ Rosa::Application.routes.draw do end end - resources :advisories, :only => [:index, :show] + resources :advisories, :only => [:index, :show, :search] do + get :search, :on => :collection + end scope :module => 'platforms' do resources :platforms do diff --git a/vendor/assets/javascripts/vendor.js b/vendor/assets/javascripts/vendor.js index aafbbfbed..9d833de06 100644 --- a/vendor/assets/javascripts/vendor.js +++ b/vendor/assets/javascripts/vendor.js @@ -10,8 +10,8 @@ //= require bootstrap-modal //= require bootstrap-button //= require bootstrap-dropdown -//= require bootstrap-tooltip -//= require bootstrap-popover +// require bootstrap-tooltip +// require bootstrap-popover //= require chosen.jquery // require html5shiv // require_tree . From 7515f3515d872b10200c6f1dd9674a21c640fbee Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 03:39:57 +0400 Subject: [PATCH 17/48] [issue #428] Fixed refs in advisory preview --- app/controllers/advisories_controller.rb | 2 +- app/views/advisories/_advisory.json.jbuilder | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 app/views/advisories/_advisory.json.jbuilder diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 3440fb3d0..c09cda470 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -30,7 +30,7 @@ class AdvisoriesController < ApplicationController @advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).limit(1).first raise ActionController::RoutingError.new('Not Found') if @advisory.nil? respond_to do |format| - format.json { render :json => @advisory } + format.json { render @advisory } end end diff --git a/app/views/advisories/_advisory.json.jbuilder b/app/views/advisories/_advisory.json.jbuilder new file mode 100644 index 000000000..5bf528434 --- /dev/null +++ b/app/views/advisories/_advisory.json.jbuilder @@ -0,0 +1,6 @@ +json.id advisory.id +json.advisory_id advisory.advisory_id +json.description advisory.description +json.references advisory.references.split("\n").map { |ref| construct_ref_link(ref) }.join('
      ') +json.update_type advisory.update_type + From 4eac2a232f8d20da339c7fb9464ad52a099b4c7f Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 4 Jul 2012 15:22:26 +0400 Subject: [PATCH 18/48] [refs #442] Ability rights refactor. status_by_human refactor --- app/controllers/mass_builds_controller.rb | 2 +- app/models/ability.rb | 6 ++---- app/models/build_list.rb | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/controllers/mass_builds_controller.rb b/app/controllers/mass_builds_controller.rb index 8f2ec3770..10a59a6cc 100644 --- a/app/controllers/mass_builds_controller.rb +++ b/app/controllers/mass_builds_controller.rb @@ -25,7 +25,7 @@ class MassBuildsController < ApplicationController @mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20) flash[:warning] = mass_build.errors.full_messages.join('. ') flash[:error] = t("flash.platform.build_all_error") - render :action => :index + render :index end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 252bdc476..0dfd99a08 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -84,8 +84,6 @@ class Ability can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform} can([:update, :members], Platform) {|platform| local_admin? platform} can([:destroy, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) } - can([:failed_builds_list, :create], MassBuild) {|mass_build| owner?(mass_build.platform) || local_admin?(mass_build.platform) } - can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build } can [:autocomplete_user_uname, :read_advisories, :advisories], Platform can [:read, :projects_list], Repository, :platform => {:visibility => 'open'} @@ -130,8 +128,8 @@ class Ability cannot [:create, :update, :destroy, :clone], Product, :platform => {:platform_type => 'personal'} cannot [:clone], Platform, :platform_type => 'personal' - cannot([:failed_builds_list, :create], MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal'} - cannot(:cancel, MassBuild) { |mass_build| mass_build.platform.platform_type == 'personal' && mass_build.stop_build } + can([:failed_builds_list, :create], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && (mass_build.platform.platform_type == 'main') } + can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && (mass_build.platform.platform_type == 'main')} can :create, Subscribe do |subscribe| !subscribe.subscribeable.subscribes.exists?(:user_id => user.id) diff --git a/app/models/build_list.rb b/app/models/build_list.rb index a02638635..d5f1db10b 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -220,7 +220,7 @@ class BuildList < ActiveRecord::Base end def self.status_by_human(human) - BuildList::HUMAN_STATUSES.each { |k,v| return k if v == human } + BuildList::HUMAN_STATUSES.key human end def set_items(items_hash) From 8c88e7a0da4174f52e0b817ba9df3c9e6713d3fb Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 15:42:43 +0400 Subject: [PATCH 19/48] [issue #428] Some code simplification. --- app/controllers/advisories_controller.rb | 3 +-- app/views/projects/build_lists/show.html.haml | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index c09cda470..96af28e02 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -26,8 +26,7 @@ class AdvisoriesController < ApplicationController end def search - puts params[:bl_type] - @advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).limit(1).first + @advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).first raise ActionController::RoutingError.new('Not Found') if @advisory.nil? respond_to do |format| format.json { render @advisory } diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index 2861b8ae7..267dad101 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -85,11 +85,15 @@ %input#advisory_search{:type => 'text'} %p.hint_text= t("layout.advisories.advisory_id_info", :advisory_format => advisory_id_for_hint) .both - .info.advisory_not_found + - %w(advisory_not_found server_error continue_input).each do |el| + .info{:class => el} + %p= t("layout.advisories.banners.#{el}") + + -#.info.advisory_not_found %p= t("layout.advisories.banners.advisory_not_found") - .info.server_error + -#.info.server_error %p= t("layout.advisories.banners.server_error") - .info.continue_input + -#.info.continue_input %p= t("layout.advisories.banners.continue_input") #new_advisory_form From 82612c368dd80e0ab4969aa6c4e614c14bec1802 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 4 Jul 2012 16:15:12 +0400 Subject: [PATCH 20/48] [refs #442] Move mass_builds to platforms dir --- app/controllers/{ => platforms}/mass_builds_controller.rb | 3 ++- app/views/{ => platforms}/mass_builds/index.html.haml | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename app/controllers/{ => platforms}/mass_builds_controller.rb (93%) rename app/views/{ => platforms}/mass_builds/index.html.haml (100%) diff --git a/app/controllers/mass_builds_controller.rb b/app/controllers/platforms/mass_builds_controller.rb similarity index 93% rename from app/controllers/mass_builds_controller.rb rename to app/controllers/platforms/mass_builds_controller.rb index 10a59a6cc..8564ff2ee 100644 --- a/app/controllers/mass_builds_controller.rb +++ b/app/controllers/platforms/mass_builds_controller.rb @@ -1,4 +1,5 @@ -class MassBuildsController < ApplicationController +#class MassBuildsController < ApplicationController +class Platforms::MassBuildsController < Platforms::BaseController before_filter :authenticate_user! load_and_authorize_resource :platform diff --git a/app/views/mass_builds/index.html.haml b/app/views/platforms/mass_builds/index.html.haml similarity index 100% rename from app/views/mass_builds/index.html.haml rename to app/views/platforms/mass_builds/index.html.haml From 2353a659723a206d808eb44d2a49d339ffc9cac3 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 4 Jul 2012 16:53:44 +0400 Subject: [PATCH 21/48] [refs #442] Repair schema --- db/schema.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 3726f88c8..ccc096c75 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -17,8 +17,8 @@ ActiveRecord::Schema.define(:version => 20120703101719) do t.integer "user_id", :null => false t.string "kind" t.text "data" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "advisories", :force => true do |t| @@ -225,7 +225,7 @@ ActiveRecord::Schema.define(:version => 20120703101719) do t.string "owner_type" t.string "visibility", :default => "open", :null => false t.string "platform_type", :default => "main", :null => false - t.string "distrib_type" + t.string "distrib_type", :null => false end add_index "platforms", ["name"], :name => "index_platforms_on_name", :unique => true, :case_sensitive => false From f6cf8373e53be3aa5621cd6e28eb186fe433c09e Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 17:28:43 +0400 Subject: [PATCH 22/48] [issue #428] Removed fetching of all Advisories. --- app/controllers/projects/build_lists_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index ad3c6603e..ab7ae43bb 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -70,7 +70,6 @@ class Projects::BuildListsController < Projects::BaseController def show @item_groups = @build_list.items.group_by_level - @advisories = Advisory.all end def update From 8687e343f8d65fa608fdff3253e25abe0802b1d1 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 17:55:55 +0400 Subject: [PATCH 23/48] [issue #554] Fixed tab+space json bug in AJAX. --- app/views/platforms/repositories/_proj_ajax.js.erb | 2 +- app/views/platforms/repositories/_project.js.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/platforms/repositories/_proj_ajax.js.erb b/app/views/platforms/repositories/_proj_ajax.js.erb index 9fd8431d4..3b00728de 100644 --- a/app/views/platforms/repositories/_proj_ajax.js.erb +++ b/app/views/platforms/repositories/_proj_ajax.js.erb @@ -6,7 +6,7 @@ <% @projects.each do |project| %> [ "<%=j link_to("#{project.owner.respond_to?(:uname) ? project.owner.uname : project.owner.name} / #{project.name}", project) %>", - "<%= truncate(project.description || '', :length => 60).gsub("\n", ' ').gsub("\r", ' ') %>", + "<%= truncate(project.description || '', :length => 60).gsub(/\n|\r|\t/, ' ') %>", "<%=j link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id) %>" ]<%= project == @projects.last ? '' : ',' %> <% end %> diff --git a/app/views/platforms/repositories/_project.js.erb b/app/views/platforms/repositories/_project.js.erb index fbff4878d..2dd623397 100644 --- a/app/views/platforms/repositories/_project.js.erb +++ b/app/views/platforms/repositories/_project.js.erb @@ -13,7 +13,7 @@ j(link_to("#{project.owner.respond_to?(:uname) ? project.owner.uname : project.owner.name} / #{project.name}", project)) + "
      ").html_safe %>", - "<%= truncate(project.description || '', :length => 60).gsub("\n", ' ').gsub("\r", ' ') %>", + "<%= truncate(project.description || '', :length => 60).gsub(/\n|\r|\t/, ' ') %>", "<%= if can? :remove_project, @repository j(link_to(' '.html_safe, From 07372dd1a327cfe8568c326c5f7a26fbf9da380f Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 4 Jul 2012 18:09:59 +0400 Subject: [PATCH 24/48] [refs #442] Fix mass_builds link --- app/views/projects/build_lists/_build_list.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/build_lists/_build_list.html.haml b/app/views/projects/build_lists/_build_list.html.haml index abb5f43b8..a7fa19354 100644 --- a/app/views/projects/build_lists/_build_list.html.haml +++ b/app/views/projects/build_lists/_build_list.html.haml @@ -1,6 +1,6 @@ %tr{:id => "row#{build_list_counter}", :class => "#{build_list_status_color(build_list.status)}"} %td= link_to (build_list.bs_id.present? ? build_list.bs_id : t("layout.build_lists.bs_id_not_set")), build_list - %td= build_list.mass_build_id ? link_to(build_list.mass_build.name, mass_builds_platform_path(build_list.save_to_platform)) : "" + %td= build_list.mass_build_id ? link_to(build_list.mass_build.name, platform_mass_builds_path(build_list.save_to_platform)) : "" %td= build_list.human_status %td= link_to build_list.project.name, build_list.project %td= link_to build_list.project_version, "#" From 02ae717af9677f2d5ae1def198818dd52ed5e553 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 18:57:23 +0400 Subject: [PATCH 25/48] [issue #428] Fixed bug with compact! and uniq! --- app/controllers/advisories_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 96af28e02..90f46ee25 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -20,7 +20,8 @@ class AdvisoriesController < ApplicationController @advisory.build_lists.find_in_batches(:include => [:save_to_platform, :packages, :project]) do |batch| batch.each do |build_list| h = { build_list.project => build_list.packages } - @packages_info[build_list.save_to_platform].merge!(h) { |pr, old, new| (old + new).compact!.uniq! } + # FIXME Maybe memory leak... + @packages_info[build_list.save_to_platform].merge!(h) { |pr, old, new| (old + new).compact.uniq } end end end From 7a3833503764c3411cccb8b053740565bda7b442 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 19:27:20 +0400 Subject: [PATCH 26/48] [issue #527] Fixed group members list --- app/views/groups/members/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/groups/members/index.html.haml b/app/views/groups/members/index.html.haml index 0fb2ab5f0..622a9a13e 100644 --- a/app/views/groups/members/index.html.haml +++ b/app/views/groups/members/index.html.haml @@ -15,7 +15,7 @@ %span#niceCheckbox1.niceCheck-main= check_box_tag "user_remove[#{user.id}][]" %td .img= image_tag avatar_url(user) - .forimg= link_to user.name, user_path(user) + .forimg= link_to "#{user.uname} (#{user.name})", user_path(user) - Relation::ROLES.each_with_index do |role, i| %td .radio= radio_button_tag "user[#{user.id}]", role, ((parent.actors.exists? :actor_id => user.id, :actor_type => 'User', :role => role) ? :checked : nil), :class => 'niceRadio' From a2d35d25385e21cf897acf1b44e32d7f98e19c8e Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 19:53:18 +0400 Subject: [PATCH 27/48] [issue #527] Use User#fullname instead of string. --- app/models/user.rb | 2 +- app/views/groups/members/index.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 7bbd42965..ede3710e6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -73,7 +73,7 @@ class User < ActiveRecord::Base end def fullname - return "#{uname} (#{name})" + return name.present? && name.length > 0 ? "#{uname} (#{name})" : uname end def user_appeal diff --git a/app/views/groups/members/index.html.haml b/app/views/groups/members/index.html.haml index 622a9a13e..9f80db048 100644 --- a/app/views/groups/members/index.html.haml +++ b/app/views/groups/members/index.html.haml @@ -15,7 +15,7 @@ %span#niceCheckbox1.niceCheck-main= check_box_tag "user_remove[#{user.id}][]" %td .img= image_tag avatar_url(user) - .forimg= link_to "#{user.uname} (#{user.name})", user_path(user) + .forimg= link_to user.fullname, user_path(user) - Relation::ROLES.each_with_index do |role, i| %td .radio= radio_button_tag "user[#{user.id}]", role, ((parent.actors.exists? :actor_id => user.id, :actor_type => 'User', :role => role) ? :checked : nil), :class => 'niceRadio' From 8c9cca39ef70da5fdf8b7075bccc3508a6a23ee5 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 20:52:22 +0400 Subject: [PATCH 28/48] [issue #428] Attempt to fix packages listing --- app/controllers/advisories_controller.rb | 15 ++++++++++++--- app/views/advisories/_packages_info.html.haml | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 90f46ee25..838ef7e9b 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -19,9 +19,18 @@ class AdvisoriesController < ApplicationController @packages_info = Hash.new { |h, k| h[k] = {} } @advisory.build_lists.find_in_batches(:include => [:save_to_platform, :packages, :project]) do |batch| batch.each do |build_list| - h = { build_list.project => build_list.packages } - # FIXME Maybe memory leak... - @packages_info[build_list.save_to_platform].merge!(h) { |pr, old, new| (old + new).compact.uniq } + tmp = build_list.packages.inject({:srpm => nil, :rpm => []}) do |h, p| + p.package_type == 'binary' ? h[:rpm] << p : h[:srpm] = p + h + end + h = { build_list.project => tmp } + @packages_info[build_list.save_to_platform].merge!(h) do |pr, old, new| + {:srpm => new[:srpm], :rpm => old[:rpm].concat(new[:rpm]).uniq} + end + +# h = { build_list.project => build_list.packages } +# # FIXME Maybe memory leak... +# @packages_info[build_list.save_to_platform].merge!(h) { |pr, old, new| (old + new).compact.uniq } end end end diff --git a/app/views/advisories/_packages_info.html.haml b/app/views/advisories/_packages_info.html.haml index 1ff955701..e552b30ac 100644 --- a/app/views/advisories/_packages_info.html.haml +++ b/app/views/advisories/_packages_info.html.haml @@ -12,9 +12,9 @@ %li %p= "SRPM:" %ul - %li= project.srpm_file_name + %li= packages[:srpm].fullname %li %p= "RPM:" %ul - - packages.each do |package| + - packages[:rpm].each do |package| %li= package.fullname From 1c4c91df5c565d70014a737bf43b4f5cb4f45d8d Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 21:38:45 +0400 Subject: [PATCH 29/48] [issue #428] Fixed attaching projects to advisory. --- app/controllers/projects/build_lists_controller.rb | 1 + app/views/advisories/show.html.haml | 2 +- config/locales/models/advisory.en.yml | 1 + config/locales/models/advisory.ru.yml | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index ab7ae43bb..cad13543d 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -186,6 +186,7 @@ class Projects::BuildListsController < Projects::BaseController redirect_to :back, :notice => t('layout.build_lists.publish_fail') and return end a.platforms << @build_list.save_to_platform unless a.platforms.include? @build_list.save_to_platform + a.projects << @build_list.project unless a.projects.include? @build_list.project @build_list.advisory = a unless a.save redirect_to :back, :notice => t('layout.build_lists.publish_fail') and return diff --git a/app/views/advisories/show.html.haml b/app/views/advisories/show.html.haml index ba1886964..c9dbdb5c9 100644 --- a/app/views/advisories/show.html.haml +++ b/app/views/advisories/show.html.haml @@ -3,7 +3,7 @@ %h3= "#{t("activerecord.models.advisory")} #{@advisory.advisory_id}".html_safe -.leftlist= "#{t("layout.advisories.project_name")}:".html_safe +.leftlist= "#{t("layout.advisories.project_names")}:".html_safe .rightlist - @advisory.projects.each do |project| = link_to project.name, project_path(project) diff --git a/config/locales/models/advisory.en.yml b/config/locales/models/advisory.en.yml index 55e3befbe..9de97d545 100644 --- a/config/locales/models/advisory.en.yml +++ b/config/locales/models/advisory.en.yml @@ -5,6 +5,7 @@ en: list_header: Advisories form_header: New advisory project_name: Project + project_names: Projects affected_versions: Affected versions affected_in: Affected in ref_comment: Add links one by row diff --git a/config/locales/models/advisory.ru.yml b/config/locales/models/advisory.ru.yml index e9a12b74d..a61aa6102 100644 --- a/config/locales/models/advisory.ru.yml +++ b/config/locales/models/advisory.ru.yml @@ -5,6 +5,7 @@ ru: list_header: Бюллетени form_header: Новый бюллетень project_name: Проект + project_names: Проекты affected_versions: Применен в версиях affected_in: Применен в ref_comment: Вставляйте ссылки по одной на строку From db66c7b3e17a6928be3707e3cd8420a5b30a13a3 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 22:01:06 +0400 Subject: [PATCH 30/48] [issue #428] Attempt to fix duplication in packages list --- app/controllers/advisories_controller.rb | 2 +- app/views/advisories/_packages_info.html.haml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 838ef7e9b..8c7e6f0c4 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -20,7 +20,7 @@ class AdvisoriesController < ApplicationController @advisory.build_lists.find_in_batches(:include => [:save_to_platform, :packages, :project]) do |batch| batch.each do |build_list| tmp = build_list.packages.inject({:srpm => nil, :rpm => []}) do |h, p| - p.package_type == 'binary' ? h[:rpm] << p : h[:srpm] = p + p.package_type == 'binary' ? h[:rpm] << p.fullname : h[:srpm] = p.fullname h end h = { build_list.project => tmp } diff --git a/app/views/advisories/_packages_info.html.haml b/app/views/advisories/_packages_info.html.haml index e552b30ac..2cc177c18 100644 --- a/app/views/advisories/_packages_info.html.haml +++ b/app/views/advisories/_packages_info.html.haml @@ -12,9 +12,9 @@ %li %p= "SRPM:" %ul - %li= packages[:srpm].fullname + %li= packages[:srpm] %li %p= "RPM:" %ul - packages[:rpm].each do |package| - %li= package.fullname + %li= package From fa5deed42f5cd6c48e583b3ba8c59569d6779925 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 22:32:10 +0400 Subject: [PATCH 31/48] [issue #428] Added BuildLists list to Advisory#show --- app/views/advisories/show.html.haml | 9 ++++++--- config/locales/models/advisory.en.yml | 1 + config/locales/models/advisory.ru.yml | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/views/advisories/show.html.haml b/app/views/advisories/show.html.haml index c9dbdb5c9..551b628bf 100644 --- a/app/views/advisories/show.html.haml +++ b/app/views/advisories/show.html.haml @@ -5,9 +5,7 @@ .leftlist= "#{t("layout.advisories.project_names")}:".html_safe .rightlist - - @advisory.projects.each do |project| - = link_to project.name, project_path(project) - %br + = raw @advisory.projects.map{ |p| link_to p.name, project_path(p) }.join(', ') .both .leftlist= "#{t("activerecord.attributes.advisory.created_at")}:".html_safe @@ -36,6 +34,11 @@ %br .both +.leftlist= "#{t("layout.advisories.build_lists")}:".html_safe +.rightlist + = raw @advisory.build_lists.map{ |bl| link_to bl.id, build_list_path(bl) }.join(', ') +.both + = render :partial => 'packages_info' :javascript diff --git a/config/locales/models/advisory.en.yml b/config/locales/models/advisory.en.yml index 9de97d545..30ff105cd 100644 --- a/config/locales/models/advisory.en.yml +++ b/config/locales/models/advisory.en.yml @@ -6,6 +6,7 @@ en: form_header: New advisory project_name: Project project_names: Projects + build_lists: Build Lists affected_versions: Affected versions affected_in: Affected in ref_comment: Add links one by row diff --git a/config/locales/models/advisory.ru.yml b/config/locales/models/advisory.ru.yml index a61aa6102..8aec17cd6 100644 --- a/config/locales/models/advisory.ru.yml +++ b/config/locales/models/advisory.ru.yml @@ -6,6 +6,7 @@ ru: form_header: Новый бюллетень project_name: Проект project_names: Проекты + build_lists: Сборочные листы affected_versions: Применен в версиях affected_in: Применен в ref_comment: Вставляйте ссылки по одной на строку From 1cfd1975d5f228789b0da3f51fce9b386fd82f5d Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Wed, 4 Jul 2012 22:52:09 +0400 Subject: [PATCH 32/48] [issue #428] Projects shows with owner name. --- app/views/advisories/show.html.haml | 2 +- lib/modules/models/owner.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/advisories/show.html.haml b/app/views/advisories/show.html.haml index 551b628bf..422ccd0ec 100644 --- a/app/views/advisories/show.html.haml +++ b/app/views/advisories/show.html.haml @@ -5,7 +5,7 @@ .leftlist= "#{t("layout.advisories.project_names")}:".html_safe .rightlist - = raw @advisory.projects.map{ |p| link_to p.name, project_path(p) }.join(', ') + = raw @advisory.projects.map{ |p| link_to p.name_with_owner, project_path(p) }.join(', ') .both .leftlist= "#{t("activerecord.attributes.advisory.created_at")}:".html_safe diff --git a/lib/modules/models/owner.rb b/lib/modules/models/owner.rb index b92a067be..218e29f29 100644 --- a/lib/modules/models/owner.rb +++ b/lib/modules/models/owner.rb @@ -10,6 +10,14 @@ module Modules module ClassMethods end + + module InstanceMethods + + def name_with_owner + "#{owner.uname}/#{self.name}" + end + + end end end end From 69d48f000edb87002440025534cf7007e86f0970 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Thu, 5 Jul 2012 11:36:18 +0400 Subject: [PATCH 33/48] [issue #428] Removed commented code. --- app/controllers/advisories_controller.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 8c7e6f0c4..ee1adf6f2 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -27,10 +27,6 @@ class AdvisoriesController < ApplicationController @packages_info[build_list.save_to_platform].merge!(h) do |pr, old, new| {:srpm => new[:srpm], :rpm => old[:rpm].concat(new[:rpm]).uniq} end - -# h = { build_list.project => build_list.packages } -# # FIXME Maybe memory leak... -# @packages_info[build_list.save_to_platform].merge!(h) { |pr, old, new| (old + new).compact.uniq } end end end From 3c8b77027ec9a27412e95826f8089e9573bf64fc Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 6 Jul 2012 03:05:47 +0400 Subject: [PATCH 34/48] [issue #428] Allowed any update_types when build for released platform. --- .../views/build_list_advisories_view.js | 54 +++++++++++++++---- app/assets/javascripts/extra/build_list.js | 4 +- app/assets/stylesheets/design/custom.scss | 2 +- .../projects/build_lists_controller.rb | 9 +++- app/helpers/build_lists_helper.rb | 11 ++++ app/models/advisory.rb | 1 + app/models/build_list.rb | 4 +- app/views/projects/build_lists/show.html.haml | 3 +- config/locales/models/advisory.en.yml | 1 + config/locales/models/advisory.ru.yml | 1 + 10 files changed, 74 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/backbone/views/build_list_advisories_view.js b/app/assets/javascripts/backbone/views/build_list_advisories_view.js index 260c8e60d..0b950150f 100644 --- a/app/assets/javascripts/backbone/views/build_list_advisories_view.js +++ b/app/assets/javascripts/backbone/views/build_list_advisories_view.js @@ -1,7 +1,9 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ initialize: function() { _.bindAll(this, 'showAdvisory', 'showPreview', 'showForm', - 'showSearch', 'hideAll', 'displayStatus', 'processSearch'); + 'showSearch', 'hideAll', 'displayStatus', 'processSearch', + 'showInTypeSelect', 'typeSelectChange'); + this.$el = $('#advisory_block'); this._$type_select = $('#build_list_update_type'); this._$publish_button = $('input[type="submit"][name="publish"]'); @@ -18,14 +20,16 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ this._$selector = this.$('#attach_advisory'); - this._header_text = this._$preview.children('h3').html(); + this._state_vars = {}; + this._state_vars = _.extend({ + checked_update_type: this._$type_select.val(), + header_text: this._$preview.children('h3').html() + }, this.state_vars); this._$selector.on('change', this.showAdvisory); this._$search_field.on('input keyup', this.processSearch); - var self = this; - this._$type_select.on('change', function() { - self._$search_field.trigger('input'); - }); + + this._$type_select.on('change', this.typeSelectChange); this.model.on('search:start', function() { this._$publish_button.prop({disabled: true}); @@ -35,21 +39,53 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ }, showAdvisory: function(ev) { - var adv_id = this._$selector.val(); this._$publish_button.prop({disabled: false}); - switch (adv_id) { + switch (this._$selector.val()) { case 'no': this.hideAll(); + this.showInTypeSelect('all'); break case 'new': this.showForm(); + this.showInTypeSelect('advisoriable'); break default: this.showSearch(); + this.showInTypeSelect('advisoriable'); this._$publish_button.prop({disabled: true}); } }, + typeSelectChange: function(ev) { + switch (this._$selector.val()) { + case 'no': + this._state_vars.checked_update_type = this._$selector.val(); + break + case 'new': + break + default: + this._$search_field.trigger('input'); + } + }, + + showInTypeSelect: function(type) { + var children = this._$type_select.children('option'); + if (type != 'all') { + var visible_ch = children.filter('.' + type); + var sel = children.filter(':selected'); + + children.prop('disabled', true); + visible_ch.prop('disabled', false); + if (sel.prop('disabled')) { + sel.prop('selected', false); + visible_ch.first().prop('selected', true); + } + } else { + children.prop('disabled', false).prop('selected', false); + children.filter('option[value="' + this._state_vars.checked_update_type + '"]').prop('selected', true); + } + }, + processSearch: function(ev) { if (ev.type == "keyup") { if (ev.keyCode != 13) { @@ -95,7 +131,7 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({ if (adv.get('found')) { this._$selector.children('option.advisory_id').val(adv.get('advisory_id')); - prev.children('h3').html(this._header_text + ' ' + adv.get('advisory_id')); + prev.children('h3').html(this._state_vars.header_text + ' ' + adv.get('advisory_id')); prev.children('.descr').html(adv.get('description')); prev.children('.refs').html(adv.get('references')); if (!this._$preview.is(':visible')) { diff --git a/app/assets/javascripts/extra/build_list.js b/app/assets/javascripts/extra/build_list.js index 654fc0d04..6402c9e5d 100644 --- a/app/assets/javascripts/extra/build_list.js +++ b/app/assets/javascripts/extra/build_list.js @@ -9,10 +9,10 @@ $(document).ready(function() { if ($(this).val() == platform_id) { if ($(this).attr('data-released') === '1') { $('#build_list_auto_publish').removeAttr('checked').attr('disabled', 'disabled'); - disableUpdateTypes(); + //disableUpdateTypes(); } else { $('#build_list_auto_publish').removeAttr('disabled').attr('checked', 'checked'); - enableUpdateTypes(); + //enableUpdateTypes(); } $(this).attr('checked', 'checked').removeAttr('disabled').trigger('change'); diff --git a/app/assets/stylesheets/design/custom.scss b/app/assets/stylesheets/design/custom.scss index 7238a04d4..ccf97e3d0 100644 --- a/app/assets/stylesheets/design/custom.scss +++ b/app/assets/stylesheets/design/custom.scss @@ -971,7 +971,7 @@ p.hint_text { padding: 0; } -div#advisory_search_block p.hint_text { +div#advisory_block p.hint_text { display: block; width: 350px; } diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index cad13543d..7893f98c0 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -170,11 +170,16 @@ class Projects::BuildListsController < Projects::BaseController @build_list.update_type = params[:build_list][:update_type] if params[:build_list][:update_type].present? if params[:attach_advisory].present? and params[:attach_advisory] != 'no' and !@build_list.advisory + + unless @build_list.update_type.in? BuildList::RELEASE_UPDATE_TYPES + redirect_to :back, :notice => t('lyout.build_lists.publish_fail') and return + end + if params[:attach_advisory] == 'new' # create new advisory unless @build_list.build_advisory(params[:build_list][:advisory]) do |a| a.update_type = @build_list.update_type - a.project = @build_list.project + a.projects << @build_list.project a.platforms << @build_list.save_to_platform unless a.platforms.include? @build_list.save_to_platform end.save redirect_to :back, :notice => t('layout.build_lists.publish_fail') and return @@ -192,7 +197,9 @@ class Projects::BuildListsController < Projects::BaseController redirect_to :back, :notice => t('layout.build_lists.publish_fail') and return end end + end + if @build_list.save and @build_list.now_publish redirect_to :back, :notice => t('layout.build_lists.publish_success') else diff --git a/app/helpers/build_lists_helper.rb b/app/helpers/build_lists_helper.rb index dde82260e..2b9d66882 100644 --- a/app/helpers/build_lists_helper.rb +++ b/app/helpers/build_lists_helper.rb @@ -23,4 +23,15 @@ module BuildListsHelper '' end + + def build_list_classified_update_types + advisoriable = BuildList::RELEASE_UPDATE_TYPES.map do |el| + [el, {:class => 'advisoriable'}] + end + nonadvisoriable = (BuildList::UPDATE_TYPES - BuildList::RELEASE_UPDATE_TYPES).map do |el| + [el, {:class => 'nonadvisoriable'}] + end + + return advisoriable + nonadvisoriable + end end diff --git a/app/models/advisory.rb b/app/models/advisory.rb index 636ba519e..4410ba621 100644 --- a/app/models/advisory.rb +++ b/app/models/advisory.rb @@ -4,6 +4,7 @@ class Advisory < ActiveRecord::Base has_many :build_lists validates :description, :update_type, :presence => true + validates :update_type, :inclusion => BuildList::RELEASE_UPDATE_TYPES after_create :generate_advisory_id before_save :normalize_references, :if => :references_changed? diff --git a/app/models/build_list.rb b/app/models/build_list.rb index d5f1db10b..6c60b6d89 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -16,9 +16,9 @@ class BuildList < ActiveRecord::Base validates :project_id, :project_version, :arch, :include_repos, :presence => true validates_numericality_of :priority, :greater_than_or_equal_to => 0 validates :update_type, :inclusion => UPDATE_TYPES, - :unless => Proc.new { |b| b.save_to_platform.released } + :unless => Proc.new { |b| b.advisory.present? } validates :update_type, :inclusion => {:in => RELEASE_UPDATE_TYPES, :message => I18n.t('flash.build_list.frozen_platform')}, - :if => Proc.new { |b| b.save_to_platform.released && b.mass_build_id.nil?} + :if => Proc.new { |b| b.advisory.present? } validate lambda { errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_platform')) if save_to_platform.platform_type == 'main' && save_to_platform_id != build_for_platform_id } diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index 267dad101..beb41fa11 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -32,7 +32,7 @@ .leftlist= t("activerecord.attributes.build_list.update_type") .rightlist - if @build_list.can_publish? and can?(:publish, @build_list) - = f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type) + = f.select :update_type, options_for_select(build_list_classified_update_types, @build_list.update_type) - else = @build_list.update_type .both @@ -76,6 +76,7 @@ .leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory") .rightlist = select_tag :attach_advisory, advisories_select_options(@advisories) + %p.hint_text= t("layout.advisories.publication_info", :update_types => BuildList::RELEASE_UPDATE_TYPES.join(', ')) .both #advisory_search_block diff --git a/config/locales/models/advisory.en.yml b/config/locales/models/advisory.en.yml index 30ff105cd..fe3e1a16f 100644 --- a/config/locales/models/advisory.en.yml +++ b/config/locales/models/advisory.en.yml @@ -16,6 +16,7 @@ en: search_by_id: Search advisory by it's ID search_hint: Paste full AdvisoryID into text field or enter there its uniq part. advisory_id_info: AdvisoryID is a string %{advisory_format}, where 'XXXX' (at least 4 symbols) is a uniq part. + publication_info: Advisory might be applied only to Build Lists with [%{update_types}] update types. banners: advisory_not_found: Couldn't find advisory with given ID for this type of Build List. diff --git a/config/locales/models/advisory.ru.yml b/config/locales/models/advisory.ru.yml index 8aec17cd6..bf153d7a9 100644 --- a/config/locales/models/advisory.ru.yml +++ b/config/locales/models/advisory.ru.yml @@ -16,6 +16,7 @@ ru: search_by_id: Искать бюллетень по его ID search_hint: Скопируйте в поле ввода полный AdvisoryID или введите его уникальную часть advisory_id_info: AdvisoryID имеет формат %{advisory_format}, где 'XXXX' (минимум 4 символа) - это уникальная часть. + publication_info: Бюллетень может быть присоединен только к сборочному листу с типами обновления %{update_types}. banners: advisory_not_found: Не удалось найти запрашиваемый бюллетень для сборочного листа этого типа. From 49927728cd1d6f6985dd578f6df45e767f6c0027 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 6 Jul 2012 17:31:18 +0400 Subject: [PATCH 35/48] [issue #428] Fetching packages moved to particular method. --- app/controllers/advisories_controller.rb | 26 ++++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index ee1adf6f2..6923cd878 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -5,6 +5,8 @@ class AdvisoriesController < ApplicationController load_resource :find_by => :advisory_id authorize_resource + before_filter :fetch_packages_info + def index @advisories = @advisories.scoped(:include => :platforms) @advisories = @advisories.search_by_id(params[:q]) if params[:q] @@ -16,7 +18,21 @@ class AdvisoriesController < ApplicationController end def show - @packages_info = Hash.new { |h, k| h[k] = {} } + end + + def search + @advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).first + raise ActionController::RoutingError.new('Not Found') if @advisory.nil? + respond_to do |format| + format.json { render @advisory } + end + end + + protected + + # this method fetches and structurize packages attached to current advisory. + def fetch_packages_info + @packages_info = Hash.new { |h, k| h[k] = {} } # maaagic, it's maaagic ;) @advisory.build_lists.find_in_batches(:include => [:save_to_platform, :packages, :project]) do |batch| batch.each do |build_list| tmp = build_list.packages.inject({:srpm => nil, :rpm => []}) do |h, p| @@ -31,12 +47,4 @@ class AdvisoriesController < ApplicationController end end - def search - @advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).first - raise ActionController::RoutingError.new('Not Found') if @advisory.nil? - respond_to do |format| - format.json { render @advisory } - end - end - end From c1a90872db4ce25f8f7d7d277ecdc80e6ae9590a Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Fri, 6 Jul 2012 18:23:49 +0400 Subject: [PATCH 36/48] [issue #428] Fixed bug with before_filter in advisory --- app/controllers/advisories_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/advisories_controller.rb b/app/controllers/advisories_controller.rb index 6923cd878..9bbf15f6c 100644 --- a/app/controllers/advisories_controller.rb +++ b/app/controllers/advisories_controller.rb @@ -5,7 +5,7 @@ class AdvisoriesController < ApplicationController load_resource :find_by => :advisory_id authorize_resource - before_filter :fetch_packages_info + before_filter :fetch_packages_info, :only => [:show] def index @advisories = @advisories.scoped(:include => :platforms) From 1f2a3b82d307efb123cd7b59b85bfbb7690bb0a8 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Fri, 6 Jul 2012 20:36:44 +0400 Subject: [PATCH 37/48] [refs #442] Add tests for mass builds and attr_accessible. Fix ability --- app/models/ability.rb | 8 +- app/models/mass_build.rb | 1 + .../platforms/mass_builds_controller_spec.rb | 163 ++++++++++++++++++ spec/factories/mass_build.rb | 12 ++ 4 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 spec/controllers/platforms/mass_builds_controller_spec.rb create mode 100644 spec/factories/mass_build.rb diff --git a/app/models/ability.rb b/app/models/ability.rb index 0dfd99a08..3fe541d55 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -86,6 +86,9 @@ class Ability can([:destroy, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) } can [:autocomplete_user_uname, :read_advisories, :advisories], Platform + can([:failed_builds_list, :create], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && (mass_build.platform.platform_type == 'main') } + can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && (mass_build.platform.platform_type == 'main')} + can [:read, :projects_list], Repository, :platform => {:visibility => 'open'} can [:read, :projects_list], Repository, :platform => {:owner_type => 'User', :owner_id => user.id} can [:read, :projects_list], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} @@ -128,8 +131,9 @@ class Ability cannot [:create, :update, :destroy, :clone], Product, :platform => {:platform_type => 'personal'} cannot [:clone], Platform, :platform_type => 'personal' - can([:failed_builds_list, :create], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && (mass_build.platform.platform_type == 'main') } - can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && (mass_build.platform.platform_type == 'main')} + + cannot([:failed_builds_list, :create], MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal'} + cannot(:cancel, MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal' || mass_build.stop_build} can :create, Subscribe do |subscribe| !subscribe.subscribeable.subscribes.exists?(:user_id => user.id) diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index 70e3a86c7..4fb14758e 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -6,6 +6,7 @@ class MassBuild < ActiveRecord::Base scope :by_platform, lambda { |platform| where(:platform_id => platform.id) } attr_accessor :repositories, :arches + attr_accessible :platform, :platform_id, :user, :user_id, :repositories, :arches, :auto_publish validates :platform_id, :arch_names, :name, :user_id, :repositories, :rep_names, :presence => true validates_inclusion_of :auto_publish, :in => [true, false] diff --git a/spec/controllers/platforms/mass_builds_controller_spec.rb b/spec/controllers/platforms/mass_builds_controller_spec.rb new file mode 100644 index 000000000..14d37f38c --- /dev/null +++ b/spec/controllers/platforms/mass_builds_controller_spec.rb @@ -0,0 +1,163 @@ +# -*- encoding : utf-8 -*- +require 'spec_helper' + +shared_examples_for 'mass_build platform owner' do + it 'should be able to perform index action' do + get :index, :platform_id => @platform + response.should render_template(:index) + end + + it 'should be able to perform create action' do + post :create, @create_params + response.should redirect_to(platform_mass_builds_path(@platform)) + end + + it 'should be able to perform cancel action' do + post :cancel, :platform_id => @platform, :id => @mass_build + response.should redirect_to(platform_mass_builds_path(@platform)) + end + + it 'should change stop_build on cancel' do + post :cancel, :platform_id => @platform, :id => @mass_build + @mass_build.reload.stop_build.should == true + end + + it 'should not be able to perform cancel action if stop_build is true' do + @mass_build.update_attribute(:stop_build, true) + post :cancel, :platform_id => @platform, :id => @mass_build + response.should redirect_to(forbidden_path) + end + + it 'should change objects count on create success' do + lambda { post :create, @create_params }.should change{ MassBuild.count }.by(1) + end + + context 'for personal platform' do + before(:each) do + Platform.update_all("platform_type = 'personal'") + end + + [:cancel, :failed_builds_list, :create].each do |action| + it "should not be able to perform #{ action } action" do + get action, :platform_id => @platform, :id => @mass_build.id + response.should redirect_to(forbidden_path) + end + end + end +end + +shared_examples_for 'mass_build platform reader' do + [:index, :create].each do |action| + it "should not be able to perform #{ action } action" do + get action, :platform_id => @platform + response.should redirect_to(forbidden_path) + end + end + + [:cancel, :failed_builds_list].each do |action| + it "should not be able to perform #{ action } action" do + get action, :platform_id => @platform, :id => @mass_build.id + response.should redirect_to(forbidden_path) + end + end + + it 'should not change objects count on create success' do + lambda { post :create, @create_params }.should change{ MassBuild.count }.by(0) + end + + it 'should not change stop_build on cancel' do + post :cancel, :platform_id => @platform, :id => @mass_build + @mass_build.reload.stop_build.should == false + end +end + + +describe Platforms::MassBuildsController do + before(:each) do + stub_symlink_methods + + @platform = FactoryGirl.create(:platform) + @repository = FactoryGirl.create(:repository, :platform => @platform) + @personal_platform = FactoryGirl.create(:platform, :platform_type => 'personal') + @user = FactoryGirl.create(:user) + @create_params = { + :platform_id => @platform, + :repositories => [@platform.repositories.first.id], + :arches => [Arch.first.id], + :auto_publish => true + } + + #@mass_build = FactoryGirl.build(:mass_build, :platform => @platform, :user => @user, :name => "fuck") + @mass_build = MassBuild.new( + :platform => @platform, + :user => @user, + :repositories => [@repository.id], + :arches => [Arch.first.id], + :auto_publish => false + ) + @mass_build.save + end + + context 'for guest' do + [:index, :create, :cancel, :failed_builds_list].each do |action| + it "should not be able to perform #{ action } action" do + get action, :platform_id => @platform + response.should redirect_to(new_user_session_path) + end + end + + it 'should not change objects count on create success' do + lambda { post :create, @create_params }.should change{ MassBuild.count }.by(0) + end + + it 'should not change stop_build on cancel' do + post :cancel, :platform_id => @platform, :id => @mass_build + @mass_build.reload.stop_build.should == false + end + end + + context 'for global admin' do + before(:each) do + @admin = FactoryGirl.create(:admin) + @user = FactoryGirl.create(:user) + set_session_for(@admin) + end + + # Can global create and view?? + #it_should_behave_like 'mass_build platform owner' + it_should_behave_like 'mass_build platform owner' + end + + context 'for owner user' do + before(:each) do + @user = FactoryGirl.create(:user) + set_session_for(@user) + @platform.update_attribute(:owner, @user) + #@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin') + end + + it_should_behave_like 'mass_build platform owner' + end + + context 'for admin user' do + before(:each) do + @user = FactoryGirl.create(:user) + set_session_for(@user) + #@platform.update_attribute(:owner, @user) + @platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin') + end + + it_should_behave_like 'mass_build platform owner' + end + + context 'for reader user' do + before(:each) do + @user = FactoryGirl.create(:user) + set_session_for(@user) + @platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'reader') + end + + it_should_behave_like 'mass_build platform reader' + end +end + diff --git a/spec/factories/mass_build.rb b/spec/factories/mass_build.rb new file mode 100644 index 000000000..46b64144a --- /dev/null +++ b/spec/factories/mass_build.rb @@ -0,0 +1,12 @@ +# -*- encoding : utf-8 -*- +FactoryGirl.define do + factory :mass_build do + association :platform + #name FactoryGirl.generate(:name) + association :user + repositories { |mb| [ mb.platform.repositories.first.id ] } + arches { [ Arch.first.id ] } + auto_publish true + end +end + From c6600054d148668601afad0f6a3ec8deb5e5009c Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Mon, 9 Jul 2012 17:16:52 +0400 Subject: [PATCH 38/48] [refs #442] Change platform and user set to platform_id and user_id --- app/controllers/platforms/mass_builds_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/platforms/mass_builds_controller.rb b/app/controllers/platforms/mass_builds_controller.rb index 8564ff2ee..a0ab0bd76 100644 --- a/app/controllers/platforms/mass_builds_controller.rb +++ b/app/controllers/platforms/mass_builds_controller.rb @@ -11,8 +11,8 @@ class Platforms::MassBuildsController < Platforms::BaseController def create mass_build = MassBuild.new( - :platform => @platform, - :user => current_user, + :platform_id => @platform.id, + :user_id => current_user.id, :repositories => params[:repositories], :arches => params[:arches], :auto_publish => params[:auto_publish] || false From 2839dc14b6a59d562dded0d88984908fb2756c2d Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Mon, 9 Jul 2012 19:19:30 +0400 Subject: [PATCH 39/48] [issue #428] Using #name_with_owner in projects pages. --- app/views/platforms/repositories/_proj_ajax.js.erb | 2 +- app/views/projects/build_lists/_build_list.html.haml | 2 +- app/views/projects/projects/_project.html.haml | 5 +---- app/views/projects/projects/_project.json.jbuilder | 2 +- app/views/projects/projects/index.html.haml | 3 +-- lib/modules/models/owner.rb | 2 +- 6 files changed, 6 insertions(+), 10 deletions(-) diff --git a/app/views/platforms/repositories/_proj_ajax.js.erb b/app/views/platforms/repositories/_proj_ajax.js.erb index 3b00728de..3058ffbb2 100644 --- a/app/views/platforms/repositories/_proj_ajax.js.erb +++ b/app/views/platforms/repositories/_proj_ajax.js.erb @@ -5,7 +5,7 @@ "aaData": [ <% @projects.each do |project| %> [ - "<%=j link_to("#{project.owner.respond_to?(:uname) ? project.owner.uname : project.owner.name} / #{project.name}", project) %>", + "<%=j link_to(project.name_with_owner, project) %>", "<%= truncate(project.description || '', :length => 60).gsub(/\n|\r|\t/, ' ') %>", "<%=j link_to t("layout.add"), url_for(:controller => :repositories, :action => :add_project, :project_id => project.id) %>" ]<%= project == @projects.last ? '' : ',' %> diff --git a/app/views/projects/build_lists/_build_list.html.haml b/app/views/projects/build_lists/_build_list.html.haml index abb5f43b8..6c8eb4a05 100644 --- a/app/views/projects/build_lists/_build_list.html.haml +++ b/app/views/projects/build_lists/_build_list.html.haml @@ -2,7 +2,7 @@ %td= link_to (build_list.bs_id.present? ? build_list.bs_id : t("layout.build_lists.bs_id_not_set")), build_list %td= build_list.mass_build_id ? link_to(build_list.mass_build.name, mass_builds_platform_path(build_list.save_to_platform)) : "" %td= build_list.human_status - %td= link_to build_list.project.name, build_list.project + %td= link_to build_list.project.name_with_owner, build_list.project %td= link_to build_list.project_version, "#" %td= build_list.arch.name %td= link_to build_list.user.try(:fullname), build_list.user diff --git a/app/views/projects/projects/_project.html.haml b/app/views/projects/projects/_project.html.haml index f5514643f..a59667f52 100644 --- a/app/views/projects/projects/_project.html.haml +++ b/app/views/projects/projects/_project.html.haml @@ -2,10 +2,7 @@ %td = link_to project do .table-sort-left= image_tag visibility_icon(project.visibility) - .table-sort-right - = link_to project.owner.uname, project.owner.class == User ? user_path(project.owner) : group_path(project.owner) #{project.owner.uname} / #{project.name} - #{ ' / ' } - = link_to project.name, project_path(project) + .table-sort-right= link_to project.name_with_owner, project_path(project) %td.td2= project.description - alone_member = alone_member? project %td diff --git a/app/views/projects/projects/_project.json.jbuilder b/app/views/projects/projects/_project.json.jbuilder index 4052c1171..cd11bcb2a 100644 --- a/app/views/projects/projects/_project.json.jbuilder +++ b/app/views/projects/projects/_project.json.jbuilder @@ -1,7 +1,7 @@ json.project do |proj| proj.visibility project.visibility.to_s - proj.name project.name + proj.name project.name_with_owner proj.description project.description proj.link project_path(project) diff --git a/app/views/projects/projects/index.html.haml b/app/views/projects/projects/index.html.haml index ed1a4777c..01c48b8bd 100644 --- a/app/views/projects/projects/index.html.haml +++ b/app/views/projects/projects/index.html.haml @@ -45,11 +45,10 @@ var image = '' + project.visibility + ''; - var owner = '' + project.owner.name + ''; var project = '' + project.name + ''; return '
      ' + image + "
      \n" + - '
      ' + owner + ' / ' + project + '
      '; + '
      ' + project + '
      '; } var thirdColumn = function(row) { diff --git a/lib/modules/models/owner.rb b/lib/modules/models/owner.rb index 218e29f29..182682e18 100644 --- a/lib/modules/models/owner.rb +++ b/lib/modules/models/owner.rb @@ -14,7 +14,7 @@ module Modules module InstanceMethods def name_with_owner - "#{owner.uname}/#{self.name}" + "#{owner.respond_to?(:uname) ? owner.uname : owner.name}/#{self.name}" end end From adc917ca3b08d7ea0a1c0352a7fc2375a2ab1597 Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Mon, 9 Jul 2012 20:13:02 +0400 Subject: [PATCH 40/48] [refs #442] MassBuild data initialize refactor --- .../platforms/mass_builds_controller.rb | 9 +++----- app/models/mass_build.rb | 22 ++++++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/app/controllers/platforms/mass_builds_controller.rb b/app/controllers/platforms/mass_builds_controller.rb index a0ab0bd76..ecea50458 100644 --- a/app/controllers/platforms/mass_builds_controller.rb +++ b/app/controllers/platforms/mass_builds_controller.rb @@ -10,13 +10,10 @@ class Platforms::MassBuildsController < Platforms::BaseController skip_authorize_resource :platform, :only => [:create, :index] def create - mass_build = MassBuild.new( - :platform_id => @platform.id, - :user_id => current_user.id, - :repositories => params[:repositories], + mass_build = @platform.mass_builds.new(:repositories => params[:repositories], :arches => params[:arches], - :auto_publish => params[:auto_publish] || false - ) + :auto_publish => params[:auto_publish] || false) + mass_build.user = current_user authorize! :create, mass_build if mass_build.save diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index 4fb14758e..70804f2ac 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -12,6 +12,7 @@ class MassBuild < ActiveRecord::Base validates_inclusion_of :auto_publish, :in => [true, false] after_create :build_all + before_validation :set_data COUNT_STATUSES = [ :build_lists, @@ -22,16 +23,6 @@ class MassBuild < ActiveRecord::Base :build_error ] - def initialize(args = nil) - super - - if new_record? - self.rep_names = Repository.where(:id => self.repositories).map(&:name).join(", ") - self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{platform.name}" - self.arch_names = Arch.where(:id => self.arches).map(&:name).join(", ") - end - end - # ATTENTION: repositories and arches must be set before calling this method! def build_all platform.build_all( @@ -59,4 +50,15 @@ class MassBuild < ActiveRecord::Base end end later :cancel_all, :queue => :clone_build + + private + + def set_data + if new_record? + self.rep_names = Repository.where(:id => self.repositories).map(&:name).join(", ") + self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{platform.name}" + self.arch_names = Arch.where(:id => self.arches).map(&:name).join(", ") + end + end + end From 620d78fd1b7dd1f318176c8603f196f2f1ab918a Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Mon, 9 Jul 2012 20:48:31 +0400 Subject: [PATCH 41/48] [refs #442] MassBuilds create refactor and specs fix --- app/models/mass_build.rb | 2 +- .../platforms/mass_builds_controller_spec.rb | 14 +------------- spec/factories/mass_build.rb | 1 + 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/app/models/mass_build.rb b/app/models/mass_build.rb index 70804f2ac..8cdc5c0f9 100644 --- a/app/models/mass_build.rb +++ b/app/models/mass_build.rb @@ -6,7 +6,7 @@ class MassBuild < ActiveRecord::Base scope :by_platform, lambda { |platform| where(:platform_id => platform.id) } attr_accessor :repositories, :arches - attr_accessible :platform, :platform_id, :user, :user_id, :repositories, :arches, :auto_publish + attr_accessible :repositories, :arches, :auto_publish validates :platform_id, :arch_names, :name, :user_id, :repositories, :rep_names, :presence => true validates_inclusion_of :auto_publish, :in => [true, false] diff --git a/spec/controllers/platforms/mass_builds_controller_spec.rb b/spec/controllers/platforms/mass_builds_controller_spec.rb index 14d37f38c..6a85981f9 100644 --- a/spec/controllers/platforms/mass_builds_controller_spec.rb +++ b/spec/controllers/platforms/mass_builds_controller_spec.rb @@ -87,15 +87,7 @@ describe Platforms::MassBuildsController do :auto_publish => true } - #@mass_build = FactoryGirl.build(:mass_build, :platform => @platform, :user => @user, :name => "fuck") - @mass_build = MassBuild.new( - :platform => @platform, - :user => @user, - :repositories => [@repository.id], - :arches => [Arch.first.id], - :auto_publish => false - ) - @mass_build.save + @mass_build = FactoryGirl.create(:mass_build, :platform => @platform, :user => @user) end context 'for guest' do @@ -123,8 +115,6 @@ describe Platforms::MassBuildsController do set_session_for(@admin) end - # Can global create and view?? - #it_should_behave_like 'mass_build platform owner' it_should_behave_like 'mass_build platform owner' end @@ -133,7 +123,6 @@ describe Platforms::MassBuildsController do @user = FactoryGirl.create(:user) set_session_for(@user) @platform.update_attribute(:owner, @user) - #@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin') end it_should_behave_like 'mass_build platform owner' @@ -143,7 +132,6 @@ describe Platforms::MassBuildsController do before(:each) do @user = FactoryGirl.create(:user) set_session_for(@user) - #@platform.update_attribute(:owner, @user) @platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin') end diff --git a/spec/factories/mass_build.rb b/spec/factories/mass_build.rb index 46b64144a..e9afc907a 100644 --- a/spec/factories/mass_build.rb +++ b/spec/factories/mass_build.rb @@ -7,6 +7,7 @@ FactoryGirl.define do repositories { |mb| [ mb.platform.repositories.first.id ] } arches { [ Arch.first.id ] } auto_publish true + stop_build false end end From 7b3c74e97db00e9bbd724ff381374f504eba0786 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Tue, 10 Jul 2012 00:43:01 +0400 Subject: [PATCH 42/48] [issue #561] Changed BuildList pages * Removed mass_build, cancel and updated_at fields from list * Added link to commit in list (instead of version) * Added platform field in list * Added filter by main platforms * Added cancel button and mass_build field to BuildList#show --- app/controllers/projects/build_lists_controller.rb | 2 +- app/helpers/build_lists_helper.rb | 9 +++++++++ app/models/build_list.rb | 1 + app/models/build_list/filter.rb | 3 +++ .../projects/build_lists/_build_list.html.haml | 6 ++---- app/views/projects/build_lists/_filter.html.haml | 2 ++ app/views/projects/build_lists/index.html.haml | 4 +--- app/views/projects/build_lists/show.html.haml | 13 +++++-------- config/locales/models/build_list.en.yml | 1 + config/locales/models/build_list.ru.yml | 1 + 10 files changed, 26 insertions(+), 16 deletions(-) diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index 7893f98c0..8ceb1836f 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -25,7 +25,7 @@ class Projects::BuildListsController < Projects::BaseController def index @action_url = @project ? search_project_build_lists_path(@project) : search_build_lists_path @filter = BuildList::Filter.new(@project, current_user, params[:filter] || {}) - @build_lists = @filter.find.recent.paginate :page => params[:page] + @build_lists = @filter.find.scoped(:include => [:save_to_platform]).recent.paginate :page => params[:page] @build_server_status = begin BuildServer.get_status diff --git a/app/helpers/build_lists_helper.rb b/app/helpers/build_lists_helper.rb index 2b9d66882..6509b3cb5 100644 --- a/app/helpers/build_lists_helper.rb +++ b/app/helpers/build_lists_helper.rb @@ -34,4 +34,13 @@ module BuildListsHelper return advisoriable + nonadvisoriable end + + def build_list_version_link(build_list, str_version = false) + if build_list.commit_hash.present? + link_to str_version ? "#{shortest_hash_id @build_list.commit_hash} ( #{@build_list.project_version} )" : shortest_hash_id(build_list.commit_hash), + commit_path(build_list.project.owner, build_list.project, build_list.commit_hash) + else + build_list.project_version + end + end end diff --git a/app/models/build_list.rb b/app/models/build_list.rb index 6c60b6d89..a3f0b416b 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -76,6 +76,7 @@ class BuildList < ActiveRecord::Base scope :for_platform, lambda { |platform| where(:build_for_platform_id => platform.id) } scope :by_mass_build, lambda { |mass_build| where(:mass_build_id => mass_build) } scope :scoped_to_arch, lambda {|arch| where(:arch_id => arch) } + scope :scoped_to_save_platform, lambda {|pl_id| where(:save_to_platform_id => pl_id) } scope :scoped_to_project_version, lambda {|project_version| where(:project_version => project_version) } scope :scoped_to_is_circle, lambda {|is_circle| where(:is_circle => is_circle) } scope :for_creation_date_period, lambda{|start_date, end_date| diff --git a/app/models/build_list/filter.rb b/app/models/build_list/filter.rb index f023d25cc..85192256f 100644 --- a/app/models/build_list/filter.rb +++ b/app/models/build_list/filter.rb @@ -15,6 +15,7 @@ class BuildList::Filter build_lists = build_lists.accessible_by(::Ability.new(@user), @options[:ownership].to_sym) if @options[:ownership] build_lists = build_lists.for_status(@options[:status]) if @options[:status] build_lists = build_lists.scoped_to_arch(@options[:arch_id]) if @options[:arch_id] + build_lists = build_lists.scoped_to_save_platform(@options[:platform_id]) if @options[:platform_id] build_lists = build_lists.scoped_to_project_version(@options[:project_version]) if @options[:project_version] build_lists = build_lists.scoped_to_is_circle(@options[:is_circle]) if @options[:is_circle].present? build_lists = build_lists.scoped_to_project_name(@options[:project_name]) if @options[:project_name] @@ -51,6 +52,7 @@ class BuildList::Filter :updated_at_start => nil, :updated_at_end => nil, :arch_id => nil, + :platform_id => nil, :is_circle => nil, :project_version => nil, :bs_id => nil, @@ -66,6 +68,7 @@ class BuildList::Filter @options[:updated_at_end] = build_date_from_params(:updated_at_end, @options) @options[:project_version] = @options[:project_version].presence @options[:arch_id] = @options[:arch_id].present? ? @options[:arch_id].to_i : nil + @options[:platform_id] = @options[:platform_id].present? ? @options[:platform_id].to_i : nil @options[:is_circle] = @options[:is_circle].present? ? @options[:is_circle] == "1" : nil @options[:bs_id] = @options[:bs_id].presence @options[:project_name] = @options[:project_name].presence diff --git a/app/views/projects/build_lists/_build_list.html.haml b/app/views/projects/build_lists/_build_list.html.haml index 8e3f67d91..153ead5fd 100644 --- a/app/views/projects/build_lists/_build_list.html.haml +++ b/app/views/projects/build_lists/_build_list.html.haml @@ -1,10 +1,8 @@ %tr{:id => "row#{build_list_counter}", :class => "#{build_list_status_color(build_list.status)}"} %td= link_to (build_list.bs_id.present? ? build_list.bs_id : t("layout.build_lists.bs_id_not_set")), build_list - %td= build_list.mass_build_id ? link_to(build_list.mass_build.name, platform_mass_builds_path(build_list.save_to_platform)) : "" %td= build_list.human_status %td= link_to build_list.project.name_with_owner, build_list.project - %td= link_to build_list.project_version, "#" + %td= build_list_version_link(build_list) %td= build_list.arch.name + %td= link_to build_list.save_to_platform.name, build_list.save_to_platform %td= link_to build_list.user.try(:fullname), build_list.user - %td= link_to image_tag('x.png', :class => 'delete-row', :id => "delete-row#{build_list_counter}"), cancel_build_list_path(build_list), :method => :put, :confirm => t('layout.confirm') if build_list.can_cancel? and can?(:cancel, build_list) - %td= build_list.updated_at diff --git a/app/views/projects/build_lists/_filter.html.haml b/app/views/projects/build_lists/_filter.html.haml index 67ea7082c..6ff7b7bd6 100644 --- a/app/views/projects/build_lists/_filter.html.haml +++ b/app/views/projects/build_lists/_filter.html.haml @@ -45,6 +45,8 @@ .lineForm.aside= f.select :is_circle, [[t("layout.yes_"), 1], [t("layout.no_"), 0]], {:include_blank => true, :selected => @filter.is_circle.present? ? (@filter.is_circle ? "1" : "0") : nil}, {:class => 'sel80 aside', :id => 'recurrent', :tabindex => 2} %h3.small= t("activerecord.attributes.build_list.arch") .lineForm.aside= f.select :arch_id, Arch.recent.collect{|arch| [arch.name, arch.id]}, {:include_blank => true, :selected => @filter.arch_id}, {:class => 'sel80 aside', :id => 'architecture', :tabindex => 2} + %h3.small= t("activerecord.models.platform") + .lineForm.aside= f.select :platform_id, Platform.main.collect{|pl| [pl.name, pl.id]}, {:include_blank => true, :selected => @filter.platform_id}, {:class => 'sel80 aside', :id => 'platform', :tabindex => 2} %h3.small= t("layout.build_lists.created_at_start") .date_select= f.date_select(:created_at_start, :include_blank => true, :selected => @filter.created_at_start) %h3.small= t("layout.build_lists.created_at_end") diff --git a/app/views/projects/build_lists/index.html.haml b/app/views/projects/build_lists/index.html.haml index 37cb2c2ea..40a290a49 100644 --- a/app/views/projects/build_lists/index.html.haml +++ b/app/views/projects/build_lists/index.html.haml @@ -4,14 +4,12 @@ %thead %tr %th.lpadding16= t("activerecord.attributes.build_list.bs_id") - %th.lpadding16= t('activerecord.attributes.build_list.mass_build_id') %th.lpadding16= t("activerecord.attributes.build_list.status") %th.lpadding16= t("activerecord.attributes.build_list.project") %th.lpadding16= t("activerecord.attributes.build_list.project_version") %th.lpadding16= t("activerecord.attributes.build_list.arch") + %th.lpadding16= t("activerecord.models.platform") %th.lpadding16= t("activerecord.attributes.build_list.user") - %th= t("layout.build_lists.action") - %th.lpadding16= t("activerecord.attributes.build_list.updated_at") %tbody= render :partial => 'projects/build_lists/build_list', :collection => @build_lists .both diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index beb41fa11..5de1af34b 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -43,7 +43,7 @@ .rightlist= t("layout.#{@build_list.auto_publish}_") .both .leftlist= t("activerecord.attributes.build_list.project_version") - .rightlist= @build_list.project_version + .rightlist= build_list_version_link(@build_list, true) .both .leftlist= t("activerecord.attributes.build_list.arch") .rightlist= @build_list.arch.name @@ -71,6 +71,10 @@ = "#{@build_list.human_current_duration} / #{@build_list.project.human_average_build_time}" .both + - if @build_list.can_cancel? and can?(:cancel, @build_list) + = link_to t("layout.build_lists.cancel"), cancel_build_list_path(@build_list), + :method => :put, :confirm => t("layout.confirm"), :class => 'button' + - if @build_list.can_publish? and @build_list.save_to_platform.released and @build_list.advisory.nil? #advisory_block .leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory") @@ -90,13 +94,6 @@ .info{:class => el} %p= t("layout.advisories.banners.#{el}") - -#.info.advisory_not_found - %p= t("layout.advisories.banners.advisory_not_found") - -#.info.server_error - %p= t("layout.advisories.banners.server_error") - -#.info.continue_input - %p= t("layout.advisories.banners.continue_input") - #new_advisory_form = f.fields_for @build_list.build_advisory do |f| = render :partial => 'advisories/form', :locals => {:f => f} diff --git a/config/locales/models/build_list.en.yml b/config/locales/models/build_list.en.yml index 139ae436b..92090d98e 100644 --- a/config/locales/models/build_list.en.yml +++ b/config/locales/models/build_list.en.yml @@ -58,6 +58,7 @@ en: packages_header: Container data no_items_data: No data show: Show + cancel: Cancel build cancel_success: 'Build canceled' cancel_fail: 'Errors during build cancelation!' publish_success: 'Build is queued for publishing' diff --git a/config/locales/models/build_list.ru.yml b/config/locales/models/build_list.ru.yml index 910292188..814b202cb 100644 --- a/config/locales/models/build_list.ru.yml +++ b/config/locales/models/build_list.ru.yml @@ -57,6 +57,7 @@ ru: packages_header: Данные о контейнере no_items_data: Данных нет show: Просмотр + cancel: Отменить сборку cancel_success: 'Сборка отменена.' cancel_fail: 'При отмене сборки произошла ошибка!' publish_success: 'Сборка поставлена в очередь на публикацию.' From 8c5a8c884dcdb35dcd00230cf35b485573cc6318 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Tue, 10 Jul 2012 01:13:55 +0400 Subject: [PATCH 43/48] [issue #561] Some DB query optimization. --- app/controllers/projects/build_lists_controller.rb | 3 ++- app/views/projects/build_lists/show.html.haml | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index 8ceb1836f..cb5115741 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -25,7 +25,8 @@ class Projects::BuildListsController < Projects::BaseController def index @action_url = @project ? search_project_build_lists_path(@project) : search_build_lists_path @filter = BuildList::Filter.new(@project, current_user, params[:filter] || {}) - @build_lists = @filter.find.scoped(:include => [:save_to_platform]).recent.paginate :page => params[:page] + @build_lists = @filter.find.scoped(:include => [:save_to_platform, :project, :user, :arch]) + @build_lists = @build_lists.recent.paginate :page => params[:page] @build_server_status = begin BuildServer.get_status diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index 5de1af34b..469f9b48b 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -55,6 +55,12 @@ .rightlist= t("layout.#{@build_list.is_circle?}_") .both + - if @build_list.mass_build_id.present? + .leftlist= t("activerecord.attributes.mass_build_id") + .rightlist= link_to build_list.mass_build.name, platform_mass_builds_path(build_list.save_to_platform) + .both + + - if @build_list.advisory.present? .leftlist= t("layout.build_lists.attached_advisory") .rightlist= link_to @build_list.advisory.advisory_id, advisory_path(@build_list.advisory) From f997e5090538af0b4dfcdc013ca26f83baf6d244 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Tue, 10 Jul 2012 01:49:19 +0400 Subject: [PATCH 44/48] [issue #561] Some cosmethic changes. * Reordered columns in BuildLists table * Reordered rows in BuildLists filter * Removed created_at filter (Commented. See TODOs) --- app/models/build_list/filter.rb | 8 +++++--- .../build_lists/_build_list.html.haml | 2 +- .../projects/build_lists/_filter.html.haml | 19 +++++++++---------- .../projects/build_lists/index.html.haml | 2 +- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/app/models/build_list/filter.rb b/app/models/build_list/filter.rb index 85192256f..b6095fc71 100644 --- a/app/models/build_list/filter.rb +++ b/app/models/build_list/filter.rb @@ -21,9 +21,11 @@ class BuildList::Filter build_lists = build_lists.scoped_to_project_name(@options[:project_name]) if @options[:project_name] build_lists = build_lists.by_mass_build(@options[:mass_build_id]) if @options[:mass_build_id] - if @options[:created_at_start] || @options[:created_at_end] - build_lists = build_lists.for_creation_date_period(@options[:created_at_start], @options[:created_at_end]) - end +# TODO [BuildList#created_at filters] Uncomment here and in build_lists/_filter.html.haml to return filters +# +# if @options[:created_at_start] || @options[:created_at_end] +# build_lists = build_lists.for_creation_date_period(@options[:created_at_start], @options[:created_at_end]) +# end if @options[:updated_at_start] || @options[:updated_at_end] build_lists = build_lists.for_notified_date_period(@options[:updated_at_start], @options[:updated_at_end]) end diff --git a/app/views/projects/build_lists/_build_list.html.haml b/app/views/projects/build_lists/_build_list.html.haml index 153ead5fd..4c6005c80 100644 --- a/app/views/projects/build_lists/_build_list.html.haml +++ b/app/views/projects/build_lists/_build_list.html.haml @@ -3,6 +3,6 @@ %td= build_list.human_status %td= link_to build_list.project.name_with_owner, build_list.project %td= build_list_version_link(build_list) - %td= build_list.arch.name %td= link_to build_list.save_to_platform.name, build_list.save_to_platform + %td= build_list.arch.name %td= link_to build_list.user.try(:fullname), build_list.user diff --git a/app/views/projects/build_lists/_filter.html.haml b/app/views/projects/build_lists/_filter.html.haml index 6ff7b7bd6..0d7d38eaa 100644 --- a/app/views/projects/build_lists/_filter.html.haml +++ b/app/views/projects/build_lists/_filter.html.haml @@ -37,20 +37,19 @@ %br = f.submit t("layout.search.header") .block - %h3.small= t("activerecord.attributes.build_list.mass_build") - .lineForm.aside= f.select :mass_build_id, options_from_collection_for_select( MassBuild.all, :id, :name, @filter.mass_build_id ), {:include_blank => true} %h3.small= t("activerecord.attributes.build_list.status") .lineForm.aside= f.select :status, BuildList::STATUSES.collect{|status| [BuildList.human_status(status), status]}, {:include_blank => true, :selected => @filter.status}, {:class => 'sel80 aside', :id => 'status', :tabindex => 2} - %h3.small= t("activerecord.attributes.build_list.is_circle") - .lineForm.aside= f.select :is_circle, [[t("layout.yes_"), 1], [t("layout.no_"), 0]], {:include_blank => true, :selected => @filter.is_circle.present? ? (@filter.is_circle ? "1" : "0") : nil}, {:class => 'sel80 aside', :id => 'recurrent', :tabindex => 2} - %h3.small= t("activerecord.attributes.build_list.arch") - .lineForm.aside= f.select :arch_id, Arch.recent.collect{|arch| [arch.name, arch.id]}, {:include_blank => true, :selected => @filter.arch_id}, {:class => 'sel80 aside', :id => 'architecture', :tabindex => 2} %h3.small= t("activerecord.models.platform") .lineForm.aside= f.select :platform_id, Platform.main.collect{|pl| [pl.name, pl.id]}, {:include_blank => true, :selected => @filter.platform_id}, {:class => 'sel80 aside', :id => 'platform', :tabindex => 2} - %h3.small= t("layout.build_lists.created_at_start") - .date_select= f.date_select(:created_at_start, :include_blank => true, :selected => @filter.created_at_start) - %h3.small= t("layout.build_lists.created_at_end") - .date_select= f.date_select(:created_at_end, :include_blank => true, :selected => @filter.created_at_end) + %h3.small= t("activerecord.attributes.build_list.mass_build") + .lineForm.aside= f.select :mass_build_id, options_from_collection_for_select( MassBuild.all, :id, :name, @filter.mass_build_id ), {:include_blank => true} + %h3.small= t("activerecord.attributes.build_list.arch") + .lineForm.aside= f.select :arch_id, Arch.recent.collect{|arch| [arch.name, arch.id]}, {:include_blank => true, :selected => @filter.arch_id}, {:class => 'sel80 aside', :id => 'architecture', :tabindex => 2} + -# TODO [BuildList#created_at filters] Uncomment here and in BuildList::Filter to return filters + %h3.small= t("layout.build_lists.created_at_start") + .date_select= f.date_select(:created_at_start, :include_blank => true, :selected => @filter.created_at_start) + %h3.small= t("layout.build_lists.created_at_end") + .date_select= f.date_select(:created_at_end, :include_blank => true, :selected => @filter.created_at_end) %h3.small= t("layout.build_lists.updated_at_start") .date_select= f.date_select(:updated_at_start, :include_blank => true, :selected => @filter.updated_at_start) %h3.small= t("layout.build_lists.updated_at_end") diff --git a/app/views/projects/build_lists/index.html.haml b/app/views/projects/build_lists/index.html.haml index 40a290a49..a1f16ddf4 100644 --- a/app/views/projects/build_lists/index.html.haml +++ b/app/views/projects/build_lists/index.html.haml @@ -7,8 +7,8 @@ %th.lpadding16= t("activerecord.attributes.build_list.status") %th.lpadding16= t("activerecord.attributes.build_list.project") %th.lpadding16= t("activerecord.attributes.build_list.project_version") - %th.lpadding16= t("activerecord.attributes.build_list.arch") %th.lpadding16= t("activerecord.models.platform") + %th.lpadding16= t("activerecord.attributes.build_list.arch") %th.lpadding16= t("activerecord.attributes.build_list.user") %tbody= render :partial => 'projects/build_lists/build_list', :collection => @build_lists .both From 3195969aabe4471dac7e280cb8d67ca15666e174 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Tue, 10 Jul 2012 02:14:31 +0400 Subject: [PATCH 45/48] [issue #561] Added bs_id to BuildList#show --- app/views/projects/build_lists/show.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index 469f9b48b..acc9c36fa 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -14,6 +14,10 @@ - container_url = "http://#{request.host_with_port}/downloads#{@build_list.container_path}" = link_to container_url, container_url .both + + .leftlist= t("activerecord.attributes.build_list.bs_id") + .rightlist= @build_list.bs_id.present? ? @build_list.bs_id : t("layout.build_lists.bs_id_not_set") + .both .leftlist= t("activerecord.attributes.build_list.user") .rightlist = link_to @build_list.user.try(:fullname), @build_list.user From f83a1ae6c22f290706478397d0bc6c94a23645ec Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Tue, 10 Jul 2012 02:52:08 +0400 Subject: [PATCH 46/48] [issue #561] Changed translations. --- app/views/projects/build_lists/index.html.haml | 2 +- config/locales/models/build_list.en.yml | 4 ++-- config/locales/models/build_list.ru.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/projects/build_lists/index.html.haml b/app/views/projects/build_lists/index.html.haml index a1f16ddf4..67d89fc2b 100644 --- a/app/views/projects/build_lists/index.html.haml +++ b/app/views/projects/build_lists/index.html.haml @@ -7,7 +7,7 @@ %th.lpadding16= t("activerecord.attributes.build_list.status") %th.lpadding16= t("activerecord.attributes.build_list.project") %th.lpadding16= t("activerecord.attributes.build_list.project_version") - %th.lpadding16= t("activerecord.models.platform") + %th.lpadding16= t("activerecord.attributes.build_list.save_to_platform") %th.lpadding16= t("activerecord.attributes.build_list.arch") %th.lpadding16= t("activerecord.attributes.build_list.user") %tbody= render :partial => 'projects/build_lists/build_list', :collection => @build_lists diff --git a/config/locales/models/build_list.en.yml b/config/locales/models/build_list.en.yml index 92090d98e..cdcf7530e 100644 --- a/config/locales/models/build_list.en.yml +++ b/config/locales/models/build_list.en.yml @@ -18,8 +18,8 @@ en: additional_repos: Additional repositories include_repos: Included repositories created_at: Created on - save_to_platform: Repository for package storage - build_for_platform: Platform + save_to_platform: Platform + build_for_platform: Build for platform update_type: Update type build_requires: Build with all the required packages auto_publish: Automated publising diff --git a/config/locales/models/build_list.ru.yml b/config/locales/models/build_list.ru.yml index 814b202cb..5c5820a9d 100644 --- a/config/locales/models/build_list.ru.yml +++ b/config/locales/models/build_list.ru.yml @@ -18,8 +18,8 @@ ru: additional_repos: Дополнительные репозитории include_repos: Подключаемые репозитории created_at: Создан - save_to_platform: Репозиторий для сохранения пакетов - build_for_platform: Платформа + save_to_platform: Платформа + build_for_platform: Собрано для платформы update_type: Критичность обновления build_requires: Пересборка с зависимостями auto_publish: Автоматическая публикация From cfb16f811857d2e1be02a66262f953bae483d059 Mon Sep 17 00:00:00 2001 From: George Vinogradov Date: Tue, 10 Jul 2012 03:56:47 +0400 Subject: [PATCH 47/48] [issue #561] Fixed bug on BuildList#show page --- app/views/projects/build_lists/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index acc9c36fa..f061efcf3 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -61,7 +61,7 @@ - if @build_list.mass_build_id.present? .leftlist= t("activerecord.attributes.mass_build_id") - .rightlist= link_to build_list.mass_build.name, platform_mass_builds_path(build_list.save_to_platform) + .rightlist= link_to @build_list.mass_build.name, platform_mass_builds_path(@build_list.save_to_platform) .both From 1de9277e4af1eef56713c041ad57b05471da25fc Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Tue, 10 Jul 2012 11:06:08 +0400 Subject: [PATCH 48/48] [refs #442] Add main? method for platforms --- app/models/ability.rb | 14 +++++++------- app/models/platform.rb | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 3fe541d55..c9e9d8ab7 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -86,22 +86,22 @@ class Ability can([:destroy, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) } can [:autocomplete_user_uname, :read_advisories, :advisories], Platform - can([:failed_builds_list, :create], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && (mass_build.platform.platform_type == 'main') } - can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && (mass_build.platform.platform_type == 'main')} + can([:failed_builds_list, :create], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && mass_build.platform.main? } + can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && mass_build.platform.main?} can [:read, :projects_list], Repository, :platform => {:visibility => 'open'} can [:read, :projects_list], Repository, :platform => {:owner_type => 'User', :owner_id => user.id} can [:read, :projects_list], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} can([:read, :projects_list], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform} can([:create, :update, :projects_list, :add_project, :remove_project], Repository) {|repository| local_admin? repository.platform} - can(:clear, Platform) {|platform| local_admin?(platform) && platform.platform_type == 'personal'} + can(:clear, Platform) {|platform| local_admin?(platform) && platform.personal?} can([:change_visibility, :settings, :destroy], Repository) {|repository| owner? repository.platform} can :read, Product, :platform => {:visibility => 'open'} can :read, Product, :platform => {:owner_type => 'User', :owner_id => user.id, :platform_type => 'main'} can :read, Product, :platform => {:owner_type => 'Group', :owner_id => user.group_ids, :platform_type => 'main'} - can(:read, Product, read_relations_for('products', 'platforms')) {|product| product.platform.platform_type == 'main'} - can([:create, :update, :destroy, :clone], Product) {|product| local_admin? product.platform and product.platform.platform_type == 'main'} + can(:read, Product, read_relations_for('products', 'platforms')) {|product| product.platform.main?} + can([:create, :update, :destroy, :clone], Product) {|product| local_admin? product.platform and product.platform.main?} can(:create, ProductBuildList) {|pbl| can?(:update, pbl.product)} can(:destroy, ProductBuildList) {|pbl| can?(:destroy, pbl.product)} @@ -132,8 +132,8 @@ class Ability cannot [:create, :update, :destroy, :clone], Product, :platform => {:platform_type => 'personal'} cannot [:clone], Platform, :platform_type => 'personal' - cannot([:failed_builds_list, :create], MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal'} - cannot(:cancel, MassBuild) {|mass_build| mass_build.platform.platform_type == 'personal' || mass_build.stop_build} + cannot([:failed_builds_list, :create], MassBuild) {|mass_build| mass_build.platform.personal?} + cannot(:cancel, MassBuild) {|mass_build| mass_build.platform.personal? || mass_build.stop_build} can :create, Subscribe do |subscribe| !subscribe.subscribeable.subscribes.exists?(:user_id => user.id) diff --git a/app/models/platform.rb b/app/models/platform.rb index 892a093e7..ddfadd1ee 100644 --- a/app/models/platform.rb +++ b/app/models/platform.rb @@ -107,6 +107,10 @@ class Platform < ActiveRecord::Base platform_type == 'personal' end + def main? + platform_type == 'main' + end + def base_clone(attrs = {}) # :description, :name, :owner dup.tap do |c| attrs.each {|k,v| c.send("#{k}=", v)} # c.attributes = attrs