diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index 728b52b5e..9c6e994d0 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -94,7 +94,6 @@ class BuildListsController < ApplicationController else @build_list.status = BuildList::FAILED_PUBLISH end - @build_list.notified_at = Time.current @build_list.save render :nothing => true, :status => 200 @@ -106,7 +105,6 @@ class BuildListsController < ApplicationController @item.save @build_list.container_path = params[:container_path] - @build_list.notified_at = Time.current @build_list.save render :nothing => true, :status => 200 @@ -114,7 +112,6 @@ class BuildListsController < ApplicationController def pre_build @build_list.status = BuildServer::BUILD_STARTED - @build_list.notified_at = Time.current @build_list.save render :nothing => true, :status => 200 @@ -123,7 +120,6 @@ class BuildListsController < ApplicationController def post_build @build_list.status = params[:status] @build_list.container_path = params[:container_path] - @build_list.notified_at = Time.current @build_list.save render :nothing => true, :status => 200 @@ -134,7 +130,6 @@ class BuildListsController < ApplicationController def circle_build @build_list.is_circle = true @build_list.container_path = params[:container_path] - @build_list.notified_at = Time.current @build_list.save render :nothing => true, :status => 200 @@ -147,7 +142,6 @@ class BuildListsController < ApplicationController @build_list.set_items(ActiveSupport::JSON.decode(params[:items])) @build_list.is_circle = (params[:is_circular].to_i != 0) @build_list.bs_id = params[:id] - @build_list.notified_at = Time.current @build_list.save render :nothing => true, :status => 200 diff --git a/app/models/activity_feed_observer.rb b/app/models/activity_feed_observer.rb index 4738fccfa..c9f1918c0 100644 --- a/app/models/activity_feed_observer.rb +++ b/app/models/activity_feed_observer.rb @@ -139,7 +139,7 @@ class ActivityFeedObserver < ActiveRecord::Observer ActivityFeed.create( :user => User.find(recipient), :kind => 'build_list_notification', - :data => {:task_num => record.bs_id, :build_list_id => record.id, :status => record.status, :notified_at => record.notified_at, + :data => {:task_num => record.bs_id, :build_list_id => record.id, :status => record.status, :updated_at => record.updated_at, :project_id => record.project_id, :project_name => record.project.name, :project_owner => record.project.owner.uname, :user_name => record.user.name, :user_email => record.user.email, :user_id => record.user_id} ) diff --git a/app/models/build_list.rb b/app/models/build_list.rb index 7293ec052..47091d4d3 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -66,22 +66,16 @@ class BuildList < ActiveRecord::Base 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| - if start_date && end_date - where(["#{table_name}.created_at BETWEEN ? AND ?", start_date, end_date]) - elsif start_date && !end_date - where(["#{table_name}.created_at >= ?", start_date]) - elsif !start_date && end_date - where(["#{table_name}.created_at <= ?", end_date]) - end + scoped = BuildList.scoped + scoped = scoped.where(["created_at >= ?", start_date]) if start_date + scoped = scoped.where(["created_at <= ?", end_date]) if end_date + scoped } scope :for_notified_date_period, lambda{|start_date, end_date| - if start_date && end_date - where(["notified_at BETWEEN ? AND ?", start_date, end_date]) - elsif start_date && !end_date - where(["notified_at >= ?", start_date]) - elsif !start_date && end_date - where(["notified_at <= ?", end_date]) - end + scoped = BuildList.scoped + scoped = scoped.where(["updated_at >= ?", start_date]) if start_date + scoped = scoped.where(["updated_at <= ?", end_date]) if end_date + scoped } scope :scoped_to_project_name, lambda {|project_name| joins(:project).where('projects.name LIKE ?', "%#{project_name}%")} @@ -136,6 +130,14 @@ class BuildList < ActiveRecord::Base {:project => project.name, :version => project_version, :arch => arch.name}.inspect end + def current_duration + (Time.now - started_at).to_i + end + + def human_current_duration + I18n.t("layout.build_lists.human_current_duration", {:hours => (current_duration/360).to_i, :minutes => (current_duration/60).to_i}) + end + def human_duration I18n.t("layout.build_lists.human_duration", {:hours => (duration/360).to_i, :minutes => (duration/60).to_i}) end diff --git a/app/models/build_list/filter.rb b/app/models/build_list/filter.rb index 58b7a9320..646011742 100644 --- a/app/models/build_list/filter.rb +++ b/app/models/build_list/filter.rb @@ -22,8 +22,8 @@ class BuildList::Filter 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[:notified_at_start] || @options[:notified_at_end] - build_lists = build_lists.for_notified_date_period(@options[:notified_at_start], @options[:notified_at_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 end @@ -47,8 +47,8 @@ class BuildList::Filter :status => nil, :created_at_start => nil, :created_at_end => nil, - :notified_at_start => nil, - :notified_at_end => nil, + :updated_at_start => nil, + :updated_at_end => nil, :arch_id => nil, :is_circle => nil, :project_version => nil, @@ -60,8 +60,8 @@ class BuildList::Filter @options[:status] = @options[:status].present? ? @options[:status].to_i : nil @options[:created_at_start] = build_date_from_params(:created_at_start, @options) @options[:created_at_end] = build_date_from_params(:created_at_end, @options) - @options[:notified_at_start] = build_date_from_params(:notified_at_start, @options) - @options[:notified_at_end] = build_date_from_params(:notified_at_end, @options) + @options[:updated_at_start] = build_date_from_params(:updated_at_start, @options) + @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[:is_circle] = @options[:is_circle].present? ? @options[:is_circle] == "1" : nil diff --git a/app/models/build_list/item.rb b/app/models/build_list/item.rb index e419526a9..36d7fab6c 100644 --- a/app/models/build_list/item.rb +++ b/app/models/build_list/item.rb @@ -1,7 +1,7 @@ # -*- encoding : utf-8 -*- class BuildList::Item < ActiveRecord::Base - belongs_to :build_list + belongs_to :build_list, :touch => true attr_protected :build_list_id diff --git a/app/models/build_list_observer.rb b/app/models/build_list_observer.rb index 793ff8e48..50ef167cd 100644 --- a/app/models/build_list_observer.rb +++ b/app/models/build_list_observer.rb @@ -6,7 +6,14 @@ class BuildListObserver < ActiveRecord::Observer record.started_at = Time.now if record.status == BuildServer::BUILD_STARTED if [BuildServer::BUILD_ERROR, BuildServer::SUCCESS].include? record.status # stores time interval beetwin build start and finish in seconds - record.duration = (Time.now - record.started_at).to_i + record.duration = record.current_duration + + if record.status == BuildServer::SUCCESS + # Update project average build time + build_count = record.project.build_count + new_av_time = ( record.project.average_build_time * build_count + record.duration ) / ( build_count + 1 ) + record.project.update_attributes({ :average_build_time => new_av_time, :build_count => build_count + 1 }, :without_protection => true) + end end end end diff --git a/app/models/project.rb b/app/models/project.rb index 54b7ac5ef..b02271c4d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -203,6 +203,11 @@ class Project < ActiveRecord::Base recipients end + def human_average_build_time + time = average_build_time + I18n.t("layout.projects.human_average_build_time", {:hours => (time/360).to_i, :minutes => (time/60).to_i}) + end + protected def build_path(dir) diff --git a/app/views/activity_feeds/_sidebar.html.haml b/app/views/activity_feeds/_sidebar.html.haml index 5d6c0e3a4..b1dc359f2 100644 --- a/app/views/activity_feeds/_sidebar.html.haml +++ b/app/views/activity_feeds/_sidebar.html.haml @@ -22,26 +22,11 @@ %h3= t("layout.activity_feed.my_builds_by_day") %table{:cellpadding => "0", :cellspacing => "0"} %tbody - %tr - %td.first - = link_to t("layout.build_lists.statuses.#{:build_published}"), build_lists_path(:filter => {:status => BuildList::BUILD_PUBLISHED, :notified_at => midnight}) - %td= BuildList.for_status(BuildList::BUILD_PUBLISHED).for_user(current_user).for_notified_date_period(midnight, nil).count - %tr - %td.first - = link_to t("layout.build_lists.statuses.#{:success}"), build_lists_path(:filter => {:status => BuildServer::SUCCESS, :notified_at => midnight}) - %td= BuildList.for_status(BuildServer::SUCCESS).for_user(current_user).for_notified_date_period(midnight, nil).count - %tr - %td.first - = link_to t("layout.build_lists.statuses.#{:build_started}"), build_lists_path(:filter => {:status => BuildServer::BUILD_STARTED, :notified_at => midnight}) - %td= BuildList.for_status(BuildServer::BUILD_STARTED).for_user(current_user).for_notified_date_period(midnight, nil).count - %tr - %td.first - = link_to t("layout.build_lists.statuses.#{:build_pending}"), build_lists_path(:filter => {:status => BuildList::BUILD_PENDING, :notified_at => midnight}) - %td= BuildList.for_status(BuildList::BUILD_PENDING).for_user(current_user).for_notified_date_period(midnight, nil).count - %tr - %td.first - = link_to t("layout.build_lists.statuses.#{:build_error}"), build_lists_path(:filter => {:status => BuildServer::BUILD_ERROR, :notified_at => midnight}) - %td= BuildList.for_status(BuildServer::BUILD_ERROR).for_user(current_user).for_notified_date_period(midnight, nil).count + - ['BuildList::BUILD_PUBLISHED', 'BuildServer::SUCCESS', 'BuildServer::BUILD_STARTED', 'BuildList::BUILD_PENDING', 'BuildServer::BUILD_ERROR'].each do |state| + %tr + %td.first + = link_to t("layout.build_lists.statuses.#{state.demodulize.downcase}"), build_lists_path(:filter => {:status => state.constantize, :updated_at => midnight}) + %td= BuildList.for_status(state.constantize).for_user(current_user).for_notified_date_period(midnight, nil).count %tr %td.first = link_to t("layout.activity_feed.all_my_builds"), build_lists_path diff --git a/app/views/activity_feeds/partials/_build_list_notification.haml b/app/views/activity_feeds/partials/_build_list_notification.haml index aa6ddebd7..71cc37532 100644 --- a/app/views/activity_feeds/partials/_build_list_notification.haml +++ b/app/views/activity_feeds/partials/_build_list_notification.haml @@ -15,5 +15,5 @@ - else ['failed', t("layout.build_lists.statuses.#{BuildList::HUMAN_STATUSES[status]}")] = raw t("notifications.bodies.build_status.#{message}", :error => error) .both - %span.date= notified_at + %span.date= updated_at .both diff --git a/app/views/build_lists/_build_list.html.haml b/app/views/build_lists/_build_list.html.haml index 04443371e..20368fd3c 100644 --- a/app/views/build_lists/_build_list.html.haml +++ b/app/views/build_lists/_build_list.html.haml @@ -6,4 +6,4 @@ %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 build_list.can_cancel? and can?(:cancel, build_list) - %td= build_list.notified_at + %td= build_list.updated_at diff --git a/app/views/build_lists/_filter.html.haml b/app/views/build_lists/_filter.html.haml index d4068759e..2f1d6f1aa 100644 --- a/app/views/build_lists/_filter.html.haml +++ b/app/views/build_lists/_filter.html.haml @@ -47,14 +47,14 @@ .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.notified_at_start") - .date_select= f.date_select(:notified_at_start, :include_blank => true, :selected => @filter.notified_at_start) - %h3.small= t("layout.build_lists.notified_at_end") - .date_select= f.date_select(:notified_at_end, :include_blank => true, :selected => @filter.notified_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") + .date_select= f.date_select(:updated_at_end, :include_blank => true, :selected => @filter.updated_at_end) %h3.small= t("layout.build_lists.project_name_search") = f.text_field :project_name %h3.small= t("layout.build_lists.bs_id_search") = f.text_field :bs_id %br %br - = f.submit t("layout.search.header") \ No newline at end of file + = f.submit t("layout.search.header") diff --git a/app/views/build_lists/_platform_build_list.html.haml b/app/views/build_lists/_platform_build_list.html.haml index 628ef7579..66e2c76a7 100644 --- a/app/views/build_lists/_platform_build_list.html.haml +++ b/app/views/build_lists/_platform_build_list.html.haml @@ -2,4 +2,4 @@ %td= link_to (platform_build_list.bs_id.present? ? platform_build_list.bs_id : t("layout.build_lists.bs_id_not_set")), platform_build_list %td= platform_build_list.human_status %td= link_to platform_build_list.project.name, platform_build_list.project - %td= platform_build_list.notified_at + %td= platform_build_list.updated_at diff --git a/app/views/build_lists/index.html.haml b/app/views/build_lists/index.html.haml index 4335c97d9..72c1482b9 100644 --- a/app/views/build_lists/index.html.haml +++ b/app/views/build_lists/index.html.haml @@ -10,7 +10,7 @@ %th.lpadding16= t("activerecord.attributes.build_list.arch") %th.lpadding16= t("activerecord.attributes.build_list.user") %th= t("layout.build_lists.action") - %th.lpadding16= t("activerecord.attributes.build_list.notified_at") + %th.lpadding16= t("activerecord.attributes.build_list.updated_at") %tbody= render @build_lists .both diff --git a/app/views/build_lists/show.html.haml b/app/views/build_lists/show.html.haml index 32fca1d6a..18a63c25f 100644 --- a/app/views/build_lists/show.html.haml +++ b/app/views/build_lists/show.html.haml @@ -46,8 +46,8 @@ .leftside.width125= t("activerecord.attributes.build_list.arch") .leftside= @build_list.arch.name .both -.leftside.width125= t("activerecord.attributes.build_list.notified_at") -.leftside= @build_list.notified_at +.leftside.width125= t("activerecord.attributes.build_list.updated_at") +.leftside= @build_list.updated_at .both .leftside.width125= t("activerecord.attributes.build_list.is_circle") .leftside= t("layout.#{@build_list.is_circle?}_") @@ -57,6 +57,13 @@ .leftside.width125 .leftside= @build_list.human_duration .both +- if !@build_list.finished? && @build_list.started_at + %br + .leftside.width125 + .leftside + = "#{@build_list.human_current_duration} / #{@build_list.project.human_average_build_time}" + .both + .hr %h3= t("layout.build_lists.items_header") - if @item_groups.blank? diff --git a/config/locales/models/build_list.en.yml b/config/locales/models/build_list.en.yml index 77bcf15a4..2ead513f0 100644 --- a/config/locales/models/build_list.en.yml +++ b/config/locales/models/build_list.en.yml @@ -14,10 +14,9 @@ en: arch_id: Architecture arch: Architecture is_circle: Recurrent build - notified_at: Notified at + updated_at: Notified at additional_repos: Additional repositories include_repos: Included repositories - updated_at: Updated on created_at: Created on pl: Repository for package storage pl_id: Repository for package storage @@ -45,8 +44,8 @@ en: current: Curent created_at_start: "Build to start on:" created_at_end: "Build to start until:" - notified_at_start: "Last update from BS on:" - notified_at_end: " Last update from BS until:" + updated_at_start: "Last update from BS on:" + updated_at_end: " Last update from BS until:" bs_id_search: 'Search by Id' project_name_search: Search by project name bs_id_not_set: Id has not been configured yet @@ -61,6 +60,7 @@ en: action: Action new_header: New build main_data: Main data + human_current_duration: Build currently takes %{hours} h. %{minutes} min. human_duration: Builded in %{hours} h. %{minutes} min. ownership: diff --git a/config/locales/models/build_list.ru.yml b/config/locales/models/build_list.ru.yml index b969bd5c2..5b5d4fd5d 100644 --- a/config/locales/models/build_list.ru.yml +++ b/config/locales/models/build_list.ru.yml @@ -14,10 +14,9 @@ ru: arch_id: Архитектура arch: Архитектура is_circle: Циклическая сборка - notified_at: Информация получена + updated_at: Информация получена additional_repos: Дополнительные репозитории include_repos: Подключаемые репозитории - updated_at: Обновлен created_at: Создан pl: Репозиторий для сохранения пакетов pl_id: Репозиторий для сохранения пакетов @@ -44,8 +43,8 @@ ru: current: Текущие created_at_start: "Время постановки на сборку с:" created_at_end: "Время постановки на сборку по:" - notified_at_start: "Время последнего обновления от BS с:" - notified_at_end: "Время последнего обновления от BS по:" + updated_at_start: "Время последнего обновления от BS с:" + updated_at_end: "Время последнего обновления от BS по:" bs_id_search: 'Поиск по Id' project_name_search: Поиск по названию проекта bs_id_not_set: Id еще не присвоен @@ -60,6 +59,8 @@ ru: action: Действие new_header: Новая сборка main_data: Основные данные + + human_current_duration: Сборка длится уже %{hours} ч. %{minutes} мин. human_duration: Собрано за %{hours} ч. %{minutes} мин. ownership: diff --git a/config/locales/models/project.en.yml b/config/locales/models/project.en.yml index 1d38c6b45..8b5e67b95 100644 --- a/config/locales/models/project.en.yml +++ b/config/locales/models/project.en.yml @@ -33,6 +33,7 @@ en: sections: Sections has_issue_description: Tracker adds a lightweight issue management system tightly integrated with your repository. has_wiki_description: Wikis are the simplest way to allow other users to contribute content. Any user can create and edit pages for documentation, examples, support or anything you wish. + human_average_build_time: Expected time is %{hours} h. %{minutes} min. git_help: cloning: Cloning the repository diff --git a/config/locales/models/project.ru.yml b/config/locales/models/project.ru.yml index 219437767..c97f6c03c 100644 --- a/config/locales/models/project.ru.yml +++ b/config/locales/models/project.ru.yml @@ -33,6 +33,7 @@ ru: sections: Разделы has_issue_description: Трэкер предоставляет лекговесный менеджер для задач по разработке Вашего проекта. has_wiki_description: Wiki - это самый простой способ предоставить другим вносить свой вклад в развитие Вашего проекта. Каждый пользователь нашего сервиса может использовать Wiki для документирования, примеров, поддержки или всего другого, в чем у Вас появится необходимость. + human_average_build_time: 'Ожидаемое время: %{hours} ч. %{minutes} мин.' diff_show_header: "%{files} с %{additions} и %{deletions}." about_subheader: "О проекте" diff --git a/db/migrate/20120413102757_build_average_time.rb b/db/migrate/20120413102757_build_average_time.rb new file mode 100644 index 000000000..07bff36e5 --- /dev/null +++ b/db/migrate/20120413102757_build_average_time.rb @@ -0,0 +1,9 @@ +class BuildAverageTime < ActiveRecord::Migration + def change + add_column :projects, :average_build_time, :integer, :null => false, :default => 0 + add_column :projects, :build_count, :integer, :null => false, :default => 0 + end + + ActivityFeed.where(:kind => 'build_list_notification').destroy_all + +end diff --git a/db/schema.rb b/db/schema.rb index 2d9c8b6da..f0fd95e9d 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 => 20120411142354) do +ActiveRecord::Schema.define(:version => 20120413102757) do create_table "activity_feeds", :force => true do |t| t.integer "user_id", :null => false @@ -190,7 +190,7 @@ ActiveRecord::Schema.define(:version => 20120411142354) 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 @@ -257,27 +257,31 @@ ActiveRecord::Schema.define(:version => 20120411142354) do t.datetime "updated_at" t.integer "owner_id" t.string "owner_type" - t.string "visibility", :default => "open" + t.string "visibility", :default => "open" t.text "description" t.string "ancestry" - t.boolean "has_issues", :default => true - t.boolean "has_wiki", :default => false + t.boolean "has_issues", :default => true t.string "srpm_file_name" t.string "srpm_content_type" t.integer "srpm_file_size" t.datetime "srpm_updated_at" - t.string "default_branch", :default => "master" - t.boolean "is_rpm", :default => true + t.boolean "has_wiki", :default => false + t.string "default_branch", :default => "master" + t.boolean "is_rpm", :default => true + 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", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "interest" t.text "more" end @@ -339,9 +343,6 @@ ActiveRecord::Schema.define(:version => 20120411142354) do 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" @@ -355,6 +356,9 @@ ActiveRecord::Schema.define(:version => 20120411142354) 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" end add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true