diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/general_controller.rb | 11 | ||||
-rw-r--r-- | app/controllers/public_body_controller.rb | 66 | ||||
-rw-r--r-- | app/models/info_request.rb | 31 | ||||
-rw-r--r-- | app/models/info_request_event.rb | 3 | ||||
-rw-r--r-- | app/models/outgoing_message.rb | 2 | ||||
-rw-r--r-- | app/models/public_body.rb | 65 | ||||
-rw-r--r-- | app/models/user.rb | 2 | ||||
-rw-r--r-- | app/views/general/_advanced_search_tips.html.erb | 5 | ||||
-rw-r--r-- | app/views/general/search.html.erb | 10 | ||||
-rw-r--r-- | app/views/public_body/_search_ahead.html.erb | 4 | ||||
-rw-r--r-- | app/views/public_body/statistics.html.erb | 6 | ||||
-rw-r--r-- | app/views/request/_describe_state.html.erb | 2 | ||||
-rw-r--r-- | app/views/request/_followup.html.erb | 7 | ||||
-rw-r--r-- | app/views/request/_sidebar.html.erb | 1 | ||||
-rw-r--r-- | app/views/request/similar.html.erb | 2 |
15 files changed, 141 insertions, 76 deletions
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb index 540f67ec9..beefef4e6 100644 --- a/app/controllers/general_controller.rb +++ b/app/controllers/general_controller.rb @@ -178,6 +178,7 @@ class GeneralController < ApplicationController @xapian_requests_hits = @xapian_requests.results.size @xapian_requests_total_hits = @xapian_requests.matches_estimated @total_hits += @xapian_requests.matches_estimated + @request_for_spelling = @xapian_requests end if @bodies @xapian_bodies = perform_search([PublicBody], @query, @sortby, nil, 5) @@ -186,6 +187,7 @@ class GeneralController < ApplicationController @xapian_bodies_hits = @xapian_bodies.results.size @xapian_bodies_total_hits = @xapian_bodies.matches_estimated @total_hits += @xapian_bodies.matches_estimated + @request_for_spelling = @xapian_bodies end if @users @xapian_users = perform_search([User], @query, @sortby, nil, 5) @@ -194,14 +196,13 @@ class GeneralController < ApplicationController @xapian_users_hits = @xapian_users.results.size @xapian_users_total_hits = @xapian_users.matches_estimated @total_hits += @xapian_users.matches_estimated + @request_for_spelling = @xapian_users end # Spelling and highight words are same for all three queries - if !@xapian_requests.nil? - @highlight_words = @xapian_requests.words_to_highlight - if !(@xapian_requests.spelling_correction =~ /[a-z]+:/) - @spelling_correction = @xapian_requests.spelling_correction - end + @highlight_words = @request_for_spelling.words_to_highlight + if !(@request_for_spelling.spelling_correction =~ /[a-z]+:/) + @spelling_correction = @request_for_spelling.spelling_correction end @track_thing = TrackThing.create_track_for_search_query(@query, @variety_postfix) diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb index cec9c4cd4..308d38e4c 100644 --- a/app/controllers/public_body_controller.rb +++ b/app/controllers/public_body_controller.rb @@ -114,8 +114,8 @@ class PublicBodyController < ApplicationController elsif @tag == 'other' category_list = PublicBodyCategories::get().tags().map{|c| "'"+c+"'"}.join(",") where_condition += base_tag_condition + " AND has_tag_string_tags.name in (#{category_list})) = 0" - elsif @tag.size == 1 - @tag.upcase! + elsif @tag.scan(/./mu).size == 1 + @tag = Unicode.upcase @tag # The first letter queries have to be done on # translations, so just indicate to add that later: first_letter = true @@ -220,12 +220,56 @@ class PublicBodyController < ApplicationController :encoding => 'utf8') end + + # This is a helper method to take data returned by the PublicBody + # model's statistics-generating methods, and converting them to + # simpler data structure that can be rendered by a Javascript + # graph library. (This could be a class method except that we need + # access to the URL helper public_body_path.) + def simplify_stats_for_graphs(data, + column, + percentages, + graph_properties) + # Copy the data, only taking known-to-be-safe keys: + result = Hash.new { |h, k| h[k] = [] } + result.update Hash[data.select do |key, value| + ['y_values', + 'y_max', + 'totals', + 'cis_below', + 'cis_above'].include? key + end] + + # Extract data about the public bodies for the x-axis, + # tooltips, and so on: + data['public_bodies'].each_with_index do |pb, i| + result['x_values'] << i + result['x_ticks'] << [i, pb.name] + result['tooltips'] << "#{pb.name} (#{result['totals'][i]})" + result['public_bodies'] << { + 'name' => pb.name, + 'url' => public_body_path(pb) + } + end + + # Set graph metadata properties, like the title, axis labels, etc. + graph_id = "#{column}-" + graph_id += graph_properties[:highest] ? 'highest' : 'lowest' + result.update({ + 'id' => graph_id, + 'x_axis' => _('Public Bodies'), + 'y_axis' => graph_properties[:y_axis], + 'errorbars' => percentages, + 'title' => graph_properties[:title] + }) + end + def statistics unless AlaveteliConfiguration::public_body_statistics_page raise ActiveRecord::RecordNotFound.new("Page not enabled") end - per_graph = 8 + per_graph = 10 minimum_requests = AlaveteliConfiguration::minimum_requests_for_statistics # Make sure minimum_requests is > 0 to avoid division-by-zero minimum_requests = [minimum_requests, 1].max @@ -275,20 +319,12 @@ class PublicBodyController < ApplicationController minimum_requests) end - data_to_draw = { - 'id' => "#{column}-#{highest ? 'highest' : 'lowest'}", - 'x_axis' => _('Public Bodies'), - 'y_axis' => graph_properties[:y_axis], - 'errorbars' => percentages, - 'title' => graph_properties[:title]} - if data - data_to_draw.update(data) - data_to_draw['x_values'] = data['public_bodies'].each_with_index.map { |pb, i| i } - data_to_draw['x_ticks'] = data['public_bodies'].each_with_index.map { |pb, i| [i, pb.name] } + @graph_list.push simplify_stats_for_graphs(data, + column, + percentages, + graph_properties) end - - @graph_list.push data_to_draw end end diff --git a/app/models/info_request.rb b/app/models/info_request.rb index aaced91a2..9463a236e 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -271,15 +271,9 @@ public # Subject lines for emails about the request def email_subject_request - # XXX pull out this general_register_office specialisation - # into some sort of separate jurisdiction dependent file - if self.public_body.url_name == 'general_register_office' - # without GQ in the subject, you just get an auto response - _('{{law_used_full}} request GQ - {{title}}',:law_used_full=>self.law_used_full,:title=>self.title.html_safe) - else - _('{{law_used_full}} request - {{title}}',:law_used_full=>self.law_used_full,:title=>self.title.html_safe) - end + _('{{law_used_full}} request - {{title}}',:law_used_full=>self.law_used_full,:title=>self.title.html_safe) end + def email_subject_followup(incoming_message = nil) if incoming_message.nil? || !incoming_message.valid_to_reply_to? || !incoming_message.subject 'Re: ' + self.email_subject_request @@ -1188,14 +1182,23 @@ public after_save :update_counter_cache after_destroy :update_counter_cache + # This method updates the count columns of the PublicBody that + # store the number of "not held", "to some extent successful" and + # "both visible and classified" requests when saving or destroying + # an InfoRequest associated with the body: def update_counter_cache PublicBody.skip_callback(:save, :after, :purge_in_cache) - self.public_body.info_requests_not_held_count = InfoRequest.where( - :public_body_id => self.public_body.id, - :described_state => 'not_held').count - self.public_body.info_requests_successful_count = InfoRequest.where( - :public_body_id => self.public_body.id, - :described_state => ['successful', 'partially_successful']).count + basic_params = { + :public_body_id => self.public_body_id, + :awaiting_description => false, + :prominence => 'normal' + } + [['info_requests_not_held_count', {:described_state => 'not_held'}], + ['info_requests_successful_count', {:described_state => ['successful', 'partially_successful']}], + ['info_requests_visible_classified_count', {}]].each do |column, extra_params| + params = basic_params.clone.update extra_params + self.public_body.send "#{column}=", InfoRequest.where(params).count + end self.public_body.without_revision do public_body.no_xapian_reindex = true public_body.save diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb index 67cdda1b4..e268b28ca 100644 --- a/app/models/info_request_event.rb +++ b/app/models/info_request_event.rb @@ -339,6 +339,9 @@ class InfoRequestEvent < ActiveRecord::Base end raise _("unknown status ") + status end + # TRANSLATORS: "Follow up" in this context means a further + # message sent by the requester to the authority after + # the initial request return _("Follow up") end diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb index e2ee696c5..6efc1d2ba 100644 --- a/app/models/outgoing_message.rb +++ b/app/models/outgoing_message.rb @@ -12,6 +12,8 @@ # last_sent_at :datetime # incoming_message_followup_id :integer # what_doing :string(255) not null +# prominence :string(255) default("normal"), not null +# prominence_reason :text # # models/outgoing_message.rb: diff --git a/app/models/public_body.rb b/app/models/public_body.rb index eba5259a8..db6359f6b 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -3,23 +3,27 @@ # # Table name: public_bodies # -# id :integer not null, primary key -# name :text not null -# short_name :text not null -# request_email :text not null -# version :integer not null -# last_edit_editor :string(255) not null -# last_edit_comment :text not null -# created_at :datetime not null -# updated_at :datetime not null -# url_name :text not null -# home_page :text default(""), not null -# notes :text default(""), not null -# first_letter :string(255) not null -# publication_scheme :text default(""), not null -# api_key :string(255) not null -# info_requests_count :integer default(0), not null -# disclosure_log :text default(""), not null +# id :integer not null, primary key +# name :text not null +# short_name :text not null +# request_email :text not null +# version :integer not null +# last_edit_editor :string(255) not null +# last_edit_comment :text not null +# created_at :datetime not null +# updated_at :datetime not null +# url_name :text not null +# home_page :text default(""), not null +# notes :text default(""), not null +# first_letter :string(255) not null +# publication_scheme :text default(""), not null +# api_key :string(255) not null +# info_requests_count :integer default(0), not null +# disclosure_log :text default(""), not null +# info_requests_successful_count :integer +# info_requests_not_held_count :integer +# info_requests_overdue_count :integer +# info_requests_visible_classified_count :integer # require 'csv' @@ -71,7 +75,7 @@ class PublicBody < ActiveRecord::Base def PublicBody.set_first_letter(instance) unless instance.name.nil? or instance.name.empty? # we use a regex to ensure it works with utf-8/multi-byte - first_letter = instance.name.scan(/^./mu)[0].upcase + first_letter = Unicode.upcase instance.name.scan(/^./mu)[0] if first_letter != instance.first_letter instance.first_letter = first_letter end @@ -190,6 +194,7 @@ class PublicBody < ActiveRecord::Base acts_as_versioned self.non_versioned_columns << 'created_at' << 'updated_at' << 'first_letter' << 'api_key' self.non_versioned_columns << 'info_requests_count' << 'info_requests_successful_count' + self.non_versioned_columns << 'info_requests_count' << 'info_requests_visible_classified_count' self.non_versioned_columns << 'info_requests_not_held_count' << 'info_requests_overdue' self.non_versioned_columns << 'info_requests_overdue_count' @@ -407,6 +412,8 @@ class PublicBody < ActiveRecord::Base fields = {} field_names.each{|name, i| fields[name] = row[i]} + yield line, fields if block_given? + name = row[field_names['name']] email = row[field_names['request_email']] next if name.nil? @@ -646,20 +653,30 @@ class PublicBody < ActiveRecord::Base end end + def self.where_clause_for_stats(minimum_requests, total_column) + # When producing statistics for public bodies, we want to + # exclude any that are tagged with 'test' - we use a + # sub-select to find the IDs of those public bodies. + test_tagged_query = "SELECT model_id FROM has_tag_string_tags" \ + " WHERE model = 'PublicBody' AND name = 'test'" + "#{total_column} >= #{minimum_requests} AND id NOT IN (#{test_tagged_query})" + end + # Return data for the 'n' public bodies with the highest (or # lowest) number of requests, but only returning data for those # with at least 'minimum_requests' requests. def self.get_request_totals(n, highest, minimum_requests) ordering = "info_requests_count" ordering += " DESC" if highest - where_clause = "info_requests_count >= #{minimum_requests}" + where_clause = where_clause_for_stats minimum_requests, 'info_requests_count' public_bodies = PublicBody.order(ordering).where(where_clause).limit(n) public_bodies.reverse! if highest y_values = public_bodies.map { |pb| pb.info_requests_count } return { 'public_bodies' => public_bodies, 'y_values' => y_values, - 'y_max' => y_values.max} + 'y_max' => y_values.max, + 'totals' => y_values} end # Return data for the 'n' public bodies with the highest (or @@ -668,11 +685,12 @@ class PublicBody < ActiveRecord::Base # percentage. This only returns data for those public bodies with # at least 'minimum_requests' requests. def self.get_request_percentages(column, n, highest, minimum_requests) - total_column = "info_requests_count" + total_column = "info_requests_visible_classified_count" ordering = "y_value" ordering += " DESC" if highest y_value_column = "(cast(#{column} as float) / #{total_column})" - where_clause = "#{total_column} >= #{minimum_requests} AND #{column} IS NOT NULL" + where_clause = where_clause_for_stats minimum_requests, total_column + where_clause += " AND #{column} IS NOT NULL" public_bodies = PublicBody.select("*, #{y_value_column} AS y_value").order(ordering).where(where_clause).limit(n) public_bodies.reverse! if highest y_values = public_bodies.map { |pb| pb.y_value.to_f } @@ -702,7 +720,8 @@ class PublicBody < ActiveRecord::Base 'y_values' => y_values, 'cis_below' => cis_below, 'cis_above' => cis_above, - 'y_max' => 100} + 'y_max' => 100, + 'totals' => original_totals} end private diff --git a/app/models/user.rb b/app/models/user.rb index d7c1c854e..2c4f87944 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -20,8 +20,6 @@ # email_bounce_message :text default(""), not null # no_limit :boolean default(FALSE), not null # receive_email_alerts :boolean default(TRUE), not null -# address :string(255) -# dob :date # require 'digest/sha1' diff --git a/app/views/general/_advanced_search_tips.html.erb b/app/views/general/_advanced_search_tips.html.erb index 08ce04439..5e19c41e0 100644 --- a/app/views/general/_advanced_search_tips.html.erb +++ b/app/views/general/_advanced_search_tips.html.erb @@ -40,7 +40,10 @@ <p><%= _("All the options below can use <strong>variety</strong> or <strong>latest_variety</strong> before the colon. For example, <strong>variety:sent</strong> will match requests which have <em>ever</em> been sent; <strong>latest_variety:sent</strong> will match only requests that are <em>currently</em> marked as sent.") %></p> <table class="status_table"> <tr><td><strong><%=search_link('variety:sent')%></strong></td><td><%= _('Original request sent') %></td></tr> - <tr><td><strong><%=search_link('variety:followup_sent')%></strong></td><td><%= _('Follow up message sent by requester') %></td></tr> + <tr><td><strong><%=search_link('variety:followup_sent')%></strong></td><td><%= # TRANSLATORS: "Follow up message" in this context means a + # further message sent by the requester to the authority after + # the initial request + _('Follow up message sent by requester') %></td></tr> <tr><td><strong><%=search_link('variety:response')%></strong></td><td><%= _('Response from a public authority') %></td></tr> <tr><td><strong><%=search_link('variety:comment')%></strong></td><td><%= _('Annotation added to request') %></td></tr> <tr><td><strong><%=search_link('variety:authority')%></strong></td><td><%= _('A public authority') %></td></tr> diff --git a/app/views/general/search.html.erb b/app/views/general/search.html.erb index d526a93c0..18f258444 100644 --- a/app/views/general/search.html.erb +++ b/app/views/general/search.html.erb @@ -116,7 +116,7 @@ <% end # if @advanced %> - <% if !@query.nil? %> + <% if !@query.nil? && @total_hits > 0 %> <p id="search_controls"> <%=link_to_unless @sortby == 'relevant', _("Show most relevant results first"), search_path([params[:query], @variety_postfix, 'relevant'], params) %> | @@ -137,6 +137,9 @@ <div style="clear:both;"></div> <% if @total_hits == 0 %> <h2><%=@title %></h2> + <% if @spelling_correction %> + <p id="did_you_mean"><%= _('Did you mean: {{correction}}', :correction => search_link(@spelling_correction)) %></p> + <% end %> <% end %> <% if not @query.nil? %> @@ -155,10 +158,7 @@ </div> <%= will_paginate WillPaginate::Collection.new(@page, @bodies_per_page, @xapian_bodies.matches_estimated) %> - <% elsif @bodies && !@query.nil? && @xapian_bodies.results.size == 0 && @page == 1 %> - <% if @spelling_correction %> - <p id="did_you_mean"><%= _('Did you mean: {{correction}}', :correction => search_link(@spelling_correction)) %></p> - <% end %> + <% elsif @variety_postfix == 'bodies' %> <p><%= raw(_('<a href="{{browse_url}}">Browse all</a> or <a href="{{add_url}}">ask us to add one</a>.', :browse_url => list_public_bodies_default_path.html_safe, :add_url => (help_requesting_path + '#missing_body').html_safe)) %></p> <% end %> </div> diff --git a/app/views/public_body/_search_ahead.html.erb b/app/views/public_body/_search_ahead.html.erb index 3d1dc8f93..2de638034 100644 --- a/app/views/public_body/_search_ahead.html.erb +++ b/app/views/public_body/_search_ahead.html.erb @@ -14,7 +14,5 @@ <% end %> </div> <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @xapian_requests.matches_estimated), :params => {:controller=>"request", :action => "select_authority"} %> + <p><%= raw(_('<a href="{{browse_url}}">Browse all</a> or <a href="{{add_url}}">ask us to add one</a>.', :browse_url => list_public_bodies_default_path.html_safe, :add_url => (help_requesting_path + '#missing_body').html_safe)) %></p> <% end %> - - - diff --git a/app/views/public_body/statistics.html.erb b/app/views/public_body/statistics.html.erb index 840af0c10..6ea253260 100644 --- a/app/views/public_body/statistics.html.erb +++ b/app/views/public_body/statistics.html.erb @@ -52,9 +52,9 @@ are due to him.") %></p> </tr> </thead> <tbody> - <% graph_data['x_ticks'].each_with_index do |pb_and_index, i| %> + <% graph_data['public_bodies'].each_with_index do |pb, i| %> <tr> - <td><%= pb_and_index[1] %></td> + <td><%= link_to pb['name'], pb['url'] %></td> <td class="statistic"><%= graph_data['y_values'][i].round %></td> </tr> <% end %> @@ -70,6 +70,6 @@ are due to him.") %></p> var graphs_data = <%= @graph_list.to_json.html_safe %>; </script> <!--[if lte IE 8]><%= javascript_include_tag 'excanvas.min.js' %><![endif]--> -<%= javascript_include_tag 'jquery.flot.min.js', 'jquery.flot.errorbars.min.js', 'jquery.flot.axislabels.js', 'stats-graphs.js' %> +<%= javascript_include_tag 'jquery.flot.min.js', 'jquery.flot.errorbars.min.js', 'jquery.flot.tickrotor.min.js', 'jquery.flot.axislabels.min.js', 'stats-graphs.js' %> </div> diff --git a/app/views/request/_describe_state.html.erb b/app/views/request/_describe_state.html.erb index 05cce013e..7b6fa9683 100644 --- a/app/views/request/_describe_state.html.erb +++ b/app/views/request/_describe_state.html.erb @@ -80,7 +80,7 @@ <% if @update_status %> <div> <%= radio_button "incoming_message", "described_state", "requires_admin", :id => 'requires_admin' + id_suffix %> - <label for="error_message<%=id_suffix%>"> + <label for="requires_admin<%=id_suffix%>"> <%= _('This request <strong>requires administrator attention</strong>') %> </label> </div> diff --git a/app/views/request/_followup.html.erb b/app/views/request/_followup.html.erb index bb099ff15..2643b767f 100644 --- a/app/views/request/_followup.html.erb +++ b/app/views/request/_followup.html.erb @@ -45,7 +45,12 @@ </div> <% end %> <% if @info_request.allow_new_responses_from == 'nobody' %> - <p><%= _('Follow ups and new responses to this request have been stopped to prevent spam. Please <a href="{{url}}">contact us</a> if you are {{user_link}} and need to send a follow up.',:user_link=>user_link(@info_request.user), :url=>help_contact_path) %></p> + + <p><%= + # TRANSLATORS: "Follow ups" in this context means further + # messages sent by the requester to the authority after + # the initial request + _('Follow ups and new responses to this request have been stopped to prevent spam. Please <a href="{{url}}">contact us</a> if you are {{user_link}} and need to send a follow up.',:user_link=>user_link(@info_request.user), :url=>help_contact_path) %></p> <% else %> <% if @internal_review %> <p> diff --git a/app/views/request/_sidebar.html.erb b/app/views/request/_sidebar.html.erb index e08f43eaa..8d4a4a2d8 100644 --- a/app/views/request/_sidebar.html.erb +++ b/app/views/request/_sidebar.html.erb @@ -60,7 +60,6 @@ <% if @xapian_similar_more %> <p><%= link_to _("More similar requests"), similar_request_path(@info_request.url_title) %></p> <% end %> - <!-- Important terms: <%= @xapian_similar.important_terms.join(" ") %> --> <% end %> <p><%= link_to _('Event history details'), request_details_path(@info_request) %></p> diff --git a/app/views/request/similar.html.erb b/app/views/request/similar.html.erb index eb7ff636d..5bdefc494 100644 --- a/app/views/request/similar.html.erb +++ b/app/views/request/similar.html.erb @@ -12,8 +12,6 @@ <%- end %> </h1> -<!-- Important terms: <%= @xapian_object.important_terms.join(" ") %> --> - <% if @xapian_object.results.empty? %> <p><%= _('No similar requests found.')%></p> <% else %> |