aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/responsive/_footer_layout.scss4
-rw-r--r--app/assets/stylesheets/responsive/_global_style.scss5
-rw-r--r--app/controllers/admin_request_controller.rb7
-rw-r--r--app/controllers/api_controller.rb166
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/comment_controller.rb2
-rw-r--r--app/controllers/general_controller.rb12
-rw-r--r--app/controllers/public_body_change_requests_controller.rb12
-rw-r--r--app/controllers/public_body_controller.rb88
-rw-r--r--app/controllers/request_controller.rb16
-rw-r--r--app/controllers/services_controller.rb2
-rw-r--r--app/controllers/track_controller.rb12
-rw-r--r--app/controllers/user_controller.rb12
-rw-r--r--app/helpers/application_helper.rb25
-rw-r--r--app/helpers/date_time_helper.rb69
-rw-r--r--app/helpers/highlight_helper.rb98
-rwxr-xr-xapp/helpers/link_to_helper.rb83
-rw-r--r--app/mailers/outgoing_mailer.rb8
-rw-r--r--app/mailers/request_mailer.rb8
-rw-r--r--app/models/comment.rb2
-rw-r--r--app/models/foi_attachment.rb2
-rw-r--r--app/models/incoming_message.rb20
-rw-r--r--app/models/info_request.rb20
-rw-r--r--app/models/info_request_event.rb8
-rw-r--r--app/models/mail_server_log.rb2
-rw-r--r--app/models/outgoing_message.rb2
-rw-r--r--app/models/post_redirect.rb2
-rw-r--r--app/models/profile_photo.rb2
-rw-r--r--app/models/public_body.rb46
-rw-r--r--app/models/track_thing.rb4
-rw-r--r--app/models/user.rb6
-rw-r--r--app/views/admin_general/index.html.erb2
-rw-r--r--app/views/admin_request/edit.html.erb8
-rw-r--r--app/views/general/_frontpage_bodies_list.html.erb5
-rw-r--r--app/views/general/_frontpage_new_request.html.erb2
-rw-r--r--app/views/general/_frontpage_requests_list.html.erb5
-rw-r--r--app/views/general/_frontpage_search_box.html.erb3
-rw-r--r--app/views/general/_locale_switcher.html.erb2
-rw-r--r--app/views/general/_responsive_topnav.html.erb2
-rw-r--r--app/views/general/_topnav.html.erb4
-rw-r--r--app/views/public_body/_list_sidebar_extra.html.erb5
-rw-r--r--app/views/public_body/show.html.erb5
-rw-r--r--app/views/public_body/statistics.html.erb6
-rw-r--r--app/views/public_body_change_requests/new.html.erb5
-rw-r--r--app/views/request/_sidebar_request_listing.html.erb2
-rw-r--r--app/views/request/_view_html_stylesheet.html.erb9
-rw-r--r--app/views/request/upload_response.html.erb6
-rw-r--r--app/views/track_mailer/event_digest.text.erb8
-rw-r--r--app/views/user/_user_listing_single.html.erb2
-rw-r--r--app/views/user/show.html.erb2
50 files changed, 511 insertions, 321 deletions
diff --git a/app/assets/stylesheets/responsive/_footer_layout.scss b/app/assets/stylesheets/responsive/_footer_layout.scss
index 2b0c956fa..55b6839c2 100644
--- a/app/assets/stylesheets/responsive/_footer_layout.scss
+++ b/app/assets/stylesheets/responsive/_footer_layout.scss
@@ -45,6 +45,10 @@
img {
display: inherit;
+ @include lte-ie7 {
+ display: block;
+ }
}
+
}
}
diff --git a/app/assets/stylesheets/responsive/_global_style.scss b/app/assets/stylesheets/responsive/_global_style.scss
index 5b268f3a6..290591b5f 100644
--- a/app/assets/stylesheets/responsive/_global_style.scss
+++ b/app/assets/stylesheets/responsive/_global_style.scss
@@ -222,4 +222,7 @@ div.pagination {
}
-
+/* Search result highlighting */
+.highlight {
+ background:#FF0;
+}
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index fc291d998..21120e4ad 100644
--- a/app/controllers/admin_request_controller.rb
+++ b/app/controllers/admin_request_controller.rb
@@ -100,7 +100,8 @@ class AdminRequestController < AdminController
@info_request.fully_destroy
# expire cached files
expire_for_request(@info_request)
- flash[:notice] = "Request #{url_title} has been completely destroyed. Email of user who made request: " + user.email
+ email = user.try(:email) ? user.email : 'This request is external so has no associated user'
+ flash[:notice] = "Request #{ url_title } has been completely destroyed. Email of user who made request: #{ email }"
redirect_to admin_request_list_url
end
@@ -199,7 +200,7 @@ class AdminRequestController < AdminController
end
# Bejeeps, look, sometimes a URL is something that belongs in a controller, jesus.
- # XXX hammer this square peg into the round MVC hole
+ # TODO: hammer this square peg into the round MVC hole
post_redirect = PostRedirect.new(
:uri => upload_response_url(:url_title => info_request.url_title),
:user_id => user.id)
@@ -253,7 +254,7 @@ class AdminRequestController < AdminController
end
info_request_event.described_state = 'waiting_clarification'
info_request_event.calculated_state = 'waiting_clarification'
- # XXX deliberately don't update described_at so doesn't reenter search?
+ # TODO: deliberately don't update described_at so doesn't reenter search?
info_request_event.save!
flash[:notice] = "Old response marked as having been a clarification"
diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb
index e6b0c121a..6f83d89d6 100644
--- a/app/controllers/api_controller.rb
+++ b/app/controllers/api_controller.rb
@@ -1,5 +1,9 @@
class ApiController < ApplicationController
before_filter :check_api_key
+ before_filter :check_external_request,
+ :only => [:add_correspondence, :update_state]
+ before_filter :check_request_ownership,
+ :only => [:add_correspondence, :update_state]
def show_request
@request = InfoRequest.find(params[:id])
@@ -9,16 +13,11 @@ class ApiController < ApplicationController
:id => @request.id,
:url => make_url("request", @request.url_title),
:title => @request.title,
-
:created_at => @request.created_at,
:updated_at => @request.updated_at,
-
:status => @request.calculate_status,
-
:public_body_url => make_url("body", @request.public_body.url_name),
-
:request_email => @request.incoming_email,
-
:request_text => @request.last_event_forming_initial_request.outgoing_message.body,
}
if @request.user
@@ -73,35 +72,19 @@ class ApiController < ApplicationController
'url' => make_url("request", request.url_title),
'id' => request.id
}
-
end
def add_correspondence
- request = InfoRequest.find_by_id(params[:id])
- if request.nil?
- render :json => { "errors" => ["Could not find request #{params[:id]}"] }, :status => 404
- return
- end
-
json = ActiveSupport::JSON.decode(params[:correspondence_json])
attachments = params[:attachments]
direction = json["direction"]
body = json["body"]
sent_at = json["sent_at"]
+ new_state = params["state"]
errors = []
- if !request.is_external?
- render :json => { "errors" => ["Request #{params[:id]} cannot be updated using the API"] }, :status => 500
- return
- end
-
- if request.public_body_id != @public_body.id
- render :json => { "errors" => ["You do not own request #{params[:id]}"] }, :status => 500
- return
- end
-
if !["request", "response"].include?(direction)
errors << "The direction parameter must be 'request' or 'response'"
end
@@ -116,6 +99,10 @@ class ApiController < ApplicationController
errors << "You cannot attach files to messages in the 'request' direction"
end
+ if new_state && !InfoRequest.allowed_incoming_states.include?(new_state)
+ errors << "'#{new_state}' is not a valid request state"
+ end
+
if !errors.empty?
render :json => { "errors" => errors }, :status => 500
return
@@ -125,16 +112,16 @@ class ApiController < ApplicationController
# In the 'request' direction, i.e. what we (Alaveteli) regard as outgoing
outgoing_message = OutgoingMessage.new(
- :info_request => request,
+ :info_request => @request,
:status => 'ready',
:message_type => 'followup',
:body => body,
:last_sent_at => sent_at,
:what_doing => 'normal_sort'
)
- request.outgoing_messages << outgoing_message
- request.save!
- request.log_event("followup_sent",
+ @request.outgoing_messages << outgoing_message
+ @request.save!
+ @request.log_event("followup_sent",
:api => true,
:email => nil,
:outgoing_message_id => outgoing_message.id,
@@ -154,12 +141,48 @@ class ApiController < ApplicationController
)
end
- mail = RequestMailer.external_response(request, body, sent_at, attachment_hashes)
+ mail = RequestMailer.external_response(@request, body, sent_at, attachment_hashes)
+
+ @request.receive(mail, mail.encoded, true)
- request.receive(mail, mail.encoded, true)
+ if new_state
+ # we've already checked above that the status is valid
+ # so no need to check a second time
+ event = @request.log_event("status_update",
+ { :script => "#{@public_body.name} via API",
+ :old_described_state => @request.described_state,
+ :described_state => new_state,
+ })
+ @request.set_described_state(new_state)
+ end
end
render :json => {
- 'url' => make_url("request", request.url_title),
+ 'url' => make_url("request", @request.url_title),
+ }
+ end
+
+ def update_state
+ new_state = params["state"]
+
+ if InfoRequest.allowed_incoming_states.include?(new_state)
+ ActiveRecord::Base.transaction do
+ event = @request.log_event("status_update",
+ { :script => "#{@public_body.name} on behalf of requester via API",
+ :old_described_state => @request.described_state,
+ :described_state => new_state,
+ })
+ @request.set_described_state(new_state)
+ end
+ else
+ render :json => {
+ "errors" => ["'#{new_state}' is not a valid request state" ]
+ },
+ :status => 500
+ return
+ end
+
+ render :json => {
+ 'url' => make_url("request", @request.url_title),
}
end
@@ -168,51 +191,48 @@ class ApiController < ApplicationController
raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i
since_date_str = params[:since_date]
- if since_date_str.nil?
- @events = InfoRequestEvent.find_by_sql([
- %(select info_request_events.*
- from info_requests
- join info_request_events on info_requests.id = info_request_events.info_request_id
- where info_requests.public_body_id = ?
- and info_request_events.event_type in (
- 'sent', 'followup_sent', 'resent', 'followup_resent'
- )
- order by info_request_events.created_at desc
- ), @public_body.id
- ])
- else
+ since_event_id = params[:since_event_id]
+
+ event_type_clause = "event_type in ('sent', 'followup_sent', 'resent', 'followup_resent')"
+
+ @events = InfoRequestEvent.where(event_type_clause) \
+ .joins(:info_request) \
+ .where("public_body_id = ?", @public_body.id) \
+ .includes([{:info_request => :user}, :outgoing_message]) \
+ .order('info_request_events.created_at DESC')
+
+ if since_date_str
begin
- since_date = Date.strptime(since_date_str, "%Y-%m-%d")
+ since_date = Date.strptime(since_date_str, "%Y-%m-%d")
rescue ArgumentError
- render :json => {"errors" => [
- "Parameter since_date must be in format yyyy-mm-dd (not '#{since_date_str}')" ] },
- :status => 500
- return
+ render :json => {"errors" => [
+ "Parameter since_date must be in format yyyy-mm-dd (not '#{since_date_str}')" ] },
+ :status => 500
+ return
end
- @events = InfoRequestEvent.find_by_sql([
- %(select info_request_events.*
- from info_requests
- join info_request_events on info_requests.id = info_request_events.info_request_id
- where info_requests.public_body_id = ?
- and info_request_events.event_type in (
- 'sent', 'followup_sent', 'resent', 'followup_resent'
- )
- and info_request_events.created_at >= ?
- order by info_request_events.created_at desc
- ), @public_body.id, since_date
- ])
+ @events = @events.where("info_request_events.created_at >= ?", since_date)
+ end
+
+ # We take a "since" parameter that allows the client
+ # to restrict to events more recent than a certain other event
+ if since_event_id
+ begin
+ event = InfoRequestEvent.find(since_event_id)
+ rescue ActiveRecord::RecordNotFound
+ render :json => {"errors" => [
+ "Event ID #{since_event_id} not found" ] },
+ :status => 500
+ return
+ end
+ @events = @events.where("info_request_events.created_at > ?", event.created_at)
end
+
+
if feed_type == "atom"
render :template => "api/request_events", :formats => ['atom'], :layout => false
elsif feed_type == "json"
- # For the JSON feed, we take a "since" parameter that allows the client
- # to restrict to events more recent than a certain other event
- if params[:since_event_id]
- @since_event_id = params[:since_event_id].to_i
- end
@event_data = []
@events.each do |event|
- break if event.id == @since_event_id
request = event.info_request
this_event = {
@@ -224,7 +244,6 @@ class ApiController < ApplicationController
:request_email => request.incoming_email,
:title => request.title,
:body => event.outgoing_message.body,
-
:user_name => request.user_name,
}
if request.user
@@ -246,6 +265,21 @@ class ApiController < ApplicationController
raise PermissionDenied if @public_body.nil?
end
+ def check_external_request
+ @request = InfoRequest.find_by_id(params[:id])
+ if @request.nil?
+ render :json => { "errors" => ["Could not find request #{params[:id]}"] }, :status => 404
+ elsif !@request.is_external?
+ render :json => { "errors" => ["Request #{params[:id]} cannot be updated using the API"] }, :status => 403
+ end
+ end
+
+ def check_request_ownership
+ if @request.public_body_id != @public_body.id
+ render :json => { "errors" => ["You do not own request #{params[:id]}"] }, :status => 403
+ end
+ end
+
private
def make_url(*args)
"http://" + AlaveteliConfiguration::domain + "/" + args.join("/")
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 78a82316a..0c5f5bd02 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -278,10 +278,10 @@ class ApplicationController < ActionController::Base
session[:post_redirect_token] = post_redirect.token
- # XXX what is the built in Ruby URI munging function that can do this
+ # TODO: what is the built in Ruby URI munging function that can do this
# choice of & vs. ? more elegantly than this dumb if statement?
if uri.include?("?")
- # XXX This looks odd. What would a fragment identifier be doing server-side?
+ # TODO: This looks odd. What would a fragment identifier be doing server-side?
# But it also looks harmless, so I’ll leave it just in case.
if uri.include?("#")
uri.sub!("#", "&post_redirect=1#")
diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb
index 5e39c3a2c..2c0037577 100644
--- a/app/controllers/comment_controller.rb
+++ b/app/controllers/comment_controller.rb
@@ -21,7 +21,7 @@ class CommentController < ApplicationController
end
if params[:comment]
- # XXX this check should theoretically be a validation rule in the model
+ # TODO: this check should theoretically be a validation rule in the model
@existing_comment = Comment.find_existing(@info_request.id, params[:comment][:body])
else
# Default to subscribing to request when first viewing form
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 6f0d29889..158492eb2 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -59,7 +59,7 @@ class GeneralController < ApplicationController
# Actual search
def search
- # XXX Why is this so complicated with arrays and stuff? Look at the route
+ # TODO: Why is this so complicated with arrays and stuff? Look at the route
# in config/routes.rb for comments.
combined = params[:combined].split("/")
@sortby = nil
@@ -70,7 +70,7 @@ class GeneralController < ApplicationController
else
@advanced = false
end
- # XXX currently /described isn't linked to anywhere, just used in RSS and for /list/successful
+ # TODO: currently /described isn't linked to anywhere, just used in RSS and for /list/successful
# This is because it's confusingly different from /newest - but still useful for power users.
if combined.size > 0 && (['newest', 'described', 'relevant'].include?(combined[-1]))
@sort_postfix = combined.pop
@@ -124,7 +124,7 @@ class GeneralController < ApplicationController
end
end
- # Query each type separately for separate display (XXX we are calling
+ # Query each type separately for separate display (TODO: we are calling
# perform_search multiple times and it clobbers per_page for each one,
# so set as separate var)
requests_per_page = params[:requests_per_page] ? params[:requests_per_page].to_i : 25
@@ -159,7 +159,7 @@ class GeneralController < ApplicationController
end
# Spelling and highight words are same for all three queries
- @highlight_words = @request_for_spelling.words_to_highlight
+ @highlight_words = @request_for_spelling.words_to_highlight(:regex => true, :include_original => true)
if !(@request_for_spelling.spelling_correction =~ /[a-z]+:/)
@spelling_correction = @request_for_spelling.spelling_correction
end
@@ -178,7 +178,9 @@ class GeneralController < ApplicationController
format.json { render :json => {
:alaveteli_git_commit => alaveteli_git_commit,
:alaveteli_version => ALAVETELI_VERSION,
- :ruby_version => RUBY_VERSION
+ :ruby_version => RUBY_VERSION,
+ :visible_request_count => InfoRequest.visible.count,
+ :confirmed_user_count => User.where(:email_confirmed => true).count
}}
end
end
diff --git a/app/controllers/public_body_change_requests_controller.rb b/app/controllers/public_body_change_requests_controller.rb
index 4a6c5f5cb..773308546 100644
--- a/app/controllers/public_body_change_requests_controller.rb
+++ b/app/controllers/public_body_change_requests_controller.rb
@@ -1,5 +1,7 @@
class PublicBodyChangeRequestsController < ApplicationController
+ before_filter :catch_spam, :only => [:create]
+
def create
@change_request = PublicBodyChangeRequest.from_params(params[:public_body_change_request], @user)
if @change_request.save
@@ -23,6 +25,16 @@ class PublicBodyChangeRequestsController < ApplicationController
else
@title = _('Ask us to add an authority')
end
+ end
+
+ private
+ def catch_spam
+ if params[:public_body_change_request].key?(:comment)
+ unless params[:public_body_change_request][:comment].empty?
+ redirect_to frontpage_url
+ end
+ end
end
+
end
diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb
index 862f4b318..d2c84d820 100644
--- a/app/controllers/public_body_controller.rb
+++ b/app/controllers/public_body_controller.rb
@@ -5,12 +5,11 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
-require 'fastercsv'
require 'confidence_intervals'
require 'tempfile'
class PublicBodyController < ApplicationController
- # XXX tidy this up with better error messages, and a more standard infrastructure for the redirect to canonical URL
+ # TODO: tidy this up with better error messages, and a more standard infrastructure for the redirect to canonical URL
def show
long_cache
if MySociety::Format.simplify_url_part(params[:url_name], 'body') != params[:url_name]
@@ -43,7 +42,7 @@ class PublicBodyController < ApplicationController
query = InfoRequestEvent.make_query_from_params(params.merge(:latest_status => @view))
query += " requested_from:#{@public_body.url_name}"
# Use search query for this so can collapse and paginate easily
- # XXX really should just use SQL query here rather than Xapian.
+ # TODO: really should just use SQL query here rather than Xapian.
sortby = "described"
begin
@xapian_requests = perform_search([InfoRequestEvent], query, sortby, 'request_collapse')
@@ -86,7 +85,7 @@ class PublicBodyController < ApplicationController
def list
long_cache
- # XXX move some of these tag SQL queries into has_tag_string.rb
+ # TODO: move some of these tag SQL queries into has_tag_string.rb
like_query = params[:public_body_query]
like_query = "" if like_query.nil?
@@ -109,17 +108,17 @@ class PublicBodyController < ApplicationController
# Restrict the public bodies shown according to the tag
# parameter supplied in the URL:
- if @tag.nil? or @tag == "all"
- @tag = "all"
+ if @tag.nil? || @tag == 'all'
+ @tag = 'all'
elsif @tag == 'other'
- category_list = PublicBodyCategories::get().tags().map{|c| "'"+c+"'"}.join(",")
+ category_list = PublicBodyCategories.get.tags.map{ |c| %Q('#{ c }') }.join(",")
where_condition += base_tag_condition + " AND has_tag_string_tags.name in (#{category_list})) = 0"
elsif @tag.scan(/./mu).size == 1
- @tag = Unicode.upcase @tag
+ @tag = Unicode.upcase(@tag)
# The first letter queries have to be done on
# translations, so just indicate to add that later:
first_letter = true
- elsif @tag.include?(":")
+ elsif @tag.include?(':')
name, value = HasTagString::HasTagStringTag.split_tag_into_name_value(@tag)
where_condition += base_tag_condition + " AND has_tag_string_tags.name = ? AND has_tag_string_tags.value = ?) > 0"
where_parameters.concat [name, value]
@@ -128,16 +127,16 @@ class PublicBodyController < ApplicationController
where_parameters.concat [@tag]
end
- if @tag == "all"
- @description = ""
+ if @tag == 'all'
+ @description = ''
elsif @tag.size == 1
- @description = _("beginning with ‘{{first_letter}}’", :first_letter=>@tag)
+ @description = _("beginning with ‘{{first_letter}}’", :first_letter => @tag)
else
- category_name = PublicBodyCategories::get().by_tag()[@tag]
+ category_name = PublicBodyCategories.get.by_tag[@tag]
if category_name.nil?
- @description = _("matching the tag ‘{{tag_name}}’", :tag_name=>@tag)
+ @description = _("matching the tag ‘{{tag_name}}’", :tag_name => @tag)
else
- @description = _("in the category ‘{{category_name}}’", :category_name=>category_name)
+ @description = _("in the category ‘{{category_name}}’", :category_name => category_name)
end
end
@@ -151,15 +150,15 @@ class PublicBodyController < ApplicationController
FROM public_bodies
LEFT OUTER JOIN public_body_translations as current_locale
ON (public_bodies.id = current_locale.public_body_id
- AND current_locale.locale = ? AND #{get_public_body_list_translated_condition 'current_locale', first_letter})
+ AND current_locale.locale = ? AND #{ get_public_body_list_translated_condition('current_locale', first_letter) })
LEFT OUTER JOIN public_body_translations as default_locale
ON (public_bodies.id = default_locale.public_body_id
- AND default_locale.locale = ? AND #{get_public_body_list_translated_condition 'default_locale', first_letter})
- WHERE #{where_condition} AND COALESCE(current_locale.name, default_locale.name) IS NOT NULL
+ AND default_locale.locale = ? AND #{ get_public_body_list_translated_condition('default_locale', first_letter) })
+ WHERE #{ where_condition } AND COALESCE(current_locale.name, default_locale.name) IS NOT NULL
ORDER BY display_name}
- sql = [query, underscore_locale, like_query, like_query]
+ sql = [query, underscore_locale, like_query, like_query, like_query]
sql.push @tag if first_letter
- sql += [underscore_default_locale, like_query, like_query]
+ sql += [underscore_default_locale, like_query, like_query, like_query]
sql.push @tag if first_letter
sql += where_parameters
@public_bodies = PublicBody.paginate_by_sql(
@@ -170,17 +169,17 @@ class PublicBodyController < ApplicationController
# The simpler case where we're just searching in the current locale:
where_condition = get_public_body_list_translated_condition('public_body_translations', first_letter, true) +
' AND ' + where_condition
- where_sql = [where_condition, like_query, like_query]
+ where_sql = [where_condition, like_query, like_query, like_query]
where_sql.push @tag if first_letter
where_sql += [underscore_locale] + where_parameters
- @public_bodies = PublicBody.where(where_sql) \
- .joins(:translations) \
- .order("public_body_translations.name") \
- .paginate(:page => params[:page], :per_page => 100)
+ @public_bodies = PublicBody.where(where_sql).
+ joins(:translations).
+ order("public_body_translations.name").
+ paginate(:page => params[:page], :per_page => 100)
end
respond_to do |format|
- format.html { render :template => "public_body/list" }
+ format.html { render :template => 'public_body/list' }
end
end
end
@@ -191,6 +190,9 @@ class PublicBodyController < ApplicationController
redirect_to list_public_bodies_url(:tag => @tag)
end
+ # GET /body/all-authorities.csv
+ #
+ # Returns all public bodies (except for the internal admin authority) as CSV
def list_all_csv
# FIXME: this is just using the download directory for zip
# archives, since we know that is allowed for X-Sendfile and
@@ -198,21 +200,29 @@ class PublicBodyController < ApplicationController
# used for the zips. However, really there should be a
# generically named downloads directory that contains all
# kinds of downloadable assets.
- download_directory = File.join(InfoRequest.download_zip_dir(),
- 'download')
- FileUtils.mkdir_p download_directory
+ download_directory = File.join(InfoRequest.download_zip_dir, 'download')
+ FileUtils.mkdir_p(download_directory)
output_leafname = 'all-authorities.csv'
- output_filename = File.join download_directory, output_leafname
+ output_filename = File.join(download_directory, output_leafname)
# Create a temporary file in the same directory, so we can
# rename it atomically to the intended filename:
- tmp = Tempfile.new output_leafname, download_directory
+ tmp = Tempfile.new(output_leafname, download_directory)
tmp.close
- # Export all the public bodies to that temporary path and make
- # it readable:
- PublicBody.export_csv tmp.path
- FileUtils.chmod 0644, tmp.path
- # Rename into place and send the file:
- File.rename tmp.path, output_filename
+
+ # Create the CSV
+ csv = PublicBodyCSV.new
+ PublicBody.visible.find_each(:include => [:translations, :tags]) do |public_body|
+ next if public_body.site_administration?
+ csv << public_body
+ end
+
+ # Export all the public bodies to that temporary path, make it readable,
+ # and rename it
+ File.open(tmp.path, 'w') { |file| file.write(csv.generate) }
+ FileUtils.chmod(0644, tmp.path)
+ File.rename(tmp.path, output_filename)
+
+ # Send the file
send_file(output_filename,
:type => 'text/csv; charset=utf-8; header=present',
:filename => 'all-authorities.csv',
@@ -344,9 +354,11 @@ class PublicBodyController < ApplicationController
end
private
+
def get_public_body_list_translated_condition(table, first_letter=false, locale=nil)
result = "(upper(#{table}.name) LIKE upper(?)" \
- " OR upper(#{table}.notes) LIKE upper (?))"
+ " OR upper(#{table}.notes) LIKE upper(?)" \
+ " OR upper(#{table}.short_name) LIKE upper(?))"
if first_letter
result += " AND #{table}.first_letter = ?"
end
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index d66c28275..3fa0ef0ce 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -181,7 +181,7 @@ class RequestController < ApplicationController
end
@filters = params.merge(:latest_status => @view)
- @title = _("View and search requests")
+ @title = _('Browse and search requests')
@title = @title + " (page " + @page.to_s + ")" if (@page > 1)
@track_thing = TrackThing.create_track_for_search_query(InfoRequestEvent.make_query_from_params(@filters))
@@ -303,8 +303,14 @@ class RequestController < ApplicationController
return render_new_compose(batch=false)
end
+ # Check we have :public_body_id - spammers seem to be using :public_body
+ # erroneously instead
+ if params[:info_request][:public_body_id].blank?
+ redirect_to frontpage_path and return
+ end
+
# See if the exact same request has already been submitted
- # XXX this check should theoretically be a validation rule in the
+ # TODO: this check should theoretically be a validation rule in the
# model, except we really want to pass @existing_request to the view so
# it can link to it.
@existing_request = InfoRequest.find_existing(params[:info_request][:title], params[:info_request][:public_body_id], params[:outgoing_message][:body])
@@ -359,7 +365,7 @@ class RequestController < ApplicationController
end
# This automatically saves dependent objects, such as @outgoing_message, in the same transaction
@info_request.save!
- # XXX send_message needs the database id, so we send after saving, which isn't ideal if the request broke here.
+ # TODO: send_message needs the database id, so we send after saving, which isn't ideal if the request broke here.
@outgoing_message.send_message
flash[:notice] = _("<p>Your {{law_used_full}} request has been <strong>sent on its way</strong>!</p>
<p><strong>We will email you</strong> when there is a response, or after {{late_number_of_days}} working days if the authority still hasn't
@@ -537,7 +543,7 @@ class RequestController < ApplicationController
elsif @info_request_event.is_outgoing_message?
redirect_to outgoing_message_url(@info_request_event.outgoing_message), :status => :moved_permanently
else
- # XXX maybe there are better URLs for some events than this
+ # TODO: maybe there are better URLs for some events than this
redirect_to request_url(@info_request_event.info_request), :status => :moved_permanently
end
end
@@ -1006,7 +1012,7 @@ class RequestController < ApplicationController
params[:info_request][:public_body] = PublicBody.find(params[:url_name])
else
public_body = PublicBody.find_by_url_name_with_historic(params[:url_name])
- raise ActiveRecord::RecordNotFound.new("None found") if public_body.nil? # XXX proper 404
+ raise ActiveRecord::RecordNotFound.new("None found") if public_body.nil? # TODO: proper 404
params[:info_request][:public_body] = public_body
end
elsif params[:public_body_id]
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index 97c47c448..dc4f783a6 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -31,7 +31,7 @@ class ServicesController < ApplicationController
FastGettext.locale = old_fgt_locale
end
end
- render :text => text, :content_type => "text/plain" # XXX workaround the HTML validation in test suite
+ render :text => text, :content_type => "text/plain" # TODO: workaround the HTML validation in test suite
end
def hidden_user_explanation
diff --git a/app/controllers/track_controller.rb b/app/controllers/track_controller.rb
index dccc52efc..83700a55b 100644
--- a/app/controllers/track_controller.rb
+++ b/app/controllers/track_controller.rb
@@ -82,7 +82,7 @@ class TrackController < ApplicationController
def track_search_query
@query = params[:query_array]
- # XXX more hackery to make alternate formats still work with query_array
+ # TODO: more hackery to make alternate formats still work with query_array
if /^(.*)\.json$/.match(@query)
@query = $1
params[:format] = "json"
@@ -154,7 +154,15 @@ class TrackController < ApplicationController
request.format = 'xml' unless params[:format]
respond_to do |format|
format.json { render :json => @xapian_object.results.map { |r| r[:model].json_for_api(true,
- lambda { |t| view_context.highlight_and_excerpt(t, @xapian_object.words_to_highlight, 150) }
+ lambda do |t|
+ view_context.highlight_and_excerpt(
+ t,
+ @xapian_object.words_to_highlight(
+ :regex => true,
+ :include_original => true),
+ 150
+ )
+ end
) } }
format.any { render :template => 'track/atom_feed',
:formats => ['atom'],
diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb
index 8d6522923..fcc500e06 100644
--- a/app/controllers/user_controller.rb
+++ b/app/controllers/user_controller.rb
@@ -46,7 +46,7 @@ class UserController < ApplicationController
@is_you = !@user.nil? && @user.id == @display_user.id
# Use search query for this so can collapse and paginate easily
- # XXX really should just use SQL query here rather than Xapian.
+ # TODO: really should just use SQL query here rather than Xapian.
if @show_requests
begin
requests_query = 'requested_by:' + @display_user.url_name
@@ -102,11 +102,11 @@ class UserController < ApplicationController
@is_you = !@user.nil? && @user.id == @display_user.id
feed_results = Set.new
# Use search query for this so can collapse and paginate easily
- # XXX really should just use SQL query here rather than Xapian.
+ # TODO: really should just use SQL query here rather than Xapian.
begin
requests_query = 'requested_by:' + @display_user.url_name
comments_query = 'commented_by:' + @display_user.url_name
- # XXX combine these as OR query
+ # TODO: combine these as OR query
@xapian_requests = perform_search([InfoRequestEvent], requests_query, 'newest', 'request_collapse')
@xapian_comments = perform_search([InfoRequestEvent], comments_query, 'newest', nil)
rescue
@@ -121,7 +121,7 @@ class UserController < ApplicationController
if @is_you
@track_things = TrackThing.find(:all, :conditions => ["tracking_user_id = ? and track_medium = ?", @display_user.id, 'email_daily'], :order => 'created_at desc')
for track_thing in @track_things
- # XXX factor out of track_mailer.rb
+ # TODO: factor out of track_mailer.rb
xapian_object = ActsAsXapian::Search.new([InfoRequestEvent], track_thing.track_query,
:sort_by_prefix => 'described_at',
:sort_by_ascending => true,
@@ -262,7 +262,7 @@ class UserController < ApplicationController
end
end
- # Change password (XXX and perhaps later email) - requires email authentication
+ # Change password (TODO: and perhaps later email) - requires email authentication
def signchangepassword
if @user and ((not session[:user_circumstance]) or (session[:user_circumstance] != "change_password"))
# Not logged in via email, so send confirmation
@@ -288,7 +288,7 @@ class UserController < ApplicationController
:reason_params => {
:web => "",
:email => _("Then you can change your password on {{site_name}}",:site_name=>site_name),
- :email_subject => _("Change your password {{site_name}}",:site_name=>site_name)
+ :email_subject => _("Change your password on {{site_name}}",:site_name=>site_name)
},
:circumstance => "change_password" # special login that lets you change your password
)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 33525cb3d..49ce94951 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -13,12 +13,18 @@ module ApplicationHelper
# all of all.
include LinkToHelper
+ # Some extra date and time formatters
+ include DateTimeHelper
+
# Site-wide access to configuration settings
include ConfigHelper
# Useful for sending emails
include MailerHelper
+ # Extra highlight helpers
+ include HighlightHelper
+
# Copied from error_messages_for in active_record_helper.rb
def foi_error_messages_for(*params)
options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {}
@@ -51,25 +57,6 @@ module ApplicationHelper
end
end
- # Highlight words, also escapes HTML (other than spans that we add)
- def highlight_words(t, words, html = true)
- if html
- highlight(h(t), words, :highlighter => '<span class="highlight">\1</span>').html_safe
- else
- highlight(t, words, :highlighter => '*\1*')
- end
- end
-
- def highlight_and_excerpt(t, words, excount, html = true)
- newt = excerpt(t, words[0], :radius => excount)
- if not newt
- newt = excerpt(t, '', :radius => excount)
- end
- t = newt
- t = highlight_words(t, words, html)
- return t
- end
-
def locale_name(locale)
return LanguageNames::get_language_name(locale)
end
diff --git a/app/helpers/date_time_helper.rb b/app/helpers/date_time_helper.rb
new file mode 100644
index 000000000..5f129e590
--- /dev/null
+++ b/app/helpers/date_time_helper.rb
@@ -0,0 +1,69 @@
+module DateTimeHelper
+ # Public: Usually-correct format for a DateTime-ish object
+ # To define a new new format define the `simple_date_{FORMAT}` method
+ #
+ # date - a DateTime, Date or Time
+ # opts - a Hash of options (default: { format: :html})
+ # :format - :html returns a HTML <time> tag
+ # :text returns a plain String
+ #
+ # Examples
+ #
+ # simple_date(Time.now)
+ # # => "<time>..."
+ #
+ # simple_date(Time.now, :format => :text)
+ # # => "March 10, 2014"
+ #
+ # Returns a String
+ # Raises ArgumentError if the format is unrecognized
+ def simple_date(date, opts = {})
+ opts = { :format => :html }.merge(opts)
+ date_formatter = "simple_date_#{ opts[:format] }"
+
+ if respond_to?(date_formatter)
+ send(date_formatter, date)
+ else
+ raise ArgumentError, "Unrecognized format :#{ opts[:format] }"
+ end
+ end
+
+ # Usually-correct HTML formatting of a DateTime-ish object
+ # Use LinkToHelper#simple_date with desired formatting options
+ #
+ # date - a DateTime, Date or Time
+ #
+ # Returns a String
+ def simple_date_html(date)
+ date = date.in_time_zone unless date.is_a?(Date)
+ time_tag date, simple_date_text(date), :title => date.to_s
+ end
+
+ # Usually-correct plain text formatting of a DateTime-ish object
+ # Use LinkToHelper#simple_date with desired formatting options
+ #
+ # date - a DateTime, Date or Time
+ #
+ # Returns a String
+ def simple_date_text(date)
+ date = date.in_time_zone.to_date unless date.is_a? Date
+
+ date_format = _('simple_date_format')
+ date_format = :long if date_format == 'simple_date_format'
+ I18n.l(date, :format => date_format)
+ end
+
+ # Strips the date from a DateTime
+ #
+ # date - a DateTime, Date or Time
+ #
+ # Examples
+ #
+ # simple_time(Time.now)
+ # # => "10:46:54"
+ #
+ # Returns a String
+ def simple_time(date)
+ date.strftime("%H:%M:%S").strip
+ end
+end
diff --git a/app/helpers/highlight_helper.rb b/app/helpers/highlight_helper.rb
new file mode 100644
index 000000000..a98f6f320
--- /dev/null
+++ b/app/helpers/highlight_helper.rb
@@ -0,0 +1,98 @@
+module HighlightHelper
+ include ERB::Util
+
+ # Implementation of rails' highlight that allows regex to be passed to
+ # the phrases parameter.
+ # https://github.com/rails/rails/pull/11793
+ def highlight_matches(text, phrases, options = {})
+ text = ActionController::Base.helpers.sanitize(text).try(:html_safe) if options.fetch(:sanitize, true)
+
+ if text.blank? || phrases.blank?
+ text
+ else
+ match = Array(phrases).map do |p|
+ Regexp === p ? p.to_s : Regexp.escape(p)
+ end.join('|')
+
+ if block_given?
+ text.gsub(/(#{match})(?![^<]*?>)/i) { |found| yield found }
+ else
+ highlighter = options.fetch(:highlighter, '<mark>\1</mark>')
+ text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
+ end
+ end.html_safe
+ end
+
+ # Highlight words, also escapes HTML (other than spans that we add)
+ def highlight_words(t, words, html = true)
+ if html
+ highlight_matches(h(t), words, :highlighter => '<span class="highlight">\1</span>').html_safe
+ else
+ highlight_matches(t, words, :highlighter => '*\1*')
+ end
+ end
+
+ def highlight_and_excerpt(t, words, excount, html = true)
+ newt = excerpt(t, words[0], :radius => excount)
+ if not newt
+ newt = excerpt(t, '', :radius => excount)
+ end
+ t = newt
+ t = highlight_words(t, words, html)
+ return t
+ end
+
+ def excerpt(text, phrase, options = {})
+ return unless text && phrase
+
+ separator = options.fetch(:separator, nil) || ""
+ case phrase
+ when Regexp
+ regex = phrase
+ else
+ regex = /#{Regexp.escape(phrase)}/i
+ end
+
+ return unless matches = text.match(regex)
+ phrase = matches[0]
+
+ unless separator.empty?
+ text.split(separator).each do |value|
+ if value.match(regex)
+ regex = phrase = value
+ break
+ end
+ end
+ end
+
+ first_part, second_part = text.split(phrase, 2)
+
+ prefix, first_part = cut_excerpt_part(:first, first_part, separator, options)
+ postfix, second_part = cut_excerpt_part(:second, second_part, separator, options)
+
+ affix = [first_part, separator, phrase, separator, second_part].join.strip
+ [prefix, affix, postfix].join
+ end
+
+ private
+
+ def cut_excerpt_part(part_position, part, separator, options)
+ return "", "" unless part
+
+ radius = options.fetch(:radius, 100)
+ omission = options.fetch(:omission, "...")
+
+ part = part.split(separator)
+ part.delete("")
+ affix = part.size > radius ? omission : ""
+
+ part = if part_position == :first
+ drop_index = [part.length - radius, 0].max
+ part.drop(drop_index)
+ else
+ part.first(radius)
+ end
+
+ return affix, part.join(separator)
+ end
+end
diff --git a/app/helpers/link_to_helper.rb b/app/helpers/link_to_helper.rb
index dd6ffa805..3709469cf 100755
--- a/app/helpers/link_to_helper.rb
+++ b/app/helpers/link_to_helper.rb
@@ -28,19 +28,19 @@ module LinkToHelper
# Incoming / outgoing messages
def incoming_message_url(incoming_message, options = {})
- return request_url(incoming_message.info_request, options.merge(:anchor => "incoming-#{incoming_message.id}"))
+ message_url(incoming_message, options)
end
def incoming_message_path(incoming_message)
- incoming_message_url(incoming_message, :only_path => true)
+ message_path(incoming_message)
end
def outgoing_message_url(outgoing_message, options = {})
- request_url(outgoing_message.info_request, options.merge(:anchor => "outgoing-#{outgoing_message.id}"))
+ message_url(outgoing_message, options)
end
def outgoing_message_path(outgoing_message)
- outgoing_message_url(outgoing_message, :only_path => true)
+ message_path(outgoing_message)
end
def comment_url(comment, options = {})
@@ -279,73 +279,30 @@ module LinkToHelper
end
end
- # Public: Usually-correct format for a DateTime-ish object
- # To define a new new format define the `simple_date_{FORMAT}` method
- #
- # date - a DateTime, Date or Time
- # opts - a Hash of options (default: { format: :html})
- # :format - :html returns a HTML <time> tag
- # :text returns a plain String
- #
- # Examples
- #
- # simple_date(Time.now)
- # # => "<time>..."
- #
- # simple_date(Time.now, :format => :text)
- # # => "March 10, 2014"
- #
- # Returns a String
- # Raises ArgumentError if the format is unrecognized
- def simple_date(date, opts = {})
- opts = { :format => :html }.merge(opts)
- date_formatter = "simple_date_#{ opts[:format] }"
-
- if respond_to?(date_formatter)
- send(date_formatter, date)
- else
- raise ArgumentError, "Unrecognised format :#{ opts[:format] }"
- end
- end
+ #I18n locale switcher
- # Usually-correct HTML formatting of a DateTime-ish object
- # Use LinkToHelper#simple_date with desired formatting options
- #
- # date - a DateTime, Date or Time
- #
- # Returns a String
- def simple_date_html(date)
- date = date.in_time_zone unless date.is_a? Date
- time_tag date, simple_date_text(date), :title => date.to_s
+ def locale_switcher(locale, params)
+ params['locale'] = locale
+ return url_for(params)
end
- # Usually-correct plain text formatting of a DateTime-ish object
- # Use LinkToHelper#simple_date with desired formatting options
- #
- # date - a DateTime, Date or Time
- #
- # Returns a String
- def simple_date_text(date)
- date = date.in_time_zone.to_date unless date.is_a? Date
+ private
- date_format = _("simple_date_format")
- date_format = :long if date_format == "simple_date_format"
- I18n.l(date, :format => date_format)
- end
+ # Private: Generate a request_url linking to the new correspondence
+ def message_url(message, options = {})
+ message_type = message.class.to_s.gsub('Message', '').downcase
- def simple_time(date)
- return date.strftime("%H:%M:%S").strip
- end
+ default_options = { :anchor => "#{ message_type }-#{ message.id }" }
- def year_from_date(date)
- return date.strftime("%Y").strip
- end
+ if options.delete(:cachebust)
+ default_options.merge!(:nocache => "#{ message_type }-#{ message.id }")
+ end
- #I18n locale switcher
+ request_url(message.info_request, options.merge(default_options))
+ end
- def locale_switcher(locale, params)
- params['locale'] = locale
- return url_for(params)
+ def message_path(message)
+ message_url(message, :only_path => true)
end
end
diff --git a/app/mailers/outgoing_mailer.rb b/app/mailers/outgoing_mailer.rb
index 083c05a7c..797bf9fdd 100644
--- a/app/mailers/outgoing_mailer.rb
+++ b/app/mailers/outgoing_mailer.rb
@@ -8,7 +8,7 @@
# separated) paragraphs, as is the convention for all the other mailers. This
# turned out to fit better with user exepectations when formatting messages.
#
-# XXX The other mail templates are written to use blank line separated
+# TODO: The other mail templates are written to use blank line separated
# paragraphs. They could be rewritten, and the wrapping method made uniform
# throughout the application.
@@ -35,10 +35,10 @@ class OutgoingMailer < ApplicationMailer
:subject => OutgoingMailer.subject_for_followup(info_request, outgoing_message))
end
- # XXX the condition checking valid_to_reply_to? also appears in views/request/_followup.html.erb,
+ # TODO: the condition checking valid_to_reply_to? also appears in views/request/_followup.html.erb,
# it shouldn't really, should call something here.
- # XXX also OutgoingMessage.get_salutation
- # XXX these look like they should be members of IncomingMessage, but logically they
+ # TODO: also OutgoingMessage.get_salutation
+ # TODO: these look like they should be members of IncomingMessage, but logically they
# need to work even when IncomingMessage is nil
def OutgoingMailer.name_and_email_for_followup(info_request, incoming_message_followup)
if incoming_message_followup.nil? || !incoming_message_followup.valid_to_reply_to?
diff --git a/app/mailers/request_mailer.rb b/app/mailers/request_mailer.rb
index 1fd5b9ba7..768257ba8 100644
--- a/app/mailers/request_mailer.rb
+++ b/app/mailers/request_mailer.rb
@@ -71,7 +71,7 @@ class RequestMailer < ApplicationMailer
def new_response(info_request, incoming_message)
# Don't use login link here, just send actual URL. This is
# because people tend to forward these emails amongst themselves.
- @url = incoming_message_url(incoming_message)
+ @url = incoming_message_url(incoming_message, :cachebust => true)
@incoming_message, @info_request = incoming_message, info_request
headers('Return-Path' => blackhole_email,
@@ -234,7 +234,7 @@ class RequestMailer < ApplicationMailer
def requests_matching_email(email)
# We deliberately don't use Envelope-to here, so ones that are BCC
# drop into the holding pen for checking.
- reply_info_requests = [] # XXX should be set?
+ reply_info_requests = [] # TODO: should be set?
for address in (email.to || []) + (email.cc || [])
reply_info_request = InfoRequest.find_by_incoming_email(address)
reply_info_requests.push(reply_info_request) if reply_info_request
@@ -362,7 +362,7 @@ class RequestMailer < ApplicationMailer
store_sent.user = info_request.user
store_sent.alert_type = type_code
store_sent.info_request_event_id = alert_event_id
- # XXX uses same template for reminder 1 and reminder 2 right now.
+ # TODO: uses same template for reminder 1 and reminder 2 right now.
RequestMailer.new_response_reminder_alert(info_request, last_response_message).deliver
store_sent.save!
end
@@ -405,7 +405,7 @@ class RequestMailer < ApplicationMailer
# cron jobs broke for more than a month events would be lost, but no
# matter. I suspect the performance gain will be needed (with an index on updated_at)
- # XXX the :order part info_request_events.created_at is a work around
+ # TODO: the :order part info_request_events.created_at is a work around
# for a very old Rails bug which means eager loading does not respect
# association orders.
# http://dev.rubyonrails.org/ticket/3438
diff --git a/app/models/comment.rb b/app/models/comment.rb
index b4c099123..a62c086d5 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -63,7 +63,7 @@ class Comment < ActiveRecord::Base
# When posting a new comment, use this to check user hasn't double submitted.
def Comment.find_existing(info_request_id, body)
- # XXX can add other databases here which have regexp_replace
+ # TODO: can add other databases here which have regexp_replace
if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
# Exclude spaces from the body comparison using regexp_replace
return Comment.find(:first, :conditions => [ "info_request_id = ? and regexp_replace(body, '[[:space:]]', '', 'g') = regexp_replace(?, '[[:space:]]', '', 'g')", info_request_id, body ])
diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb
index 6f198249a..a8d105f52 100644
--- a/app/models/foi_attachment.rb
+++ b/app/models/foi_attachment.rb
@@ -178,7 +178,7 @@ class FoiAttachment < ActiveRecord::Base
return filename
end
- # XXX changing this will break existing URLs, so have a care - maybe
+ # TODO: changing this will break existing URLs, so have a care - maybe
# make another old_display_filename see above
def display_filename
filename = self.filename
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index 124db8d4a..135a6bdaf 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -150,7 +150,7 @@ class IncomingMessage < ActiveRecord::Base
end
# The cached fields mentioned in the previous comment
- # XXX there must be a nicer way to do this without all that
+ # TODO: there must be a nicer way to do this without all that
# repetition. I tried overriding method_missing but got some
# unpredictable results.
def valid_to_reply_to
@@ -194,7 +194,7 @@ class IncomingMessage < ActiveRecord::Base
end
# And look up by URL part number and display filename to get an attachment
- # XXX relies on extract_attachments calling MailHandler.ensure_parts_counted
+ # TODO: relies on extract_attachments calling MailHandler.ensure_parts_counted
# The filename here is passed from the URL parameter, so it's the
# display_filename rather than the real filename.
def self.get_attachment_by_url_part_number_and_filename(attachments, found_url_part_number, display_filename)
@@ -220,7 +220,7 @@ class IncomingMessage < ActiveRecord::Base
# Converts email addresses we know about into textual descriptions of them
def mask_special_emails!(text)
- # XXX can later display some of these special emails as actual emails,
+ # TODO: can later display some of these special emails as actual emails,
# if they are public anyway. For now just be precautionary and only
# put in descriptions of them in square brackets.
if self.info_request.public_body.is_followupable?
@@ -368,8 +368,8 @@ class IncomingMessage < ActiveRecord::Base
# Remove quoted sections from emails (eventually the aim would be for this
- # to do as good a job as GMail does) XXX bet it needs a proper parser
- # XXX and this FOLDED_QUOTED_SECTION stuff is a mess
+ # to do as good a job as GMail does) TODO: bet it needs a proper parser
+ # TODO: and this FOLDED_QUOTED_SECTION stuff is a mess
def self.remove_quoted_sections(text, replacement = "FOLDED_QUOTED_SECTION")
text = text.dup
replacement = "\n" + replacement + "\n"
@@ -399,7 +399,7 @@ class IncomingMessage < ActiveRecord::Base
(
\s*#{score}\n(?:(?!#{score}\n).)*? # top line
(disclaimer:\n|confidential|received\sthis\semail\sin\serror|virus|intended\s+recipient|monitored\s+centrally|intended\s+(for\s+|only\s+for\s+use\s+by\s+)the\s+addressee|routinely\s+monitored|MessageLabs|unauthorised\s+use)
- .*?(?:#{score}|\z) # bottom line OR end of whole string (for ones with no terminator XXX risky)
+ .*?(?:#{score}|\z) # bottom line OR end of whole string (for ones with no terminator TODO: risky)
)
/imx, replacement)
end
@@ -480,7 +480,7 @@ class IncomingMessage < ActiveRecord::Base
# Returns body text from main text part of email, converted to UTF-8, with uudecode removed,
# emails and privacy sensitive things remove, censored, and folded to remove excess quoted text
# (marked with FOLDED_QUOTED_SECTION)
- # XXX returns a .dup of the text, so calling functions can in place modify it
+ # TODO: returns a .dup of the text, so calling functions can in place modify it
def get_main_body_text_folded
if self.cached_main_body_text_folded.nil?
self._cache_main_body_text
@@ -511,7 +511,7 @@ class IncomingMessage < ActiveRecord::Base
source_charset = part.charset
if part.content_type == 'text/html'
# e.g. http://www.whatdotheyknow.com/request/35/response/177
- # XXX This is a bit of a hack as it is calling a
+ # TODO: This is a bit of a hack as it is calling a
# convert to text routine. Could instead call a
# sanitize HTML one.
@@ -627,7 +627,7 @@ class IncomingMessage < ActiveRecord::Base
return nil
end
# otherwise return it assuming it is text (sometimes you get things
- # like binary/octet-stream, or the like, which are really text - XXX if
+ # like binary/octet-stream, or the like, which are really text - TODO: if
# you find an example, put URL here - perhaps we should be always returning
# nil in this case)
return p
@@ -722,7 +722,7 @@ class IncomingMessage < ActiveRecord::Base
text = get_main_body_text_unfolded
folded_quoted_text = get_main_body_text_folded
- # Remove quoted sections, adding HTML. XXX The FOLDED_QUOTED_SECTION is
+ # Remove quoted sections, adding HTML. TODO: The FOLDED_QUOTED_SECTION is
# a nasty hack so we can escape other HTML before adding the unfold
# links, without escaping them. Rather than using some proper parser
# making a tree structure (I don't know of one that is to hand, that
diff --git a/app/models/info_request.rb b/app/models/info_request.rb
index 47ad435cb..aed651ad3 100644
--- a/app/models/info_request.rb
+++ b/app/models/info_request.rb
@@ -115,6 +115,16 @@ class InfoRequest < ActiveRecord::Base
states
end
+ # Subset of states accepted via the API
+ def self.allowed_incoming_states
+ [
+ 'waiting_response',
+ 'rejected',
+ 'successful',
+ 'partially_successful'
+ ]
+ end
+
# Possible reasons that a request could be reported for administrator attention
def report_reasons
[_("Contains defamatory material"),
@@ -387,16 +397,16 @@ public
# When constructing a new request, use this to check user hasn't double submitted.
- # XXX could have a date range here, so say only check last month's worth of new requests. If somebody is making
+ # TODO: could have a date range here, so say only check last month's worth of new requests. If somebody is making
# repeated requests, say once a quarter for time information, then might need to do that.
- # XXX this *should* also check outgoing message joined to is an initial
+ # TODO: this *should* also check outgoing message joined to is an initial
# request (rather than follow up)
def InfoRequest.find_existing(title, public_body_id, body)
return InfoRequest.find(:first, :conditions => [ "title = ? and public_body_id = ? and outgoing_messages.body = ?", title, public_body_id, body ], :include => [ :outgoing_messages ] )
end
def find_existing_outgoing_message(body)
- # XXX can add other databases here which have regexp_replace
+ # TODO: can add other databases here which have regexp_replace
if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
# Exclude spaces from the body comparison using regexp_replace
return self.outgoing_messages.find(:first, :conditions => [ "regexp_replace(outgoing_messages.body, '[[:space:]]', '', 'g') = regexp_replace(?, '[[:space:]]', '', 'g')", body ])
@@ -658,7 +668,7 @@ public
event.last_described_at = Time.now()
event.save!
end
- if event.last_described_at.nil? # XXX actually maybe this isn't needed
+ if event.last_described_at.nil? # TODO: actually maybe this isn't needed
event.last_described_at = Time.now()
event.save!
end
@@ -713,7 +723,7 @@ public
elsif event.event_type == 'resent'
last_sent = event
elsif expecting_clarification and event.event_type == 'followup_sent'
- # XXX this needs to cope with followup_resent, which it doesn't.
+ # TODO: this needs to cope with followup_resent, which it doesn't.
# Not really easy to do, and only affects cases where followups
# were resent after a clarification.
last_sent = event
diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb
index 5eed5ba83..9dde3ba80 100644
--- a/app/models/info_request_event.rb
+++ b/app/models/info_request_event.rb
@@ -75,7 +75,7 @@ class InfoRequestEvent < ActiveRecord::Base
:values => [
[ :created_at, 0, "range_search", :date ], # for QueryParser range searches e.g. 01/01/2008..14/01/2008
[ :created_at_numeric, 1, "created_at", :number ], # for sorting
- [ :described_at_numeric, 2, "described_at", :number ], # XXX using :number for lack of :datetime support in Xapian values
+ [ :described_at_numeric, 2, "described_at", :number ], # TODO: using :number for lack of :datetime support in Xapian values
[ :request, 3, "request_collapse", :string ],
[ :request_title_collapse, 4, "request_title_collapse", :string ],
],
@@ -174,7 +174,7 @@ class InfoRequestEvent < ActiveRecord::Base
end
def get_clipped_response_efficiently
- # XXX this ugly code is an attempt to not always load all the
+ # TODO: this ugly code is an attempt to not always load all the
# columns for an incoming message, which can be *very* large
# (due to all the cached text). We care particularly in this
# case because it's called for every search result on a page
@@ -266,7 +266,7 @@ class InfoRequestEvent < ActiveRecord::Base
# We store YAML version of parameters in the database
def params=(params)
- # XXX should really set these explicitly, and stop storing them in
+ # TODO: should really set these explicitly, and stop storing them in
# here, but keep it for compatibility with old way for now
if not params[:incoming_message_id].nil?
self.incoming_message_id = params[:incoming_message_id]
@@ -392,7 +392,7 @@ class InfoRequestEvent < ActiveRecord::Base
:outgoing_message_id => self.outgoing_message_id,
:comment_id => self.comment_id,
- # XXX would be nice to add links here, but alas the
+ # TODO: would be nice to add links here, but alas the
# code to make them is in views only. See views/request/details.html.erb
# perhaps can call with @template somehow
}
diff --git a/app/models/mail_server_log.rb b/app/models/mail_server_log.rb
index 0e5b60ff1..07d2fdac0 100644
--- a/app/models/mail_server_log.rb
+++ b/app/models/mail_server_log.rb
@@ -166,7 +166,7 @@ class MailServerLog < ActiveRecord::Base
# lines. Writes any errors to STDERR. This check is really mainly to
# check the envelope from is the request address, as Ruby is quite
# flaky with regard to that, and it is important for anti-spam reasons.
- # XXX does this really check that, as the log just wouldn't pick
+ # TODO: does this really check that, as the log just wouldn't pick
# up at all if the requests weren't sent that way as there would be
# no request- email in it?
#
diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb
index a435511d3..160f69d0b 100644
--- a/app/models/outgoing_message.rb
+++ b/app/models/outgoing_message.rb
@@ -125,7 +125,7 @@ class OutgoingMessage < ActiveRecord::Base
get_salutation + "\n\n" + get_default_letter + "\n\n" + get_signoff + "\n\n"
end
def set_signature_name(name)
- # XXX We use raw_body here to get unstripped one
+ # TODO: We use raw_body here to get unstripped one
if self.raw_body == self.get_default_message
self.body = self.raw_body + name
end
diff --git a/app/models/post_redirect.rb b/app/models/post_redirect.rb
index 5da3d2742..6f288b471 100644
--- a/app/models/post_redirect.rb
+++ b/app/models/post_redirect.rb
@@ -65,7 +65,7 @@ class PostRedirect < ActiveRecord::Base
# Used by (rspec) test code only
def self.get_last_post_redirect
- # XXX yeuch - no other easy way of getting the token so we can check
+ # TODO: yeuch - no other easy way of getting the token so we can check
# the redirect URL, as it is by definition opaque to the controller
# apart from in the place that it redirects to.
post_redirects = PostRedirect.find_by_sql("select * from post_redirects order by id desc limit 1")
diff --git a/app/models/profile_photo.rb b/app/models/profile_photo.rb
index 6c3b2cfa0..3c0be222c 100644
--- a/app/models/profile_photo.rb
+++ b/app/models/profile_photo.rb
@@ -115,7 +115,7 @@ class ProfilePhoto < ActiveRecord::Base
return
end
- self.image = image_list[0] # XXX perhaps take largest image or somesuch if there were multiple in the file?
+ self.image = image_list[0] # TODO: perhaps take largest image or somesuch if there were multiple in the file?
self.convert_image
end
end
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 03ec270ee..b22482541 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -93,7 +93,7 @@ class PublicBody < ActiveRecord::Base
self.translations.find_by_locale(locale)
end
- # XXX - Don't like repeating this!
+ # TODO: - Don't like repeating this!
def calculate_cached_fields(t)
PublicBody.set_first_letter(t)
short_long_name = t.name
@@ -329,7 +329,7 @@ class PublicBody < ActiveRecord::Base
first = false
end
if html
- # XXX this should call proper route helpers, but is in model sigh
+ # TODO: this should call proper route helpers, but is in model sigh
desc = '<a href="/body/list/' + tag.name + '">' + desc + '</a>'
end
types.push(desc)
@@ -399,6 +399,9 @@ class PublicBody < ActiveRecord::Base
end
end
+ def site_administration?
+ has_tag?('site_administration')
+ end
class ImportCSVDryRun < StandardError
end
@@ -569,45 +572,6 @@ class PublicBody < ActiveRecord::Base
return [errors, notes]
end
- # Returns all public bodies (except for the internal admin authority) as csv
- def self.export_csv(output_filename)
- CSV.open(output_filename, "w") do |csv|
- csv << [
- 'Name',
- 'Short name',
- # deliberately not including 'Request email'
- 'URL name',
- 'Tags',
- 'Home page',
- 'Publication scheme',
- 'Disclosure log',
- 'Notes',
- 'Created at',
- 'Updated at',
- 'Version',
- ]
- PublicBody.visible.find_each(:include => [:translations, :tags]) do |public_body|
- # Skip bodies we use only for site admin
- next if public_body.has_tag?('site_administration')
- csv << [
- public_body.name,
- public_body.short_name,
- # DO NOT include request_email (we don't want to make it
- # easy to spam all authorities with requests)
- public_body.url_name,
- public_body.tag_string,
- public_body.calculated_home_page,
- public_body.publication_scheme,
- public_body.disclosure_log,
- public_body.notes,
- public_body.created_at,
- public_body.updated_at,
- public_body.version,
- ]
- end
- end
- end
-
# Does this user have the power of FOI officer for this body?
def is_foi_officer?(user)
user_domain = user.email_domain
diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb
index 13b6f78dd..10ba28f4a 100644
--- a/app/models/track_thing.rb
+++ b/app/models/track_thing.rb
@@ -149,7 +149,7 @@ class TrackThing < ActiveRecord::Base
end
end
track_thing.track_query = query
- # XXX should extract requested_by:, request:, requested_from:
+ # TODO: should extract requested_by:, request:, requested_from:
# and stick their values into the respective relations.
# Should also update "params" to make the list_description
# nicer and more generic. It will need to do some clever
@@ -271,7 +271,7 @@ class TrackThing < ActiveRecord::Base
:web => _("To follow requests and responses matching your search"),
:email => _("Then you will be notified whenever a new request or response matches your search."),
:email_subject => _("Confirm you want to follow new requests or responses matching your search"),
- # RSS sorting - XXX hmmm, we don't really know which to use
+ # RSS sorting - TODO: hmmm, we don't really know which to use
# here for sorting. Might be a query term (e.g. 'cctv'), in
# which case newest is good, or might be something like
# all refused requests in which case want to sort by
diff --git a/app/models/user.rb b/app/models/user.rb
index d75622b37..4b83d8572 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -99,7 +99,7 @@ class User < ActiveRecord::Base
end
# Don't display any leading/trailing spaces
- # XXX we have strip_attributes! now, so perhaps this can be removed (might
+ # TODO: we have strip_attributes! now, so perhaps this can be removed (might
# be still needed for existing cases)
def name
name = read_attribute(:name)
@@ -222,7 +222,7 @@ class User < ActiveRecord::Base
# Can the user make new requests, without having to describe state of (most) existing ones?
def can_leave_requests_undescribed?
- # XXX should be flag in database really
+ # TODO: should be flag in database really
if self.url_name == "heather_brooke" || self.url_name == "heather_brooke_2"
return true
end
@@ -425,7 +425,7 @@ class User < ActiveRecord::Base
## Class methods
def User.encrypted_password(password, salt)
- string_to_hash = password + salt # XXX need to add a secret here too?
+ string_to_hash = password + salt # TODO: need to add a secret here too?
Digest::SHA1.hexdigest(string_to_hash)
end
diff --git a/app/views/admin_general/index.html.erb b/app/views/admin_general/index.html.erb
index 2202663be..f29258162 100644
--- a/app/views/admin_general/index.html.erb
+++ b/app/views/admin_general/index.html.erb
@@ -39,7 +39,7 @@
<% if message.get_body_for_quoting.strip.size == 0 %>
<%= link_to "(no body)", admin_request_show_raw_email_path(message.raw_email_id) %>
<% else %>
- <%= link_to excerpt(message.get_body_for_quoting, "", 60), admin_request_show_raw_email_path(message.raw_email_id) %>
+ <%= link_to excerpt(message.get_body_for_quoting, "", :radius => 60), admin_request_show_raw_email_path(message.raw_email_id) %>
<% end %>
</td>
<td class="span2">
diff --git a/app/views/admin_request/edit.html.erb b/app/views/admin_request/edit.html.erb
index 0e9c68aea..552b31bbb 100644
--- a/app/views/admin_request/edit.html.erb
+++ b/app/views/admin_request/edit.html.erb
@@ -33,7 +33,7 @@
<p><label for="info_request_tag_string"><strong>Tags</strong> <small>(space separated, can use key:value)</small></label><br/>
<%= text_field 'info_request', 'tag_string', :size => 60 %></p>
- <p><%= submit_tag 'Save changes', :accesskey => 's' %>
+ <p><%= submit_tag 'Save changes', :accesskey => 's', :class => 'btn btn-primary' %>
</p>
<p><strong>Note:</strong> To edit the actual request body text, click edit
@@ -49,13 +49,17 @@
<hr>
+<div class="well">
+
<%= form_tag admin_request_destroy_path(@info_request) do %>
<p>
- <strong>This is permanent and irreversible!</strong> <%= submit_tag 'Destroy request entirely' %>
+ <strong>This is permanent and irreversible!</strong> <%= submit_tag 'Destroy request entirely', :class => 'btn btn-danger' %>
<br>Use it mainly if someone posts private information, e.g. made a Data Protection request. It
destroys all responses and tracks as well.
</p>
<% end %>
+</div>
+
<hr>
diff --git a/app/views/general/_frontpage_bodies_list.html.erb b/app/views/general/_frontpage_bodies_list.html.erb
index 44321f14a..1c35c55ad 100644
--- a/app/views/general/_frontpage_bodies_list.html.erb
+++ b/app/views/general/_frontpage_bodies_list.html.erb
@@ -3,9 +3,10 @@
<div id="examples_0">
<h3><%= _("Who can I request information from?") %></h3>
<%= _("{{site_name}} covers requests to {{number_of_authorities}} authorities, including:",
- :site_name => site_name, :number_of_authorities => PublicBody.visible.count) %>
+ :site_name => site_name,
+ :number_of_authorities => number_with_delimiter(PublicBody.visible.count)) %>
<ul>
- <% for popular_body in popular_bodies %>
+ <% popular_bodies.each do |popular_body| %>
<li><%=public_body_link(popular_body)%>
<%= n_('{{count}} request', '{{count}} requests', popular_body.info_requests_count, :count => popular_body.info_requests_count) %>
</li>
diff --git a/app/views/general/_frontpage_new_request.html.erb b/app/views/general/_frontpage_new_request.html.erb
index 499b60eb5..5b987b320 100644
--- a/app/views/general/_frontpage_new_request.html.erb
+++ b/app/views/general/_frontpage_new_request.html.erb
@@ -4,4 +4,4 @@
Information<br/>
request</strong>") %>
</h1>
-<a class="link_button_green_large" href="<%= select_authority_path %>"><%= _("Start now &raquo;") %></a>
+<a class="link_button_green_large" href="<%= select_authority_path %>"><%= _("Make a request &raquo;") %></a>
diff --git a/app/views/general/_frontpage_requests_list.html.erb b/app/views/general/_frontpage_requests_list.html.erb
index d7d9184c4..39187f3f0 100644
--- a/app/views/general/_frontpage_requests_list.html.erb
+++ b/app/views/general/_frontpage_requests_list.html.erb
@@ -8,9 +8,10 @@
<% end %>
</h3>
<%= _("{{site_name}} users have made {{number_of_requests}} requests, including:",
- :site_name => site_name, :number_of_requests => InfoRequest.visible.count) %>
+ :site_name => site_name,
+ :number_of_requests => number_with_delimiter(InfoRequest.visible.count)) %>
<ul>
- <% for event in @request_events %>
+ <% @request_events.each do |event| %>
<li>
<% if @request_events_all_successful %>
<%= _("{{public_body_link}} answered a request about",
diff --git a/app/views/general/_frontpage_search_box.html.erb b/app/views/general/_frontpage_search_box.html.erb
index 890602416..f77bd97fc 100644
--- a/app/views/general/_frontpage_search_box.html.erb
+++ b/app/views/general/_frontpage_search_box.html.erb
@@ -2,7 +2,8 @@
<%= _("Search over<br/>
<strong>{{number_of_requests}} requests</strong> <span>and</span><br/>
<strong>{{number_of_authorities}} authorities</strong>",
- :number_of_requests => InfoRequest.visible.count, :number_of_authorities => PublicBody.visible.count) %>
+ :number_of_requests => number_with_delimiter(InfoRequest.visible.count),
+ :number_of_authorities => number_with_delimiter(PublicBody.visible.count)) %>
</h2>
<form id="search_form" method="post" action="<%= search_redirect_path %>">
<div>
diff --git a/app/views/general/_locale_switcher.html.erb b/app/views/general/_locale_switcher.html.erb
index a318f61f3..7b6377665 100644
--- a/app/views/general/_locale_switcher.html.erb
+++ b/app/views/general/_locale_switcher.html.erb
@@ -1,7 +1,7 @@
<% if FastGettext.default_available_locales.length > 1 && !params.empty? %>
<div id="user_locale_switcher">
<div class="btn-group">
- <% for possible_locale in FastGettext.default_available_locales %>
+ <% FastGettext.default_available_locales.each do |possible_locale| %>
<% if possible_locale == FastGettext.locale %>
<a href="#" class="btn disabled"><%= locale_name(possible_locale) %></a>
<% else %>
diff --git a/app/views/general/_responsive_topnav.html.erb b/app/views/general/_responsive_topnav.html.erb
index e726c17f4..0ece0da9a 100644
--- a/app/views/general/_responsive_topnav.html.erb
+++ b/app/views/general/_responsive_topnav.html.erb
@@ -6,7 +6,7 @@
</li>
<li class="<%= 'selected' if params[:controller] == 'request' and !['new', 'select_authority'].include?(params[:action]) %>">
- <%= link_to _("View requests"), request_list_successful_path %>
+ <%= link_to _("Browse requests"), request_list_successful_path %>
</li>
<li class="<%= 'selected' if params[:controller] == 'public_body' %>">
diff --git a/app/views/general/_topnav.html.erb b/app/views/general/_topnav.html.erb
index d37bd97d1..04ca07fa9 100644
--- a/app/views/general/_topnav.html.erb
+++ b/app/views/general/_topnav.html.erb
@@ -2,7 +2,9 @@
<ul id="navigation">
<li class="<%= 'selected' if params[:controller] == 'general' and params[:action] != 'blog' and params[:action] != 'search' %>"><%= link_to _("Home"), frontpage_path %></li>
<li class="<%= 'selected' if params[:controller] == 'request' and ['new', 'select_authority'].include?(params[:action]) %>"><%= link_to _("Make a request"), select_authority_path, :id => 'make-request-link' %></li>
- <li class="<%= 'selected' if params[:controller] == 'request' and !['new', 'select_authority'].include?(params[:action]) %>"><%= link_to _("View requests"), request_list_successful_path %></li>
+ <li class="<%= 'selected' if params[:controller] == 'request' and !['new', 'select_authority'].include?(params[:action]) %>">
+ <%= link_to _("Browse requests"), request_list_successful_path %>
+ </li>
<li class="<%= 'selected' if params[:controller] == 'public_body' %>"><%= link_to _("View authorities"), list_public_bodies_default_path %></li>
<% unless AlaveteliConfiguration::blog_feed.empty? %>
<li class="<%= 'selected' if params[:controller] == 'general' and params[:action] == 'blog' %>"><%= link_to _("Read blog"), blog_path %></li>
diff --git a/app/views/public_body/_list_sidebar_extra.html.erb b/app/views/public_body/_list_sidebar_extra.html.erb
index 290593d6a..6e683d7a1 100644
--- a/app/views/public_body/_list_sidebar_extra.html.erb
+++ b/app/views/public_body/_list_sidebar_extra.html.erb
@@ -1,3 +1,8 @@
+<% if AlaveteliConfiguration::public_body_statistics_page %>
+ <p>
+ <%= link_to _('Public authority statistics'), public_bodies_statistics_path %>
+ </p>
+<% end %>
<p>
<%= link_to _('Are we missing a public authority?'), help_requesting_path + '#missing_body' %>
</p>
diff --git a/app/views/public_body/show.html.erb b/app/views/public_body/show.html.erb
index a9c50e657..9352747ea 100644
--- a/app/views/public_body/show.html.erb
+++ b/app/views/public_body/show.html.erb
@@ -127,7 +127,10 @@
<% if @xapian_requests.results.empty? %>
<p><% _('There were no requests matching your query.') %></p>
<% else %>
- <p> <%= _('Only requests made using {{site_name}} are shown.', :site_name => site_name) %></p>
+ <p>
+ <%= _('Only requests made using {{site_name}} are shown.', :site_name => site_name) %>
+ <%= link_to _('?'), help_about_path %>
+ </p>
<% end %>
<% else %>
diff --git a/app/views/public_body/statistics.html.erb b/app/views/public_body/statistics.html.erb
index d935a9e47..0e7e7424e 100644
--- a/app/views/public_body/statistics.html.erb
+++ b/app/views/public_body/statistics.html.erb
@@ -1,6 +1,6 @@
<% @title = _("Public Body Statistics") %>
<div id="main_content">
- <h1>Public Body Statistics</h1>
+ <h1><%= @title %></h1>
<p><%= _("This page of public body statistics is currently \
experimental, so there are some caveats that should be borne \
@@ -33,6 +33,8 @@ requests to the authority through this site, rather than, \
say, all requests that have been made to the public body by \
any means.") %></li>
+ <li><%= _("Unclassified or hidden requests are not counted.") %></li>
+
</ul>
<p><%= _("These graphs were partly inspired by \
@@ -47,7 +49,7 @@ are due to him.") %></p>
<table border=0>
<thead>
<tr>
- <th>Public Body</th>
+ <th><%= _('Public Body') %></th>
<th><%= graph_data['y_axis'] %></th>
</tr>
</thead>
diff --git a/app/views/public_body_change_requests/new.html.erb b/app/views/public_body_change_requests/new.html.erb
index 7079cd868..b52d583be 100644
--- a/app/views/public_body_change_requests/new.html.erb
+++ b/app/views/public_body_change_requests/new.html.erb
@@ -54,6 +54,11 @@
<%= f.text_area :notes, :rows => 10, :cols => 60 %>
</p>
+ <p style="display:none;">
+ <%= label_tag 'public_body_change_request[comment]', _('Do not fill in this field') %>
+ <%= text_field_tag 'public_body_change_request[comment]' %>
+ </p>
+
<div class="form_button">
<%= submit_tag _("Submit request") %>
</div>
diff --git a/app/views/request/_sidebar_request_listing.html.erb b/app/views/request/_sidebar_request_listing.html.erb
index ec5a5813d..64fe39341 100644
--- a/app/views/request/_sidebar_request_listing.html.erb
+++ b/app/views/request/_sidebar_request_listing.html.erb
@@ -4,7 +4,7 @@
<%= request_link(info_request) %>
</span>
<span class="desc">
- <%=h excerpt(info_request.initial_request_text, "", 100) %>
+ <%=h excerpt(info_request.initial_request_text, "", :radius => 100) %>
</span>
<span class="bottomline">
<strong>
diff --git a/app/views/request/_view_html_stylesheet.html.erb b/app/views/request/_view_html_stylesheet.html.erb
index f3d8799da..09f295346 100644
--- a/app/views/request/_view_html_stylesheet.html.erb
+++ b/app/views/request/_view_html_stylesheet.html.erb
@@ -1,17 +1,16 @@
<% if AlaveteliConfiguration::responsive_styling || params[:responsive] %>
<!--[if LTE IE 7]>
- <link href="/assets/responsive/application-lte-ie7.css" media="all" rel="stylesheet" title="Main" type="text/css" />
+ <link href="/assets/responsive/application-lte-ie7.css" media="all" rel="stylesheet" title="Main" type="text/css" charset="UTF-8" />
<![endif]-->
<!--[if IE 8]>
- <link href="/assets/responsive/application-ie8.css" media="all" rel="stylesheet" title="Main" type="text/css" />
+ <link href="/assets/responsive/application-ie8.css" media="all" rel="stylesheet" title="Main" type="text/css" charset="UTF-8" />
<![endif]-->
<!--[if GT IE 8]><!-->
- <link href="/assets/responsive/application.css" media="all" rel="stylesheet" title="Main" type="text/css" />
+ <link href="/assets/responsive/application.css" media="all" rel="stylesheet" title="Main" type="text/css" charset="UTF-8" />
<!--<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<% else %>
- <link type="text/css" title="Main" rel="stylesheet" media="screen" href="/assets/application.css">
-
+ <link type="text/css" title="Main" rel="stylesheet" media="screen" href="/assets/application.css" charset="UTF-8" />
<% end %>
diff --git a/app/views/request/upload_response.html.erb b/app/views/request/upload_response.html.erb
index f5fd6f000..f07af34d5 100644
--- a/app/views/request/upload_response.html.erb
+++ b/app/views/request/upload_response.html.erb
@@ -9,7 +9,9 @@
<%= foi_error_messages_for :comment %>
- <h1><%= _('Respond to the FOI request')%> '<%=request_link(@info_request)%>'<% _(' made by ')%><%=user_link(@info_request.user) %></h1>
+ <h1><%= _("Respond to the FOI request '{{request}}' made by {{user}}",
+ :request => request_link(@info_request),
+ :user => user_link(@info_request.user)) %></h1>
<p>
<%= raw(_('Your response will <strong>appear on the Internet</strong>, <a href="{{url}}">read why</a> and answers to other questions.', :url => help_officers_path.html_safe)) %>
@@ -48,5 +50,3 @@
</p>
<% end %>
<% end %>
-
-
diff --git a/app/views/track_mailer/event_digest.text.erb b/app/views/track_mailer/event_digest.text.erb
index b83c184f0..f6e699e41 100644
--- a/app/views/track_mailer/event_digest.text.erb
+++ b/app/views/track_mailer/event_digest.text.erb
@@ -4,7 +4,7 @@
for track_thing, alert_results, xapian_object in @email_about_things
main_text += track_thing.params[:title_in_email] + "\n"
main_text += ("=" * track_thing.params[:title_in_email].size) + "\n\n"
- @highlight_words = xapian_object.words_to_highlight
+ @highlight_words = xapian_object.words_to_highlight(:regex => true)
for result in alert_results.reverse
if result[:model].class.to_s == "InfoRequestEvent"
event = result[:model]
@@ -17,14 +17,14 @@
# e.g. Julian Burgess sent a request to Royal Mail Group (15 May 2008)
if event.event_type == 'response'
- url = incoming_message_url(event.incoming_message)
+ url = incoming_message_url(event.incoming_message, :cachebust => true)
main_text += _("{{public_body}} sent a response to {{user_name}}", :public_body => event.info_request.public_body.name, :user_name => event.info_request.user_name)
elsif event.event_type == 'followup_sent'
- url = outgoing_message_url(event.outgoing_message)
+ url = outgoing_message_url(event.outgoing_message, :cachebust => true)
main_text += _("{{user_name}} sent a follow up message to {{public_body}}", :user_name => event.info_request.user_name, :public_body => event.info_request.public_body.name)
elsif event.event_type == 'sent'
# this is unlikely to happen in real life, but happens in the test code
- url = outgoing_message_url(event.outgoing_message)
+ url = outgoing_message_url(event.outgoing_message, :cachebust => true)
main_text += _("{{user_name}} sent a request to {{public_body}}", :user_name => event.info_request.user_name, :public_body => event.info_request.public_body.name)
elsif event.event_type == 'comment'
url = comment_url(event.comment)
diff --git a/app/views/user/_user_listing_single.html.erb b/app/views/user/_user_listing_single.html.erb
index ed1b95718..3cb0d283f 100644
--- a/app/views/user/_user_listing_single.html.erb
+++ b/app/views/user/_user_listing_single.html.erb
@@ -18,7 +18,7 @@ end %>
<span class="bottomline">
<%= pluralize(display_user.info_requests.size, "request") %> <%= _('made.')%>
<%= pluralize(display_user.visible_comments.size, "annotation") %> <%= _('made.')%>
- <%= _('Joined in')%> <%= year_from_date(display_user.created_at) %>.
+ <%= _('Joined in')%> <%= display_user.created_at.year %>.
</span>
</div>
diff --git a/app/views/user/show.html.erb b/app/views/user/show.html.erb
index ce328b46f..7ae577565 100644
--- a/app/views/user/show.html.erb
+++ b/app/views/user/show.html.erb
@@ -64,7 +64,7 @@
<h1> <%= h(@display_user.name) + (@is_you ? _(" (you)") : "") %></h1>
<p class="subtitle">
- <%= _('Joined {{site_name}} in', :site_name=>site_name) %> <%= year_from_date(@display_user.created_at) %>
+ <%= _('Joined {{site_name}} in', :site_name=>site_name) %> <%= @display_user.created_at.year %>
<% if !@user.nil? && @user.admin_page_links? %>
(<%= link_to "admin", admin_user_show_path(@display_user) %>)
<% end %>