aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/public_body.rb28
-rw-r--r--config/initializers/alaveteli.rb1
-rw-r--r--lib/date_quarter.rb22
-rw-r--r--lib/tasks/stats.rake55
-rw-r--r--spec/lib/date_quarter_spec.rb29
5 files changed, 135 insertions, 0 deletions
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 9cb344f14..03ec270ee 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -60,6 +60,34 @@ class PublicBody < ActiveRecord::Base
translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme
+ # Public: Search for Public Bodies whose name, short_name, request_email or
+ # tags contain the given query
+ #
+ # query - String to query the searchable fields
+ # locale - String to specify the language of the seach query
+ # (default: I18n.locale)
+ #
+ # Returns an ActiveRecord::Relation
+ def self.search(query, locale = I18n.locale)
+ locale = locale.to_s.gsub('-', '_') # Clean the locale string
+
+ sql = <<-SQL
+ (
+ lower(public_body_translations.name) like lower('%'||?||'%')
+ OR lower(public_body_translations.short_name) like lower('%'||?||'%')
+ OR lower(public_body_translations.request_email) like lower('%'||?||'%' )
+ OR lower(has_tag_string_tags.name) like lower('%'||?||'%' )
+ )
+ AND has_tag_string_tags.model_id = public_bodies.id
+ AND has_tag_string_tags.model = 'PublicBody'
+ AND (public_body_translations.locale = ?)
+ SQL
+
+ PublicBody.joins(:translations, :tags).
+ where([sql, query, query, query, query, locale]).
+ uniq
+ end
+
# Convenience methods for creating/editing translations via forms
def find_translation_by_locale(locale)
self.translations.find_by_locale(locale)
diff --git a/config/initializers/alaveteli.rb b/config/initializers/alaveteli.rb
index c7672d05b..e909013aa 100644
--- a/config/initializers/alaveteli.rb
+++ b/config/initializers/alaveteli.rb
@@ -52,6 +52,7 @@ require 'alaveteli_localization'
require 'message_prominence'
require 'theme'
require 'xapian_queries'
+require 'date_quarter'
AlaveteliLocalization.set_locales(AlaveteliConfiguration::available_locales,
AlaveteliConfiguration::default_locale)
diff --git a/lib/date_quarter.rb b/lib/date_quarter.rb
new file mode 100644
index 000000000..ac159b420
--- /dev/null
+++ b/lib/date_quarter.rb
@@ -0,0 +1,22 @@
+module DateQuarter
+ extend self
+
+ def quarters_between(start_at, finish_at)
+ results = []
+
+ quarter_start = start_at.beginning_of_quarter
+ quarter_end = start_at.end_of_quarter
+
+ while quarter_end <= finish_at.end_of_quarter do
+ # Collect these
+ results << [quarter_start, quarter_end]
+
+ # Update dates
+ quarter_start = quarter_end + 1.second
+ quarter_end = quarter_start.end_of_quarter
+ end
+
+ results
+ end
+
+end
diff --git a/lib/tasks/stats.rake b/lib/tasks/stats.rake
index 38eb15996..f09594529 100644
--- a/lib/tasks/stats.rake
+++ b/lib/tasks/stats.rake
@@ -97,6 +97,61 @@ namespace :stats do
end
end
+ desc <<-DESC
+Prints the per-quarter number of created FOI Requests made to each Public Body found by the query.
+Specify the search query as QUERY='london school'
+DESC
+ task :number_of_requests_created => :environment do
+ query = ENV['QUERY']
+ start_at = PublicBody.minimum(:created_at)
+ finish_at = PublicBody.maximum(:created_at)
+ public_bodies = PublicBody.search(query)
+ quarters = DateQuarter.quarters_between(start_at, finish_at)
+
+ # Headers
+ headers = ['Body'] + quarters.map { |date_tuple| date_tuple.join('~') }
+ puts headers.join(",")
+
+ public_bodies.each do |body|
+ stats = quarters.map do |quarter|
+ conditions = ['created_at >= ? AND created_at < ?', quarter[0], quarter[1]]
+ count = body.info_requests.count(:conditions => conditions)
+ count ? count : 0
+ end
+
+ row = [body.name] + stats
+ puts row.join(",")
+ end
+ end
+
+ desc <<-DESC
+Prints the per-quarter number of successful FOI Requests made to each Public Body found by the query.
+Specify the search query as QUERY='london school'
+DESC
+ task :number_of_requests_successful => :environment do
+ query = ENV['QUERY']
+ start_at = PublicBody.minimum(:created_at)
+ finish_at = PublicBody.maximum(:created_at)
+ public_bodies = PublicBody.search(query)
+ quarters = DateQuarter.quarters_between(start_at, finish_at)
+
+ # Headers
+ headers = ['Body'] + quarters.map { |date_tuple| date_tuple.join('~') }
+ puts headers.join(",")
+
+ public_bodies.each do |body|
+ stats = quarters.map do |quarter|
+ conditions = ['created_at >= ? AND created_at < ? AND described_state = ?',
+ quarter[0], quarter[1], 'successful']
+ count = body.info_requests.count(:conditions => conditions)
+ count ? count : 0
+ end
+
+ row = [body.name] + stats
+ puts row.join(",")
+ end
+ end
+
desc 'Update statistics in the public_bodies table'
task :update_public_bodies_stats => :environment do
verbose = ENV['VERBOSE'] == '1'
diff --git a/spec/lib/date_quarter_spec.rb b/spec/lib/date_quarter_spec.rb
new file mode 100644
index 000000000..29c2eb28d
--- /dev/null
+++ b/spec/lib/date_quarter_spec.rb
@@ -0,0 +1,29 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe DateQuarter do
+ include DateQuarter
+
+ describe :quarters_between do
+
+ it 'returns all the quarters in a year' do
+ # This is a bit of a convoluted spec, since we have to convert each
+ # Time in to an Integer to make a reasonable comparison
+ # See http://makandracards.com/makandra/1057-why-two-ruby-time-objects-are-not-equal-although-they-appear-to-be
+ start = Time.parse('2014-01-01')
+ finish = Time.parse('2014-12-31')
+
+ expected = [['Wed Jan 01 00:00:00 +0000 2014', 'Mon Mar 31 23:59:59 +0000 2014'],
+ ['Tue Apr 01 00:00:00 +0000 2014', 'Mon Jun 30 23:59:59 +0000 2014'],
+ ['Tue Jul 01 00:00:00 +0000 2014', 'Tue Sep 30 23:59:59 +0000 2014'],
+ ['Wed Oct 01 00:00:00 +0000 2014', 'Wed Dec 31 23:59:59 +0000 2014']].
+ map { |pair| [Time.parse(pair[0]).to_i, Time.parse(pair[1]).to_i] }
+
+ quarters_between(start, finish).each_with_index do |pair, i|
+ pair.map!(&:to_i)
+ pair.should == expected[i]
+ end
+ end
+
+ end
+
+end