Delete statistic and data point models
This commit is contained in:
parent
a7f149e399
commit
0cb218bba0
14 changed files with 11 additions and 378 deletions
|
|
@ -1,49 +0,0 @@
|
||||||
class StatisticsController < ApplicationController
|
|
||||||
before_filter :authenticate_user!
|
|
||||||
before_filter :redirect_unless_admin
|
|
||||||
|
|
||||||
def index
|
|
||||||
@statistics = Statistic.find(:all, :order => 'created_at DESC').paginate(:page => params[:page], :per_page => 15)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
@statistic = Statistic.where(:id => params[:id]).first
|
|
||||||
@distribution = @statistic.distribution_as_array
|
|
||||||
@google_chart_url = Gchart.line( :size => '700x400',
|
|
||||||
:title => "Posts on day",
|
|
||||||
:bg => 'efefef',
|
|
||||||
:legend => ['Posts'],
|
|
||||||
:data => @distribution,
|
|
||||||
:max_value => 1,
|
|
||||||
:axis_with_labels => ['x','y'],
|
|
||||||
:axis_labels => [(0..@distribution.length-1).to_a.map{|d| d%10==0 ? d : ''},
|
|
||||||
(0..10).to_a.map!{|int| int.to_f/10}]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_single
|
|
||||||
stat = Statistic.generate()
|
|
||||||
redirect_to stat
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_search
|
|
||||||
user = params[:user] || {}
|
|
||||||
user = user.delete_if {|key, value| value.blank? }
|
|
||||||
params[:user] = user
|
|
||||||
|
|
||||||
if user.keys.count == 0
|
|
||||||
@users = []
|
|
||||||
else
|
|
||||||
@users = User.where(params[:user]).all || []
|
|
||||||
end
|
|
||||||
|
|
||||||
render 'statistics/user_search'
|
|
||||||
end
|
|
||||||
|
|
||||||
def admin_inviter
|
|
||||||
Invitation.create_invitee(:identifier => params[:identifier])
|
|
||||||
flash[:notice] = "invitation sent to #{params[:identifier]}"
|
|
||||||
redirect_to 'statistics/user_search'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
module StatisticsHelper
|
|
||||||
end
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
class DataPoint < ActiveRecord::Base
|
|
||||||
belongs_to :statistic
|
|
||||||
|
|
||||||
def self.users_with_posts_on_day(time, number)
|
|
||||||
sql = ActiveRecord::Base.connection()
|
|
||||||
value = sql.execute("SELECT COUNT(*) FROM (SELECT COUNT(*) AS post_sum, person_id FROM posts WHERE created_at >= '#{(time - 1.days).utc.to_datetime}' AND created_at <= '#{time.utc.to_datetime}' GROUP BY person_id) AS t1 WHERE t1.post_sum = #{number};").first[0]
|
|
||||||
self.new(:key => number.to_s, :value => value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
class Statistic < ActiveRecord::Base
|
|
||||||
has_many :data_points, :class_name => 'DataPoint'
|
|
||||||
|
|
||||||
def compute_average
|
|
||||||
users = 0
|
|
||||||
sum = 0
|
|
||||||
self.data_points.each do |d|
|
|
||||||
sum += d.key.to_i*d.value
|
|
||||||
users += d.value
|
|
||||||
end
|
|
||||||
self.average = sum.to_f/users
|
|
||||||
end
|
|
||||||
|
|
||||||
def distribution
|
|
||||||
@dist ||= lambda {
|
|
||||||
dist = {}
|
|
||||||
self.data_points.each do |d|
|
|
||||||
dist[d.key] = d.value.to_f/users_in_sample
|
|
||||||
end
|
|
||||||
dist
|
|
||||||
}.call
|
|
||||||
end
|
|
||||||
|
|
||||||
def distribution_as_array
|
|
||||||
dist = distribution
|
|
||||||
arr = []
|
|
||||||
(0..dist.size-1).each do |key|
|
|
||||||
arr << dist[key.to_s]
|
|
||||||
end
|
|
||||||
arr
|
|
||||||
end
|
|
||||||
|
|
||||||
def users_in_sample
|
|
||||||
@users ||= lambda {
|
|
||||||
users = self.data_points.map{|d| d.value}
|
|
||||||
users.inject do |total,curr|
|
|
||||||
total += curr
|
|
||||||
end
|
|
||||||
}.call
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_graph
|
|
||||||
# need to use google's graph API
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.generate(time=Time.now, post_range=(0..50))
|
|
||||||
stat = Statistic.new(:time => time)
|
|
||||||
stat.save
|
|
||||||
post_range.each do |n|
|
|
||||||
data_point = DataPoint.users_with_posts_on_day(time,n)
|
|
||||||
data_point.statistic = stat
|
|
||||||
data_point.save
|
|
||||||
end
|
|
||||||
stat.compute_average
|
|
||||||
stat.save
|
|
||||||
stat
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
-# Copyright (c) 2010, Diaspora Inc. This file is
|
|
||||||
-# licensed under the Affero General Public License version 3 or later. See
|
|
||||||
-# the COPYRIGHT file.
|
|
||||||
|
|
||||||
%h1 Statistics
|
|
||||||
|
|
||||||
%ul
|
|
||||||
- for statistic in @statistics
|
|
||||||
%li= link_to statistic.created_at, statistic
|
|
||||||
|
|
||||||
= will_paginate @statistics
|
|
||||||
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
-# Copyright (c) 2010, Diaspora Inc. This file is
|
|
||||||
-# licensed under the Affero General Public License version 3 or later. See
|
|
||||||
-# the COPYRIGHT file.
|
|
||||||
|
|
||||||
%h3 Viewing statistic
|
|
||||||
|
|
||||||
%h2
|
|
||||||
= "Users in sample: #{@statistic.users_in_sample}"
|
|
||||||
= image_tag(@google_chart_url)
|
|
||||||
|
|
||||||
%br
|
|
||||||
= link_to 'all statistics', statistics_path
|
|
||||||
|
|
||||||
|
|
@ -14,8 +14,6 @@ Diaspora::Application.routes.draw do
|
||||||
|
|
||||||
match 'admins/user_search' => 'admins#user_search'
|
match 'admins/user_search' => 'admins#user_search'
|
||||||
match 'admins/admin_inviter' => 'admins#admin_inviter'
|
match 'admins/admin_inviter' => 'admins#admin_inviter'
|
||||||
match 'statistics/generate_single' => 'statistics#generate_single'
|
|
||||||
resources :statistics
|
|
||||||
|
|
||||||
match 'notifications/read_all' => 'notifications#read_all'
|
match 'notifications/read_all' => 'notifications#read_all'
|
||||||
resources :notifications, :only => [:index, :update]
|
resources :notifications, :only => [:index, :update]
|
||||||
|
|
|
||||||
9
db/migrate/20110301202619_drop_statistics.rb
Normal file
9
db/migrate/20110301202619_drop_statistics.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
class DropStatistics < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
drop_table :statistics
|
||||||
|
drop_table :data_points
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
end
|
||||||
|
end
|
||||||
19
db/schema.rb
19
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20110228201109) do
|
ActiveRecord::Schema.define(:version => 20110301202619) do
|
||||||
|
|
||||||
create_table "aspect_memberships", :force => true do |t|
|
create_table "aspect_memberships", :force => true do |t|
|
||||||
t.integer "aspect_id", :null => false
|
t.integer "aspect_id", :null => false
|
||||||
|
|
@ -70,16 +70,6 @@ ActiveRecord::Schema.define(:version => 20110228201109) do
|
||||||
add_index "contacts", ["user_id", "pending"], :name => "index_contacts_on_user_id_and_pending"
|
add_index "contacts", ["user_id", "pending"], :name => "index_contacts_on_user_id_and_pending"
|
||||||
add_index "contacts", ["user_id", "person_id"], :name => "index_contacts_on_user_id_and_person_id", :unique => true
|
add_index "contacts", ["user_id", "person_id"], :name => "index_contacts_on_user_id_and_person_id", :unique => true
|
||||||
|
|
||||||
create_table "data_points", :force => true do |t|
|
|
||||||
t.string "key", :null => false
|
|
||||||
t.integer "value", :null => false
|
|
||||||
t.integer "statistic_id", :null => false
|
|
||||||
t.datetime "created_at"
|
|
||||||
t.datetime "updated_at"
|
|
||||||
end
|
|
||||||
|
|
||||||
add_index "data_points", ["statistic_id"], :name => "index_data_points_on_statistic_id"
|
|
||||||
|
|
||||||
create_table "invitations", :force => true do |t|
|
create_table "invitations", :force => true do |t|
|
||||||
t.text "message"
|
t.text "message"
|
||||||
t.integer "sender_id", :null => false
|
t.integer "sender_id", :null => false
|
||||||
|
|
@ -436,13 +426,6 @@ ActiveRecord::Schema.define(:version => 20110228201109) do
|
||||||
add_index "services", ["mongo_id"], :name => "index_services_on_mongo_id"
|
add_index "services", ["mongo_id"], :name => "index_services_on_mongo_id"
|
||||||
add_index "services", ["user_id"], :name => "index_services_on_user_id"
|
add_index "services", ["user_id"], :name => "index_services_on_user_id"
|
||||||
|
|
||||||
create_table "statistics", :force => true do |t|
|
|
||||||
t.integer "average"
|
|
||||||
t.datetime "time", :null => false
|
|
||||||
t.datetime "created_at"
|
|
||||||
t.datetime "updated_at"
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "users", :force => true do |t|
|
create_table "users", :force => true do |t|
|
||||||
t.string "username"
|
t.string "username"
|
||||||
t.text "serialized_private_key"
|
t.text "serialized_private_key"
|
||||||
|
|
|
||||||
|
|
@ -55,15 +55,6 @@ namespace :statistics do
|
||||||
puts "Users with 10 or more contacts: %i" % users_with_x_contacts(9)
|
puts "Users with 10 or more contacts: %i" % users_with_x_contacts(9)
|
||||||
end
|
end
|
||||||
|
|
||||||
task :model => :environment do
|
|
||||||
stat = Statistic.new(:type => "posts_per_day")
|
|
||||||
[0..15].each do |n|
|
|
||||||
stat.data_points << DataPoint.posts_per_day(n)
|
|
||||||
end
|
|
||||||
stat.compute_average
|
|
||||||
stat.save
|
|
||||||
end
|
|
||||||
|
|
||||||
task :splunk => :environment do
|
task :splunk => :environment do
|
||||||
set_up_user_stats
|
set_up_user_stats
|
||||||
puts "event=statistic, type=users, count=#{@users}, "+
|
puts "event=statistic, type=users, count=#{@users}, "+
|
||||||
|
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe StatisticsController do
|
|
||||||
render_views
|
|
||||||
|
|
||||||
before do
|
|
||||||
AppConfig[:admins] = ['alice']
|
|
||||||
sign_in :user, alice
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
|
||||||
faker_stat = Statistic.generate
|
|
||||||
@stat = Statistic.new
|
|
||||||
5.times do |n|
|
|
||||||
bob.post(:status_message, :message => 'hi', :to => bob.aspects.first)
|
|
||||||
end
|
|
||||||
(0..10).each do |n|
|
|
||||||
@stat.data_points << DataPoint.users_with_posts_on_day(Time.now, n)
|
|
||||||
end
|
|
||||||
@stat.time = faker_stat.time
|
|
||||||
@stat.save
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#index' do
|
|
||||||
it 'returns all statistics' do
|
|
||||||
get :index
|
|
||||||
assigns[:statistics].should include @stat
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#show' do
|
|
||||||
it 'succeeds' do
|
|
||||||
get :show, :id => @stat.id
|
|
||||||
response.should be_success
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe ' sets a before filter to use #redirect_unless_admin' do
|
|
||||||
it 'redirects for non admins' do
|
|
||||||
AppConfig[:admins] = ['bob']
|
|
||||||
get :index
|
|
||||||
response.should be_redirect
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds' do
|
|
||||||
get :index
|
|
||||||
response.should be_success
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe DataPoint do
|
|
||||||
|
|
||||||
before do
|
|
||||||
@time = Time.now
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.users_with_posts_on_day' do
|
|
||||||
it 'returns a DataPoint object' do
|
|
||||||
DataPoint.users_with_posts_on_day(@time, 1).class.should == DataPoint
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns a DataPoint with non-zero value' do
|
|
||||||
point = DataPoint.users_with_posts_on_day(@time, 1)
|
|
||||||
point.value.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns a DataPoint with zero value' do
|
|
||||||
point = DataPoint.users_with_posts_on_day(@time, 15)
|
|
||||||
point.value.should == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the correct descriptor' do
|
|
||||||
point = DataPoint.users_with_posts_on_day(Time.now, 15)
|
|
||||||
point.key.should == 15.to_s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Statistic do
|
|
||||||
before do
|
|
||||||
@stat = Statistic.first
|
|
||||||
@time = Time.now
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#compute_average' do
|
|
||||||
it 'computes the average of all its DataPoints' do
|
|
||||||
@stat.compute_average.should == 16.to_f/3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#distribution' do
|
|
||||||
it 'generates a hash' do
|
|
||||||
@stat.distribution.class.should == Hash
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'correctly sets values' do
|
|
||||||
dist = @stat.distribution
|
|
||||||
[dist['1'], dist['5'], dist['10']].each do |d|
|
|
||||||
d.should == 1.to_f/3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'generates a distribution' do
|
|
||||||
values = @stat.distribution.map{|d| d[1]}
|
|
||||||
values.inject{ |sum, curr|
|
|
||||||
sum += curr
|
|
||||||
}.should == 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#distribution_as_array' do
|
|
||||||
it 'returns an array' do
|
|
||||||
@stat.distribution_as_array.class.should == Array
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns in order' do
|
|
||||||
dist = @stat.distribution_as_array
|
|
||||||
[dist[1], dist[5], dist[10]].each do |d|
|
|
||||||
d.should == 1.to_f/3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#users_in_sample' do
|
|
||||||
it 'returns a count' do
|
|
||||||
@stat.users_in_sample.should == 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#generate_graph' do
|
|
||||||
it 'outputs a binary string' do
|
|
||||||
pending "should use google graph API"
|
|
||||||
@stat.generate_graph.class.should == String
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.generate' do
|
|
||||||
before do
|
|
||||||
@time = Time.now - 1.day
|
|
||||||
|
|
||||||
1.times do |n|
|
|
||||||
p = alice.post(:status_message, :message => 'hi', :to => alice.aspects.first)
|
|
||||||
p.created_at = @time
|
|
||||||
p.save
|
|
||||||
end
|
|
||||||
|
|
||||||
5.times do |n|
|
|
||||||
p = bob.post(:status_message, :message => 'hi', :to => alice.aspects.first)
|
|
||||||
p.created_at = @time
|
|
||||||
p.save
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a Statistic with a default date and range' do
|
|
||||||
time = Time.now
|
|
||||||
Time.stub!(:now).and_return(time)
|
|
||||||
|
|
||||||
stat = Statistic.generate
|
|
||||||
stat.data_points.count.should == 51
|
|
||||||
stat.time.should == time
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'custom date' do
|
|
||||||
before do
|
|
||||||
@stat = Statistic.generate(@time)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a Statistic with a custom date' do
|
|
||||||
@stat.time.should == @time
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns only desired sampling' do
|
|
||||||
@stat.users_in_sample.should == 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'custom range' do
|
|
||||||
it 'creates a Statistic with a custom range' do
|
|
||||||
stat = Statistic.generate(Time.now, (2..32))
|
|
||||||
stat.data_points.count.should == 31
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -14,24 +14,6 @@ FixtureBuilder.configure do |fbuilder|
|
||||||
|
|
||||||
connect_users(bob, bob.aspects.first, alice, alice.aspects.first)
|
connect_users(bob, bob.aspects.first, alice, alice.aspects.first)
|
||||||
connect_users(bob, bob.aspects.first, eve, eve.aspects.first)
|
connect_users(bob, bob.aspects.first, eve, eve.aspects.first)
|
||||||
|
|
||||||
# Statistics
|
|
||||||
frodo = Factory(:user_with_aspect, :username => "frodo")
|
|
||||||
sam = Factory(:user_with_aspect, :username => "sam")
|
|
||||||
bilbo = Factory(:user_with_aspect, :username => "bilbo")
|
|
||||||
|
|
||||||
stat = Statistic.new
|
|
||||||
time = Time.now
|
|
||||||
|
|
||||||
1.times { frodo.post_at_time(time) }
|
|
||||||
5.times { sam.post_at_time(time) }
|
|
||||||
10.times { bilbo.post_at_time(time) }
|
|
||||||
|
|
||||||
(0..10).each do |n|
|
|
||||||
stat.data_points << DataPoint.users_with_posts_on_day(time, n)
|
|
||||||
end
|
|
||||||
stat.time = time
|
|
||||||
stat.save!
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue