#435: fetch data for BuildLists graph
This commit is contained in:
parent
71e7b3b37e
commit
af7f9c6a15
|
@ -1,7 +1,74 @@
|
|||
class StatisticsController < ApplicationController
|
||||
|
||||
RANGES = [
|
||||
RANGE_TWENTY_FOUR_HOURS = 'twenty_four_hours',
|
||||
RANGE_LAST_7_DAYS = 'last_7_days',
|
||||
RANGE_LAST_30_DAYS = 'last_30_days',
|
||||
RANGE_LAST_60_DAYS = 'last_60_days',
|
||||
RANGE_LAST_90_DAYS = 'last_90_days',
|
||||
RANGE_LAST_180_DAYS = 'last_180_days',
|
||||
RANGE_LAST_YEAR = 'last_year',
|
||||
RANGE_CUSTOM = 'custom',
|
||||
]
|
||||
|
||||
before_filter :init_variables
|
||||
|
||||
def index
|
||||
# TODO
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json do
|
||||
scope = Statistic.for_period(@range_start, @range_end)
|
||||
@build_lists = scope.build_lists(@range_start, @range_end, @unit)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_variables
|
||||
case params[:range]
|
||||
when RANGE_TWENTY_FOUR_HOURS
|
||||
@range_end = Time.now.utc
|
||||
@range_start = @range_end - 1.day
|
||||
@unit = :hour
|
||||
when RANGE_LAST_7_DAYS
|
||||
@range_end = Date.today
|
||||
@range_start = @range_end - 7.days
|
||||
@unit = :day
|
||||
when RANGE_LAST_30_DAYS
|
||||
@range_end = Date.today
|
||||
@range_start = @range_end - 30.days
|
||||
@unit = :day
|
||||
when RANGE_LAST_60_DAYS
|
||||
@range_end = Date.today
|
||||
@range_start = @range_end - 30.days
|
||||
@unit = :day
|
||||
when RANGE_LAST_90_DAYS
|
||||
@range_end = Date.today
|
||||
@range_start = @range_end - 90.days
|
||||
@unit = :day
|
||||
when RANGE_LAST_180_DAYS
|
||||
@range_end = Date.today
|
||||
@range_start = @range_end - 180.days
|
||||
@unit = :month
|
||||
when RANGE_LAST_YEAR
|
||||
@range_end = Date.today
|
||||
@range_start = @range_end - 1.year
|
||||
@unit = :month
|
||||
when RANGE_CUSTOM
|
||||
@range_start = Time.parse(params[:range_start]).utc
|
||||
@range_end = Time.parse(params[:range_end]).utc
|
||||
diff = @range_end - @range_start
|
||||
@unit =
|
||||
if diff <= 24.hours
|
||||
:hour
|
||||
elsif diff <= 90.days
|
||||
:day
|
||||
else
|
||||
:month
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,18 +1,8 @@
|
|||
module StatisticsHelper
|
||||
RANGES = %w(
|
||||
twenty_four_hours
|
||||
last_7_days
|
||||
last_30_days
|
||||
last_60_days
|
||||
last_90_days
|
||||
last_180_days
|
||||
last_year
|
||||
custom
|
||||
)
|
||||
|
||||
def statistics_range_options
|
||||
options_for_select(
|
||||
RANGES.map { |r| [I18n.t(r, scope: 'statistics.helper.period'), r] }
|
||||
StatisticsController::RANGES.map { |r| [I18n.t(r, scope: 'statistics.helper.period'), r] }
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
class Statistic < ActiveRecord::Base
|
||||
# TYPES = %w()
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :project
|
||||
|
||||
validates :user_id,
|
||||
uniqueness: { scope: [:project_id, :type, :activity_at] },
|
||||
uniqueness: { scope: [:project_id, :key, :activity_at] },
|
||||
presence: true
|
||||
|
||||
validates :email,
|
||||
|
@ -17,7 +15,7 @@ class Statistic < ActiveRecord::Base
|
|||
validates :project_name_with_owner,
|
||||
presence: true
|
||||
|
||||
validates :type,
|
||||
validates :key,
|
||||
presence: true
|
||||
|
||||
validates :counter,
|
||||
|
@ -30,30 +28,93 @@ class Statistic < ActiveRecord::Base
|
|||
:email,
|
||||
:project_id,
|
||||
:project_name_with_owner,
|
||||
:type,
|
||||
:key,
|
||||
:counter,
|
||||
:activity_at
|
||||
|
||||
def self.now_statsd_increment(options = {})
|
||||
scope :for_period, -> (start_date, end_date) { where(activity_at: (start_date..end_date)) }
|
||||
|
||||
def self.build_lists(range_start, range_end, unit)
|
||||
items = select("SUM(counter) as count, date_trunc('#{ unit }', activity_at) as activity_at").
|
||||
group("date_trunc('#{ unit }', activity_at)").order('activity_at')
|
||||
|
||||
|
||||
build_started = items.where(key: "build_list.#{BuildList::BUILD_STARTED}")
|
||||
success = items.where(key: "build_list.#{BuildList::SUCCESS}")
|
||||
build_error = items.where(key: "build_list.#{BuildList::BUILD_ERROR}")
|
||||
build_published = items.where(key: "build_list.#{BuildList::BUILD_PUBLISHED}")
|
||||
|
||||
{
|
||||
build_started: prepare_collection(build_started, range_start, range_end, unit),
|
||||
success: prepare_collection(success, range_start, range_end, unit),
|
||||
build_error: prepare_collection(build_error, range_start, range_end, unit),
|
||||
build_published: prepare_collection(build_published, range_start, range_end, unit),
|
||||
}
|
||||
end
|
||||
|
||||
def self.prepare_collection(items, range_start, range_end, unit)
|
||||
format = unit == :hour ? '%F %H:00:00' : '%F'
|
||||
items = items.map do |item|
|
||||
{ x: item.activity_at.strftime(format), y: item.count }
|
||||
end
|
||||
if items.size == 0
|
||||
start = range_start
|
||||
while start <= range_end
|
||||
items.unshift({ x: start.strftime(format), y: 0 })
|
||||
start += 1.send(unit)
|
||||
end
|
||||
end
|
||||
if items[0].try(:[], :x) != range_start.strftime(format)
|
||||
items.unshift({ x: range_start.strftime(format), y: 0 })
|
||||
end
|
||||
if items[-1].try(:[], :x) != range_end.strftime(format)
|
||||
items << { x: range_end.strftime(format), y: 0 }
|
||||
end
|
||||
items
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def format
|
||||
@format ||= case period.unit
|
||||
when 'hour'
|
||||
'%F %H:00:00'
|
||||
else # 'day', 'month'
|
||||
'%F'
|
||||
end
|
||||
end
|
||||
|
||||
def self.now_statsd_increment(activity_at: nil, user_id: nil, project_id: nil, key: nil)
|
||||
# Truncates a DateTime to the minute
|
||||
activity_at = options[:activity_at].utc.change(min: 0)
|
||||
user = User.find options[:user_id]
|
||||
project = Project.find options[:project_id]
|
||||
activity_at = activity_at.utc.change(min: 0)
|
||||
user = User.find user_id
|
||||
project = Project.find project_id
|
||||
Statistic.create(
|
||||
user: user,
|
||||
user_id: user_id,
|
||||
email: user.email,
|
||||
project: project,
|
||||
project_id: project_id,
|
||||
project_name_with_owner: project.name_with_owner,
|
||||
type: options[:type],
|
||||
key: key,
|
||||
activity_at: activity_at
|
||||
)
|
||||
ensure
|
||||
Statistic.where(
|
||||
user_id: options[:user_id],
|
||||
project_id: options[:project_id],
|
||||
type: options[:type],
|
||||
user_id: user_id,
|
||||
project_id: project_id,
|
||||
key: key,
|
||||
activity_at: activity_at
|
||||
).update_all('counter = counter + ?', options[:counter])
|
||||
).update_all('counter = counter + 1')
|
||||
end
|
||||
|
||||
def self.fill_in
|
||||
BuildList.find_each do |bl|
|
||||
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
|
||||
end
|
||||
|
||||
def self.statsd_increment(options = {})
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
= image_tag 'loading-large.gif'
|
||||
.no-data{ ng_hide: 'loading || statistics.build_lists' }
|
||||
= t('.no_data')
|
||||
%canvas#build_lists_chart ng-show='statistics.build_lists'
|
||||
%canvas#build_lists_chart{ ng_show: 'statistics.build_lists' }
|
||||
|
||||
.span3
|
||||
.panel-wrapper
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
json.build_lists @build_lists
|
|
@ -15,6 +15,11 @@ en:
|
|||
total_user_sessions: "Total user sessions"
|
||||
no_data: "No data available"
|
||||
|
||||
build_lists:
|
||||
build_started_title: "Build started"
|
||||
success_title: "Build complete"
|
||||
build_error_title: "Build error"
|
||||
build_published_title: "Build has been published"
|
||||
|
||||
helper:
|
||||
period:
|
||||
|
|
|
@ -5,7 +5,7 @@ class CreateStatistics < ActiveRecord::Migration
|
|||
t.string :email, null: false
|
||||
t.integer :project_id, null: false
|
||||
t.string :project_name_with_owner, null: false
|
||||
t.string :type, null: false
|
||||
t.string :key, null: false
|
||||
t.integer :counter, null: false, default: 0
|
||||
t.datetime :activity_at, null: false
|
||||
|
||||
|
@ -15,13 +15,13 @@ class CreateStatistics < ActiveRecord::Migration
|
|||
|
||||
add_index :statistics, :user_id
|
||||
add_index :statistics, :project_id
|
||||
add_index :statistics, :type
|
||||
add_index :statistics, [:user_id, :type, :activity_at]
|
||||
add_index :statistics, [:project_id, :type, :activity_at]
|
||||
add_index :statistics, [:type, :activity_at]
|
||||
add_index :statistics, :key
|
||||
add_index :statistics, [:user_id, :key, :activity_at]
|
||||
add_index :statistics, [:project_id, :key, :activity_at]
|
||||
add_index :statistics, [:key, :activity_at]
|
||||
add_index :statistics, :activity_at
|
||||
|
||||
add_index :statistics, [:user_id, :project_id, :type, :activity_at], unique: true,
|
||||
add_index :statistics, [:user_id, :project_id, :key, :activity_at], unique: true,
|
||||
name: 'index_statistics_on_all_keys'
|
||||
end
|
||||
|
||||
|
|
12
db/schema.rb
12
db/schema.rb
|
@ -586,18 +586,18 @@ ActiveRecord::Schema.define(version: 20141006182907) do
|
|||
t.string "email", null: false
|
||||
t.integer "project_id", null: false
|
||||
t.string "project_name_with_owner", null: false
|
||||
t.string "type", null: false
|
||||
t.string "key", null: false
|
||||
t.integer "counter", default: 0, null: false
|
||||
t.datetime "activity_at", null: false
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.index ["activity_at"], :name => "index_statistics_on_activity_at"
|
||||
t.index ["project_id", "type", "activity_at"], :name => "index_statistics_on_project_id_and_type_and_activity_at"
|
||||
t.index ["key", "activity_at"], :name => "index_statistics_on_key_and_activity_at"
|
||||
t.index ["key"], :name => "index_statistics_on_key"
|
||||
t.index ["project_id", "key", "activity_at"], :name => "index_statistics_on_project_id_and_key_and_activity_at"
|
||||
t.index ["project_id"], :name => "index_statistics_on_project_id"
|
||||
t.index ["type", "activity_at"], :name => "index_statistics_on_type_and_activity_at"
|
||||
t.index ["type"], :name => "index_statistics_on_type"
|
||||
t.index ["user_id", "project_id", "type", "activity_at"], :name => "index_statistics_on_all_keys", :unique => true
|
||||
t.index ["user_id", "type", "activity_at"], :name => "index_statistics_on_user_id_and_type_and_activity_at"
|
||||
t.index ["user_id", "key", "activity_at"], :name => "index_statistics_on_user_id_and_key_and_activity_at"
|
||||
t.index ["user_id", "project_id", "key", "activity_at"], :name => "index_statistics_on_all_keys", :unique => true
|
||||
t.index ["user_id"], :name => "index_statistics_on_user_id"
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue