Merge pull request #438 from abf/rosa-build:435-statistics-by-commits

#435: Commits statistics
This commit is contained in:
avokhmin 2014-10-20 20:46:19 +04:00
commit 773a21cb81
10 changed files with 101 additions and 40 deletions

View File

@ -70,6 +70,10 @@ RosaABF.controller 'StatisticsController', ['$scope', '$http', ($scope, $http) -
if $scope.statistics.issues
$scope.initIssuesChart()
# Commits
if $scope.statistics.commits
$scope.initCommitsChart()
.error (data, status, headers, config) ->
console.log 'error:'
$scope.loading = false
@ -125,6 +129,11 @@ RosaABF.controller 'StatisticsController', ['$scope', '$http', ($scope, $http) -
$scope.statistics.build_lists.build_published
]
$scope.initCommitsChart = ->
$scope.dateChart '#commits_chart', [
$scope.statistics.commits.chart
]
$scope.initPullRequestsChart = ->
$scope.dateChart '#pull_requests_chart', [
$scope.statistics.pull_requests.open,

View File

@ -11,7 +11,7 @@ module BuildListObserver
def update_statistic
Statistic.statsd_increment(
activity_at: Time.now,
key: "build_list.#{status}",
key: "#{Statistic::KEY_BUILD_LIST}.#{status}",
project_id: project_id,
user_id: user_id,
) if status_changed?

View File

@ -20,9 +20,9 @@ module Feed::Git
last_commits, commits = [[record.newrev, record.message]], []
all_commits = last_commits
else
commits = record.project.repo.commits_between(record.oldrev, record.newrev)
all_commits = commits.collect { |commit| [commit.sha, commit.message] }
last_commits = all_commits.last(3).reverse
commits = record.project.repo.commits_between(record.oldrev, record.newrev)
all_commits = commits.collect { |commit| [commit.sha, commit.message] }
last_commits = all_commits.last(3).reverse
end
kind = 'git_new_push_notification'
@ -32,7 +32,17 @@ module Feed::Git
commits = commits[0...-3]
options.merge!({other_commits_count: commits.count, other_commits: "#{commits[0].sha[0..9]}...#{commits[-1].sha[0..9]}"})
end
Comment.create_link_on_issues_from_item(record, all_commits) if all_commits.count > 0
if all_commits.count > 0
Statistic.statsd_increment(
activity_at: Time.now,
key: Statistic::KEY_COMMIT,
project_id: record.project.id,
user_id: record.user.id,
counter: all_commits.count
)
Comment.create_link_on_issues_from_item(record, all_commits)
end
end
options.merge!({user_id: record.user.id, user_name: record.user.name, user_email: record.user.email}) if record.user

View File

@ -1,4 +1,13 @@
class Statistic < ActiveRecord::Base
KEYS = [
KEY_COMMIT = 'commit',
KEY_BUILD_LIST = 'build_list',
KEY_BUILD_LIST_BUILD_STARTED = "#{KEY_BUILD_LIST}.#{BuildList::BUILD_STARTED}",
KEY_BUILD_LIST_SUCCESS = "#{KEY_BUILD_LIST}.#{BuildList::SUCCESS}",
KEY_BUILD_LIST_BUILD_ERROR = "#{KEY_BUILD_LIST}.#{BuildList::BUILD_ERROR}",
KEY_BUILD_LIST_BUILD_PUBLISHED = "#{KEY_BUILD_LIST}.#{BuildList::BUILD_PUBLISHED}"
]
belongs_to :user
belongs_to :project
@ -34,14 +43,15 @@ class Statistic < ActiveRecord::Base
scope :for_period, -> (start_date, end_date) { where(activity_at: (start_date..end_date)) }
scope :build_lists_started, -> { where(key: "build_list.#{BuildList::BUILD_STARTED}") }
scope :build_lists_success, -> { where(key: "build_list.#{BuildList::SUCCESS}") }
scope :build_lists_error, -> { where(key: "build_list.#{BuildList::BUILD_ERROR}") }
scope :build_lists_published, -> { where(key: "build_list.#{BuildList::BUILD_PUBLISHED}") }
scope :build_lists_started, -> { where(key: KEY_BUILD_LIST_BUILD_STARTED) }
scope :build_lists_success, -> { where(key: KEY_BUILD_LIST_SUCCESS) }
scope :build_lists_error, -> { where(key: KEY_BUILD_LIST_BUILD_ERROR) }
scope :build_lists_published, -> { where(key: KEY_BUILD_LIST_BUILD_PUBLISHED) }
scope :commits, -> { where(key: KEY_COMMIT) }
def self.now_statsd_increment(activity_at: nil, user_id: nil, project_id: nil, key: nil)
def self.now_statsd_increment(activity_at: nil, user_id: nil, project_id: nil, key: nil, counter: 1)
# Truncates a DateTime to the minute
activity_at = activity_at.utc.change(min: 0)
user = User.find user_id
@ -62,25 +72,7 @@ class Statistic < ActiveRecord::Base
project_id: project_id,
key: key,
activity_at: activity_at
).update_all('counter = counter + 1')
end
# TODO: remove later
def self.fill_in_build_lists
BuildList.find_each do |bl|
Statistic.now_statsd_increment({
activity_at: bl.created_at,
key: "build_list.#{BuildList::BUILD_STARTED}",
project_id: bl.project_id,
user_id: bl.user_id,
})
Statistic.now_statsd_increment({
activity_at: bl.updated_at,
key: "build_list.#{bl.status}",
project_id: bl.project_id,
user_id: bl.user_id,
})
end
).update_all(['counter = counter + ?', counter]) if user_id.present? && project_id.present?
end
def self.statsd_increment(options = {})

View File

@ -20,6 +20,10 @@ class StatisticPresenter < ApplicationPresenter
success_count: build_lists_success.sum(&:count),
build_error_count: build_lists_error.sum(&:count),
build_published_count: build_lists_published.sum(&:count),
},
commits: {
chart: prepare_collection(commits_chart),
commits_count: commits_chart.sum(&:count)
}
}
end
@ -27,29 +31,29 @@ class StatisticPresenter < ApplicationPresenter
private
def scope
@scope ||= Statistic.for_period(range_start, range_end)
end
def build_lists
@build_lists ||= scope.
@scope ||= Statistic.for_period(range_start, range_end).
select("SUM(counter) as count, date_trunc('#{ unit }', activity_at) as activity_at").
group("date_trunc('#{ unit }', activity_at)").order('activity_at')
end
def commits_chart
@commits_chart ||= scope.commits.to_a
end
def build_lists_started
@build_lists_started ||= build_lists.build_lists_started.to_a
@build_lists_started ||= scope.build_lists_started.to_a
end
def build_lists_success
@build_lists_success ||= build_lists.build_lists_success.to_a
@build_lists_success ||= scope.build_lists_success.to_a
end
def build_lists_error
@build_lists_error ||= build_lists.build_lists_error.to_a
@build_lists_error ||= scope.build_lists_error.to_a
end
def build_lists_published
@build_lists_published ||= build_lists.build_lists_published.to_a
@build_lists_published ||= scope.build_lists_published.to_a
end
def prepare_collection(items)

View File

@ -1,3 +1,8 @@
.row
.span12
%h3.text-info
= t('.header')
.row
.span8
.graph-wrapper

View File

@ -0,0 +1,26 @@
.row
.span12
%h3.text-info
= t('.header')
.row
.span8
.graph-wrapper
%h3
%span.graph-key-color1
= t('.commits_title')
.centered.graph-loading{ ng_show: 'loading' }
= image_tag 'loading-large.gif'
.no-data{ ng_hide: 'loading || statistics.commits' }
= t('.no_data')
%canvas#commits_chart{ ng_show: 'statistics.commits' }
.span3
.panel-wrapper
%h3
= t('.total_commits')
.panel-data
= image_tag 'loading-small.gif', ng_show: 'loading'
.no-data{ ng_hide: 'loading || statistics.commits.commits_count >= 0' }
= t('.no_data')
{{ statistics.commits.commits_count | number }}

View File

@ -4,4 +4,5 @@
= render 'filter'
= render 'build_lists'
= render 'commits'

View File

@ -9,9 +9,9 @@ en:
range_start_placeholder: "Select a start date"
range_separator: " and "
range_end_placeholder: "Select an end date"
no_data: "No data available"
build_lists:
header: "Build lists"
build_started_title: "Build started"
success_title: "Build complete"
build_error_title: "Build error"
@ -21,6 +21,13 @@ en:
total_success: "Total build complete"
total_build_error: "Total build error"
total_build_published: "Total build has been published"
no_data: "No data available"
commits:
header: "Commits"
commits_title: "Commits"
total_commits: "Total commits"
no_data: "No data available"
helper:
period:

View File

@ -9,9 +9,9 @@ ru:
range_start_placeholder: "Выберите начальную дату"
range_separator: " и "
range_end_placeholder: "Выберите конечную дату"
no_data: "Нет данных"
build_lists:
header: "Сборочные листы"
build_started_title: "Cобирается"
success_title: "Cобрано"
build_error_title: "Ошибка сборки"
@ -21,6 +21,13 @@ ru:
total_success: "Всего собрано"
total_build_error: "Всего ошибок сборки"
total_build_published: "Всего опубликовано"
no_data: "Нет данных"
commits:
header: "Коммиты"
commits_title: "Коммиты"
total_commits: "Всего коммитов"
no_data: "Нет данных"
helper:
period: