active_reporter 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +14 -0
- data/README.md +436 -0
- data/Rakefile +23 -0
- data/lib/active_reporter.rb +26 -0
- data/lib/active_reporter/aggregator.rb +9 -0
- data/lib/active_reporter/aggregator/array.rb +14 -0
- data/lib/active_reporter/aggregator/average.rb +9 -0
- data/lib/active_reporter/aggregator/base.rb +73 -0
- data/lib/active_reporter/aggregator/count.rb +23 -0
- data/lib/active_reporter/aggregator/count_if.rb +23 -0
- data/lib/active_reporter/aggregator/max.rb +9 -0
- data/lib/active_reporter/aggregator/min.rb +9 -0
- data/lib/active_reporter/aggregator/ratio.rb +23 -0
- data/lib/active_reporter/aggregator/sum.rb +13 -0
- data/lib/active_reporter/calculator.rb +2 -0
- data/lib/active_reporter/calculator/base.rb +19 -0
- data/lib/active_reporter/calculator/ratio.rb +9 -0
- data/lib/active_reporter/dimension.rb +8 -0
- data/lib/active_reporter/dimension/base.rb +150 -0
- data/lib/active_reporter/dimension/bin.rb +123 -0
- data/lib/active_reporter/dimension/bin/set.rb +162 -0
- data/lib/active_reporter/dimension/bin/table.rb +43 -0
- data/lib/active_reporter/dimension/category.rb +29 -0
- data/lib/active_reporter/dimension/enum.rb +32 -0
- data/lib/active_reporter/dimension/number.rb +51 -0
- data/lib/active_reporter/dimension/time.rb +93 -0
- data/lib/active_reporter/evaluator.rb +2 -0
- data/lib/active_reporter/evaluator/base.rb +17 -0
- data/lib/active_reporter/evaluator/block.rb +15 -0
- data/lib/active_reporter/inflector.rb +8 -0
- data/lib/active_reporter/invalid_params_error.rb +4 -0
- data/lib/active_reporter/report.rb +102 -0
- data/lib/active_reporter/report/aggregation.rb +297 -0
- data/lib/active_reporter/report/definition.rb +195 -0
- data/lib/active_reporter/report/metrics.rb +75 -0
- data/lib/active_reporter/report/validation.rb +106 -0
- data/lib/active_reporter/serializer.rb +7 -0
- data/lib/active_reporter/serializer/base.rb +103 -0
- data/lib/active_reporter/serializer/csv.rb +22 -0
- data/lib/active_reporter/serializer/form_field.rb +134 -0
- data/lib/active_reporter/serializer/hash_table.rb +12 -0
- data/lib/active_reporter/serializer/highcharts.rb +200 -0
- data/lib/active_reporter/serializer/nested_hash.rb +11 -0
- data/lib/active_reporter/serializer/table.rb +21 -0
- data/lib/active_reporter/tracker.rb +2 -0
- data/lib/active_reporter/tracker/base.rb +15 -0
- data/lib/active_reporter/tracker/delta.rb +9 -0
- data/lib/active_reporter/version.rb +3 -0
- data/lib/tasks/active_reporter_tasks.rake +4 -0
- data/spec/acceptance/data_spec.rb +381 -0
- data/spec/active_reporter/aggregator_spec.rb +102 -0
- data/spec/active_reporter/dimension/base_spec.rb +102 -0
- data/spec/active_reporter/dimension/bin/set_spec.rb +83 -0
- data/spec/active_reporter/dimension/bin/table_spec.rb +47 -0
- data/spec/active_reporter/dimension/bin_spec.rb +77 -0
- data/spec/active_reporter/dimension/category_spec.rb +60 -0
- data/spec/active_reporter/dimension/enum_spec.rb +94 -0
- data/spec/active_reporter/dimension/number_spec.rb +71 -0
- data/spec/active_reporter/dimension/time_spec.rb +61 -0
- data/spec/active_reporter/report_spec.rb +597 -0
- data/spec/active_reporter/serializer/hash_table_spec.rb +45 -0
- data/spec/active_reporter/serializer/highcharts_spec.rb +113 -0
- data/spec/active_reporter/serializer/table_spec.rb +62 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +26 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/site_controller.rb +11 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/author.rb +4 -0
- data/spec/dummy/app/models/comment.rb +4 -0
- data/spec/dummy/app/models/data_builder.rb +112 -0
- data/spec/dummy/app/models/post.rb +6 -0
- data/spec/dummy/app/models/post_report.rb +14 -0
- data/spec/dummy/app/views/layouts/application.html.erb +17 -0
- data/spec/dummy/app/views/site/report.html.erb +73 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +57 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/migrate/20150714202319_add_dummy_models.rb +25 -0
- data/spec/dummy/db/schema.rb +43 -0
- data/spec/dummy/db/seeds.rb +1 -0
- data/spec/dummy/log/test.log +37033 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/factories.rb +29 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/support/float.rb +8 -0
- metadata +385 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveReporter::Serializer::HashTable do
|
4
|
+
let(:report_model) do
|
5
|
+
Class.new(ActiveReporter::Report) do
|
6
|
+
report_on :Post
|
7
|
+
number_dimension :likes
|
8
|
+
time_dimension :created_at
|
9
|
+
category_dimension :title
|
10
|
+
count_aggregator :post_count
|
11
|
+
sum_aggregator :likes_count, attribute: :likes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:report) do
|
16
|
+
report_model.new(
|
17
|
+
aggregators: [:post_count, :likes_count],
|
18
|
+
groupers: %i[title created_at],
|
19
|
+
dimensions: { created_at: { bin_width: '1 day' } }
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:hash_table) do
|
24
|
+
ActiveReporter::Serializer::HashTable.new(report)
|
25
|
+
end
|
26
|
+
|
27
|
+
before do
|
28
|
+
create(:post, created_at: '2016-01-01', likes: 2, title: 'A')
|
29
|
+
create(:post, created_at: '2016-01-01', likes: 2, title: 'A')
|
30
|
+
create(:post, created_at: '2016-01-01', likes: 1, title: 'B')
|
31
|
+
create(:post, created_at: '2016-01-02', likes: 1, title: 'A')
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#report' do
|
35
|
+
it 'builds report' do
|
36
|
+
expect(hash_table.table).to eq [
|
37
|
+
{ title: 'Title', created_at: 'Created at', post_count: 'Post count', likes_count: 'Likes count' },
|
38
|
+
{ title: 'A', created_at: '2016-01-01 00:00:00 UTC', post_count: '2', likes_count: '4' },
|
39
|
+
{ title: 'A', created_at: '2016-01-02 00:00:00 UTC', post_count: '1', likes_count: '1' },
|
40
|
+
{ title: 'B', created_at: '2016-01-01 00:00:00 UTC', post_count: '1', likes_count: '1' },
|
41
|
+
{ title: 'B', created_at: '2016-01-02 00:00:00 UTC', post_count: '0', likes_count: '0' }
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveReporter::Serializer::Highcharts do
|
4
|
+
let(:report_model) do
|
5
|
+
Class.new(ActiveReporter::Report) do
|
6
|
+
report_on :Post
|
7
|
+
number_dimension :likes
|
8
|
+
time_dimension :created_at
|
9
|
+
category_dimension :title
|
10
|
+
count_aggregator :post_count
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:chart) do
|
15
|
+
ActiveReporter::Serializer::Highcharts.new(report)
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
create(:post, created_at: '2016-01-01', likes: 2, title: 'A')
|
20
|
+
create(:post, created_at: '2016-01-01', likes: 2, title: 'A')
|
21
|
+
create(:post, created_at: '2016-01-01', likes: 1, title: 'B')
|
22
|
+
create(:post, created_at: '2016-01-02', likes: 1, title: 'A')
|
23
|
+
end
|
24
|
+
|
25
|
+
def y_values(series)
|
26
|
+
series[:data].map { |d| d[:y] }
|
27
|
+
end
|
28
|
+
|
29
|
+
def filters(series)
|
30
|
+
series[:data].map { |d| d[:filters] }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#series' do
|
34
|
+
context 'with one grouper' do
|
35
|
+
let(:report) do
|
36
|
+
report_model.new(aggregators: :post_count, groupers: %i[title])
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns one series of the y values (with filters)' do
|
40
|
+
expect(chart.series.count).to eq 1
|
41
|
+
# expect(y_values(chart.series[0])).to eq [3, 1]
|
42
|
+
expect(filters(chart.series[0])).to eq [{ title: 'A' }, { title: 'B' }]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with two groupers' do
|
47
|
+
let(:report) do
|
48
|
+
report_model.new(
|
49
|
+
aggregators: :post_count,
|
50
|
+
groupers: %i[title likes],
|
51
|
+
dimensions: { likes: { bin_width: 1 } }
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns one series for each x_2 value' do
|
56
|
+
expect(chart.series.count).to eq 2
|
57
|
+
# expect(y_values(chart.series[0])).to eq [1, 1]
|
58
|
+
expect(filters(chart.series[0])).to eq [
|
59
|
+
{ title: 'A', likes: { min: 1, max: 2 } },
|
60
|
+
{ title: 'B', likes: { min: 1, max: 2 } }
|
61
|
+
]
|
62
|
+
# expect(y_values(chart.series[1])).to eq [2, 0]
|
63
|
+
expect(filters(chart.series[1])).to eq [
|
64
|
+
{ title: 'A', likes: { min: 2, max: 3 } },
|
65
|
+
{ title: 'B', likes: { min: 2, max: 3 } }
|
66
|
+
]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'with three groupers' do
|
71
|
+
let(:report) do
|
72
|
+
report_model.new(
|
73
|
+
aggregators: :post_count,
|
74
|
+
groupers: %i[title likes created_at],
|
75
|
+
dimensions: {
|
76
|
+
likes: { bin_width: 1 },
|
77
|
+
created_at: { bin_width: '1 day' }
|
78
|
+
}
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns stacks for each x_3 of groups for each x_2' do
|
83
|
+
expect(chart.series.count).to eq 4
|
84
|
+
|
85
|
+
expect(chart.series[0][:stack]).to eq '2016-01-01'
|
86
|
+
expect(chart.series[1][:stack]).to eq '2016-01-01'
|
87
|
+
expect(chart.series[2][:stack]).to eq '2016-01-02'
|
88
|
+
expect(chart.series[3][:stack]).to eq '2016-01-02'
|
89
|
+
|
90
|
+
expect(chart.series[0][:id]).to eq '[1.0, 2.0)'
|
91
|
+
expect(chart.series[1][:id]).to eq '[2.0, 3.0)'
|
92
|
+
expect(chart.series[2][:linkedTo]).to eq '[1.0, 2.0)'
|
93
|
+
expect(chart.series[3][:linkedTo]).to eq '[2.0, 3.0)'
|
94
|
+
|
95
|
+
colors = chart.series.map { |s| s[:color] }
|
96
|
+
expect(colors.all?(&:present?)).to be true
|
97
|
+
expect(colors[0]).to eq colors[2]
|
98
|
+
expect(colors[1]).to eq colors[3]
|
99
|
+
expect(colors[0]).not_to eq colors[1]
|
100
|
+
|
101
|
+
# expect(y_values(chart.series[0])).to eq [0, 1]
|
102
|
+
|
103
|
+
jan1 = Time.zone.parse('2016-01-01')
|
104
|
+
jan2 = Time.zone.parse('2016-01-02')
|
105
|
+
|
106
|
+
expect(filters(chart.series[0])).to eq [
|
107
|
+
{ title: 'A', likes: { min: 1.0, max: 2.0 }, created_at: { min: jan1, max: jan2 } },
|
108
|
+
{ title: 'B', likes: { min: 1.0, max: 2.0 }, created_at: { min: jan1, max: jan2 } }
|
109
|
+
]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveReporter::Serializer::Table do
|
4
|
+
let(:report_model) do
|
5
|
+
Class.new(ActiveReporter::Report) do
|
6
|
+
report_on :Post
|
7
|
+
number_dimension :likes
|
8
|
+
time_dimension :created_at
|
9
|
+
category_dimension :title
|
10
|
+
count_aggregator :post_count
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:report) do
|
15
|
+
report_model.new(
|
16
|
+
aggregators: :post_count,
|
17
|
+
groupers: %i[created_at likes title],
|
18
|
+
dimensions: {
|
19
|
+
created_at: { bin_width: '1 day' },
|
20
|
+
likes: { bin_width: 1 }
|
21
|
+
}
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:table) do
|
26
|
+
ActiveReporter::Serializer::Table.new(report)
|
27
|
+
end
|
28
|
+
|
29
|
+
before do
|
30
|
+
create(:post, created_at: '2016-01-01', likes: 2, title: 'A')
|
31
|
+
create(:post, created_at: '2016-01-01', likes: 2, title: 'A')
|
32
|
+
create(:post, created_at: '2016-01-01', likes: 1, title: 'B')
|
33
|
+
create(:post, created_at: '2016-01-02', likes: 1, title: 'A')
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#headers' do
|
37
|
+
it 'is a formatted list of groupers and the aggregator' do
|
38
|
+
expect(table.headers).to eq ['Created at', 'Likes', 'Title', 'Post count']
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#caption' do
|
43
|
+
it 'is a summary of the axes and the total record count' do
|
44
|
+
expect(table.caption).to eq 'Post count by Created at, Likes, and Title for 4 Posts'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#each_row' do
|
49
|
+
it 'iterates through arrays of formatted grouper values and the aggregator value' do
|
50
|
+
expect(table.each_row.to_a).to eq [
|
51
|
+
['2016-01-01', '[1.0, 2.0)', 'A', 0],
|
52
|
+
['2016-01-01', '[1.0, 2.0)', 'B', 1],
|
53
|
+
['2016-01-01', '[2.0, 3.0)', 'A', 2],
|
54
|
+
['2016-01-01', '[2.0, 3.0)', 'B', 0],
|
55
|
+
['2016-01-02', '[1.0, 2.0)', 'A', 1],
|
56
|
+
['2016-01-02', '[1.0, 2.0)', 'B', 0],
|
57
|
+
['2016-01-02', '[2.0, 3.0)', 'A', 0],
|
58
|
+
['2016-01-02', '[2.0, 3.0)', 'B', 0]
|
59
|
+
]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/spec/dummy/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
16
|
+
|
17
|
+
body { margin: 2em; }
|
18
|
+
fieldset { display: inline; }
|
19
|
+
h2 { margin: 0; }
|
20
|
+
form { margin-top: 1em; margin-bottom: 2em; }
|
21
|
+
table { width: 100%; }
|
22
|
+
select { margin-top: 2px; margin-bottom: 1px; }
|
23
|
+
.active-reporter-axis-fields { margin-bottom: 1em; }
|
24
|
+
.active-reporter-dimension-fields--number-dimension input { width: 5em; }
|
25
|
+
.active-reporter-dimension-fields--time-dimension input { width: 10em; }
|
26
|
+
.active-reporter-dimension-fields--time-dimension input:nth-child(4) { width: 5em; }
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class SiteController < ApplicationController
|
2
|
+
def report
|
3
|
+
@report = PostReport.new(params.fetch(:post_report, {}))
|
4
|
+
@csv = ActiveReporter::Serializer::Csv.new(@report)
|
5
|
+
|
6
|
+
respond_to do |format|
|
7
|
+
format.html
|
8
|
+
format.csv { send_data(csv.csv_text, filename: csv.filename) }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
class DataBuilder
|
2
|
+
class << self
|
3
|
+
def gaussian(mean, stddev)
|
4
|
+
theta = 2 * Math::PI * Random.new.rand
|
5
|
+
rho = Math.sqrt(-2 * Math.log(1 - Random.new.rand))
|
6
|
+
scale = stddev * rho
|
7
|
+
return [0, mean + scale * Math.cos(theta)].max
|
8
|
+
end
|
9
|
+
|
10
|
+
def random_title
|
11
|
+
if rand < 0.5
|
12
|
+
"#{Faker::Hacker.ingverb} #{Faker::Hacker.adjective} #{Faker::Hacker.noun}"
|
13
|
+
else
|
14
|
+
Faker::Book.title
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def build!
|
19
|
+
Post.destroy_all
|
20
|
+
Comment.destroy_all
|
21
|
+
Author.destroy_all
|
22
|
+
|
23
|
+
authors = ([
|
24
|
+
"Shay Sides",
|
25
|
+
"Teodoro Rainey",
|
26
|
+
"Norman Hanley",
|
27
|
+
"Raleigh Townes",
|
28
|
+
"Samatha Doan",
|
29
|
+
"Valeria Seward",
|
30
|
+
"Jewel Cervantes",
|
31
|
+
"Fallon Clapp",
|
32
|
+
"Kenna Marlow",
|
33
|
+
"Maurine Butterfield",
|
34
|
+
"Teresa Gonzales",
|
35
|
+
"Becky Silva",
|
36
|
+
"Frank Robertson",
|
37
|
+
"Alex Hamilton",
|
38
|
+
"Emilio Powell",
|
39
|
+
"Jerry Zimmerman",
|
40
|
+
] + 20.times.map { Faker::Name.name }).map do |name|
|
41
|
+
Author.create!(name: name)
|
42
|
+
end
|
43
|
+
|
44
|
+
titles = [
|
45
|
+
"The 17 Cutest Ways To Eat A Burrito Of The Post-Y2K Era",
|
46
|
+
"22 Problems Only Cover Bands Will Understand",
|
47
|
+
"The 26 Most Beloved Things Of The '80s",
|
48
|
+
"The 18 Greatest Facts Of 2013",
|
49
|
+
"39 Real Estate Moguls Who Absolutely Nailed It In 2013",
|
50
|
+
"34 Painful Truths Only NFL Linebackers Will Understand",
|
51
|
+
"The 43 Most Important Punctuation Marks In South America",
|
52
|
+
"The 25 Most Picturesque HBO Shows Of The Last 10 Years",
|
53
|
+
"The 45 Best Oprah-Grams From The Ocean Floor",
|
54
|
+
"20 Tweets That Look Like Miley Cyrus",
|
55
|
+
"The 44 iPhone Apps That Look Like Channing Tatum",
|
56
|
+
"The 14 Most Wanted Truths Of All Time",
|
57
|
+
"The 37 Most Courageous Horses Of The '90s"
|
58
|
+
] + 1000.times.map { random_title }
|
59
|
+
|
60
|
+
author_likeability = authors.each_with_object({}) do |author, h|
|
61
|
+
average_likes = gaussian(10, 5)
|
62
|
+
stddev_likes = gaussian(10, 2.5)
|
63
|
+
h[author] = [average_likes, stddev_likes]
|
64
|
+
end
|
65
|
+
|
66
|
+
likeability_for = Hash.new { |author_hash, author|
|
67
|
+
author_hash[author] = Hash.new { |title_hash, title|
|
68
|
+
average_likes, stddev_likes = author_likeability[author]
|
69
|
+
title_hash[title] = [average_likes * (1+rand), stddev_likes]
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
titles.each do |title|
|
74
|
+
if rand < 0.5
|
75
|
+
author = authors.sample
|
76
|
+
else
|
77
|
+
author_index = gaussian(authors.length/2, authors.length/4).to_i
|
78
|
+
author = authors[author_index % authors.length]
|
79
|
+
end
|
80
|
+
|
81
|
+
created_at = gaussian(100, 40).days.ago
|
82
|
+
likes = gaussian(*likeability_for[author][title]).to_i
|
83
|
+
status = Post.statuses.values.sample
|
84
|
+
published_at = created_at if [:published, :archived].include?(status)
|
85
|
+
category = Post.categories.values.push(nil).sample
|
86
|
+
|
87
|
+
post = Post.create!(
|
88
|
+
title: title,
|
89
|
+
created_at: created_at,
|
90
|
+
likes: likes,
|
91
|
+
author: author,
|
92
|
+
status: status,
|
93
|
+
published_at: published_at,
|
94
|
+
category: category,
|
95
|
+
)
|
96
|
+
|
97
|
+
gaussian(8, 4).to_i.times do
|
98
|
+
likes = gaussian(5, 2).to_i
|
99
|
+
author = authors.sample
|
100
|
+
created_at = post.created_at + gaussian(10, 5).days
|
101
|
+
|
102
|
+
Comment.create!(
|
103
|
+
post: post,
|
104
|
+
likes: likes,
|
105
|
+
author: author,
|
106
|
+
created_at: created_at
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|