From 2c83d0e846c709647d7308cc478ebc33c90d8a80 Mon Sep 17 00:00:00 2001 From: Jason Robinson Date: Thu, 21 Nov 2013 23:58:33 +0200 Subject: [PATCH] Statistics route with general info, some user and total posts stats. By default statistics off, enabled in settings. --- Changelog.md | 1 + app/controllers/statistics_controller.rb | 15 +++++++ app/models/user.rb | 1 + app/presenters/statistics_presenter.rb | 24 ++++++++++ config/defaults.yml | 3 ++ config/diaspora.yml.example | 9 ++++ config/routes.rb | 3 ++ .../controllers/statistics_controller_spec.rb | 23 ++++++++++ spec/models/user_spec.rb | 16 +++++++ spec/presenters/statistics_presenter_spec.rb | 44 +++++++++++++++++++ 10 files changed, 139 insertions(+) create mode 100644 app/controllers/statistics_controller.rb create mode 100644 app/presenters/statistics_presenter.rb create mode 100644 spec/controllers/statistics_controller_spec.rb create mode 100644 spec/presenters/statistics_presenter_spec.rb diff --git a/Changelog.md b/Changelog.md index 14d6be3f2..d965e4fd9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -51,6 +51,7 @@ * Added ignore user icon on user profile [#4417](https://github.com/diaspora/diaspora/pull/4417) * Improve the management of the contacts visibility settings in an aspect [#4567](https://github.com/diaspora/diaspora/pull/4567) * Add actions on aspects on the contact page [#4570](https://github.com/diaspora/diaspora/pull/4570) +* Added a statistics route with general pod information, and if enabled in pod settings, total user, half year/monthly active users and local post counts [#4602](https://github.com/diaspora/diaspora/pull/4602) # 0.2.0.0 diff --git a/app/controllers/statistics_controller.rb b/app/controllers/statistics_controller.rb new file mode 100644 index 000000000..61c999877 --- /dev/null +++ b/app/controllers/statistics_controller.rb @@ -0,0 +1,15 @@ +# Copyright (c) 2010-2011, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +class StatisticsController < ApplicationController + + respond_to :json + + def statistics + respond_to do |format| + format.json { render :json => StatisticsPresenter.new } + end + end + +end diff --git a/app/models/user.rb b/app/models/user.rb index 25afb1c7e..af682247e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -12,6 +12,7 @@ class User < ActiveRecord::Base scope :monthly_actives, lambda { |time = Time.now| logged_in_since(time - 1.month) } scope :daily_actives, lambda { |time = Time.now| logged_in_since(time - 1.day) } scope :yearly_actives, lambda { |time = Time.now| logged_in_since(time - 1.year) } + scope :halfyear_actives, lambda { |time = Time.now| logged_in_since(time - 6.month) } devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, diff --git a/app/presenters/statistics_presenter.rb b/app/presenters/statistics_presenter.rb new file mode 100644 index 000000000..b39e07768 --- /dev/null +++ b/app/presenters/statistics_presenter.rb @@ -0,0 +1,24 @@ +class StatisticsPresenter + + def as_json(options={}) + result = { + 'name' => AppConfig.settings.pod_name, + 'version' => AppConfig.version_string, + 'registrations_open' => AppConfig.settings.enable_registrations + } + if AppConfig.privacy.statistics.user_counts? + result['total_users'] = User.count + result['active_users_halfyear'] = User.halfyear_actives.count + result['active_users_monthly'] = User.monthly_actives.count + end + if AppConfig.privacy.statistics.post_counts? + result['local_posts'] = self.local_posts + end + result + end + + def local_posts + Post.where(:type => "StatusMessage").joins(:author).where("owner_id IS NOT null").count + end + +end diff --git a/config/defaults.yml b/config/defaults.yml index 9b319045a..f29bd246e 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -49,6 +49,9 @@ defaults: site_id: mixpanel_uid: chartbeat_uid: + statistics: + user_counts: false + post_counts: false settings: pod_name: 'diaspora*' enable_registrations: true diff --git a/config/diaspora.yml.example b/config/diaspora.yml.example index 83512a337..664ce143c 100644 --- a/config/diaspora.yml.example +++ b/config/diaspora.yml.example @@ -191,6 +191,15 @@ configuration: ## Section ## Chartbeat tracking #chartbeat_uid: + + ## Statistics + ## By default pod name, version and whether registrations are + ## open or not is reported. Enable more statistics below. + statistics: ## Section + ## Local user total and 6 month active counts + #user_counts: true + ## Local post total count + #post_counts: true ## General settings settings: ## Section diff --git a/config/routes.rb b/config/routes.rb index a3c9b6c70..471a708de 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -228,6 +228,9 @@ Diaspora::Application.routes.draw do #Protocol Url get 'protocol' => redirect("http://wiki.diasporafoundation.org/Federation_Protocol_Overview") + + #Statistics + get :statistics, controller: :statistics # Startpage root :to => 'home#show' diff --git a/spec/controllers/statistics_controller_spec.rb b/spec/controllers/statistics_controller_spec.rb new file mode 100644 index 000000000..8fb06c122 --- /dev/null +++ b/spec/controllers/statistics_controller_spec.rb @@ -0,0 +1,23 @@ +# Copyright (c) 2010-2011, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +require 'spec_helper' + +describe StatisticsController do + + describe '#statistics' do + + it 'responds to format json' do + get :statistics, :format => 'json' + response.code.should == '200' + end + + it 'contains json' do + get :statistics, :format => 'json' + json = JSON.parse(response.body) + json['name'].should be_present + end + end + +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 9e3c62d24..9974ae843 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -94,6 +94,22 @@ describe User do User.daily_actives.should_not include(user) end end + + describe 'halfyear_actives' do + it 'returns list which includes users who latest signed in within half a year' do + user = FactoryGirl.build(:user) + user.last_sign_in_at = Time.now - 4.month + user.save + User.halfyear_actives.should include user + end + + it 'returns list which does not include users who did not sign in within the last half a year' do + user = FactoryGirl.build(:user) + user.last_sign_in_at = Time.now - 7.month + user.save + User.halfyear_actives.should_not include user + end + end context 'callbacks' do describe '#save_person!' do diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb new file mode 100644 index 000000000..5811b91c1 --- /dev/null +++ b/spec/presenters/statistics_presenter_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe StatisticsPresenter do + before do + @presenter = StatisticsPresenter.new + end + + describe '#as_json' do + it 'works' do + @presenter.as_json.should be_present + @presenter.as_json.should be_a Hash + end + end + + describe '#statistics contents' do + + it 'provides generic pod data in json' do + AppConfig.privacy.statistics.user_counts = false + AppConfig.privacy.statistics.post_counts = false + @presenter.as_json.should == { + "name" => AppConfig.settings.pod_name, + "version" => AppConfig.version_string, + "registrations_open" => AppConfig.settings.enable_registrations + } + end + + it 'provides generic pod data and counts in json' do + AppConfig.privacy.statistics.user_counts = true + AppConfig.privacy.statistics.post_counts = true + + @presenter.as_json.should == { + "name" => AppConfig.settings.pod_name, + "version" => AppConfig.version_string, + "registrations_open" => AppConfig.settings.enable_registrations, + "total_users" => User.count, + "active_users_halfyear" => User.halfyear_actives.count, + "active_users_monthly" => User.monthly_actives.count, + "local_posts" => @presenter.local_posts + } + end + + end + +end