From 69d6de2fe7bf80bee9f3fae774179151ae69bfc1 Mon Sep 17 00:00:00 2001 From: zhitomirskiyi Date: Thu, 20 Jan 2011 15:51:37 -0800 Subject: [PATCH] added views and graph generation for statistics --- Gemfile | 4 ++ Gemfile.lock | 4 ++ app/controllers/statistics_controller.rb | 33 +++++++++++++++ app/helpers/statistics_helper.rb | 2 + app/models/statistic.rb | 21 ++++++++++ app/views/statistics/index.html.haml | 12 ++++++ app/views/statistics/show.html.haml | 13 ++++++ config/routes.rb | 4 ++ .../controllers/statistics_controller_spec.rb | 42 +++++++++++++++++++ spec/helpers/statistics_helper_spec.rb | 15 +++++++ spec/models/data_point_spec.rb | 1 - spec/models/statistic_spec.rb | 19 +++++++++ 12 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 app/controllers/statistics_controller.rb create mode 100644 app/helpers/statistics_helper.rb create mode 100644 app/views/statistics/index.html.haml create mode 100644 app/views/statistics/show.html.haml create mode 100644 spec/controllers/statistics_controller_spec.rb create mode 100644 spec/helpers/statistics_helper_spec.rb diff --git a/Gemfile b/Gemfile index 4c739a098..af63a4182 100644 --- a/Gemfile +++ b/Gemfile @@ -43,6 +43,10 @@ gem 'rest-client', '1.6.1' #Backups gem 'cloudfiles', '1.4.10', :require => false +#Statistics +gem 'gruff' +gem 'rmagick' + #Queue gem 'resque', '1.10.0' gem 'SystemTimer', '1.2.1' unless RUBY_VERSION.include? '1.9' diff --git a/Gemfile.lock b/Gemfile.lock index 95cdd3671..a6899cee5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -176,6 +176,7 @@ GEM gem_plugin (0.2.3) gherkin (2.3.3) json (~> 1.4.6) + gruff (0.3.6) haml (3.0.25) hashie (0.4.0) highline (1.6.1) @@ -292,6 +293,7 @@ GEM vegas (~> 0.1.2) rest-client (1.6.1) mime-types (>= 1.16) + rmagick (2.13.1) rspec (2.4.0) rspec-core (~> 2.4.0) rspec-expectations (~> 2.4.0) @@ -374,6 +376,7 @@ DEPENDENCIES fastercsv (= 1.5.4) fixture_builder (~> 0.2.0) fog + gruff haml (= 3.0.25) http_accept_language! jammit (= 0.5.4) @@ -389,6 +392,7 @@ DEPENDENCIES rails (= 3.0.3) resque (= 1.10.0) rest-client (= 1.6.1) + rmagick roxml! rspec (>= 2.0.0) rspec-instafail diff --git a/app/controllers/statistics_controller.rb b/app/controllers/statistics_controller.rb new file mode 100644 index 000000000..9d4c1f930 --- /dev/null +++ b/app/controllers/statistics_controller.rb @@ -0,0 +1,33 @@ +class StatisticsController < ApplicationController + before_filter :authenticate_user! + + 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 + end + + def generate_single + stat = Statistic.new(:type => "posts_per_day") + (0..15).each do |n| + data_point = DataPoint.users_with_posts_today(n) + data_point.save + stat.data_points << data_point + end + stat.compute_average + stat.save! + stat + redirect_to stat + end + + def graph + @statistic = Statistic.where(:id => params[:id]).first + send_data(@statistic.generate_graph, + :disposition => 'inline', + :type => 'image/png', + :filename => "stats.png") + end +end + diff --git a/app/helpers/statistics_helper.rb b/app/helpers/statistics_helper.rb new file mode 100644 index 000000000..2d25d41c5 --- /dev/null +++ b/app/helpers/statistics_helper.rb @@ -0,0 +1,2 @@ +module StatisticsHelper +end diff --git a/app/models/statistic.rb b/app/models/statistic.rb index 48b82e0cf..34d07749c 100644 --- a/app/models/statistic.rb +++ b/app/models/statistic.rb @@ -21,6 +21,15 @@ class Statistic < ActiveRecord::Base }.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} @@ -29,4 +38,16 @@ class Statistic < ActiveRecord::Base end }.call end + + def generate_graph + g = Gruff::Bar.new + g.title = "Posts per user today" + g.data("Users", self.distribution_as_array) + + h = {} + distribution.keys.each{|k| h[k.to_i] = k.to_s } + + g.labels = h + g.to_blob + end end diff --git a/app/views/statistics/index.html.haml b/app/views/statistics/index.html.haml new file mode 100644 index 000000000..d3137f9ca --- /dev/null +++ b/app/views/statistics/index.html.haml @@ -0,0 +1,12 @@ +-# 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 + diff --git a/app/views/statistics/show.html.haml b/app/views/statistics/show.html.haml new file mode 100644 index 000000000..a2f0048da --- /dev/null +++ b/app/views/statistics/show.html.haml @@ -0,0 +1,13 @@ +-# Copyright (c) 2010, Diaspora Inc. This file is +-# licensed under the Affero General Public License version 3 or later. See +-# the COPYRIGHT file. + +%h1 Viewing statistic + +%h3 + = "Users in sample: #{@statistic.users_in_sample}" += image_tag( "/statistics/graph/#{@statistic.id}") + +%br += link_to 'all statistics', statistics_path + diff --git a/config/routes.rb b/config/routes.rb index a3a980307..0a969fa5c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,10 @@ Diaspora::Application.routes.draw do resources :requests, :only => [:destroy, :create] resources :services + match 'statistics/generate_single' => 'statistics#generate_single' + match 'statistics/graph/:id' => 'statistics#graph' + resources :statistics + match 'notifications/read_all' => 'notifications#read_all' resources :notifications, :only => [:index, :update] resources :posts, :only => [:show], :path => '/p/' diff --git a/spec/controllers/statistics_controller_spec.rb b/spec/controllers/statistics_controller_spec.rb new file mode 100644 index 000000000..0724be0ce --- /dev/null +++ b/spec/controllers/statistics_controller_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe StatisticsController do + render_views + + before do + sign_in :user, alice + end + + before(:all) do + @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_today(n) + end + @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 '#graph' do + it 'generates a graph' do + get :graph, :id => @stat.id + response.should be_success + end + end + +end diff --git a/spec/helpers/statistics_helper_spec.rb b/spec/helpers/statistics_helper_spec.rb new file mode 100644 index 000000000..5312649e3 --- /dev/null +++ b/spec/helpers/statistics_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the StatisticsHelper. For example: +# +# describe StatisticsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe StatisticsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/data_point_spec.rb b/spec/models/data_point_spec.rb index 9f927cedd..d4b689ae5 100644 --- a/spec/models/data_point_spec.rb +++ b/spec/models/data_point_spec.rb @@ -35,5 +35,4 @@ describe DataPoint do point.key.should == 15 end end - end diff --git a/spec/models/statistic_spec.rb b/spec/models/statistic_spec.rb index f730d9d22..293f4e7bd 100644 --- a/spec/models/statistic_spec.rb +++ b/spec/models/statistic_spec.rb @@ -47,9 +47,28 @@ describe Statistic do end end + context '#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 + context '#users_in_sample' do it 'returns a count' do @stat.users_in_sample.should == 3 end end + + context '#generate_graph' do + it 'outputs a binary string' do + @stat.generate_graph.class.should == String + end + end end