aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin_request_controller.rb9
-rw-r--r--app/controllers/api_controller.rb72
-rw-r--r--app/controllers/application_controller.rb20
-rw-r--r--app/controllers/general_controller.rb6
-rw-r--r--app/helpers/application_helper.rb26
-rwxr-xr-xapp/helpers/link_to_helper.rb4
-rw-r--r--app/models/foi_attachment.rb68
-rw-r--r--app/models/incoming_message.rb512
-rw-r--r--app/models/info_request.rb28
-rw-r--r--app/models/info_request_event.rb2
-rw-r--r--app/models/outgoing_mailer.rb5
-rw-r--r--app/models/raw_email.rb4
-rw-r--r--app/models/request_mailer.rb7
-rw-r--r--app/models/user.rb2
-rw-r--r--app/views/comment/_single_comment.rhtml2
-rw-r--r--app/views/general/_frontpage_new_request.rhtml2
-rw-r--r--app/views/general/_frontpage_search_box.rhtml2
-rw-r--r--app/views/help/_sidebar.rhtml18
-rw-r--r--app/views/help/about.rhtml4
-rw-r--r--app/views/help/api.rhtml12
-rw-r--r--app/views/help/contact.rhtml18
-rw-r--r--app/views/help/officers.rhtml38
-rw-r--r--app/views/help/privacy.rhtml28
-rw-r--r--app/views/help/requesting.rhtml38
-rw-r--r--app/views/help/unhappy.rhtml16
-rw-r--r--app/views/layouts/default.rhtml14
-rw-r--r--app/views/request/_correspondence.rhtml24
-rw-r--r--app/views/request/select_authority.rhtml4
-rw-r--r--app/views/request/show.rhtml3
-rw-r--r--app/views/user/_show_user_info.rhtml2
-rw-r--r--app/views/user/sign.rhtml17
31 files changed, 361 insertions, 646 deletions
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index 3e574b10f..c7c8d4972 100644
--- a/app/controllers/admin_request_controller.rb
+++ b/app/controllers/admin_request_controller.rb
@@ -207,8 +207,7 @@ class AdminRequestController < AdminController
end
raw_email_data = incoming_message.raw_email.data
- mail = TMail::Mail.parse(raw_email_data)
- mail.base64_decode
+ mail = MailHandler.mail_from_raw_email(raw_email_data)
destination_request.receive(mail, raw_email_data, true)
incoming_message_id = incoming_message.id
@@ -278,7 +277,7 @@ class AdminRequestController < AdminController
if params[:incoming_message_id]
incoming_message = IncomingMessage.find(params[:incoming_message_id])
- email = incoming_message.mail.from_addrs[0].address
+ email = incoming_message.from_email
name = incoming_message.safe_mail_from || info_request.public_body.name
else
email = info_request.public_body.request_email
@@ -313,12 +312,12 @@ class AdminRequestController < AdminController
@raw_email = RawEmail.find(params[:id])
# For the holding pen, try to guess where it should be ...
@holding_pen = false
- if (@raw_email.incoming_message.info_request == InfoRequest.holding_pen_request && !@raw_email.incoming_message.mail.from_addrs.nil? && @raw_email.incoming_message.mail.from_addrs.size > 0)
+ if (@raw_email.incoming_message.info_request == InfoRequest.holding_pen_request && !@raw_email.incoming_message.empty_from_field?)
@holding_pen = true
# 1. Use domain of email to try and guess which public body it
# is associated with, so we can display that.
- email = @raw_email.incoming_message.mail.from_addrs[0].spec
+ email = @raw_email.incoming_message.from_email
domain = PublicBody.extract_domain_from_email(email)
if domain.nil?
diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb
index aa5e85db3..15fb4f5f9 100644
--- a/app/controllers/api_controller.rb
+++ b/app/controllers/api_controller.rb
@@ -1,30 +1,30 @@
class ApiController < ApplicationController
before_filter :check_api_key
-
+
def show_request
@request = InfoRequest.find(params[:id])
raise PermissionDenied if @request.public_body_id != @public_body.id
-
+
@request_data = {
: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),
:requestor_url => make_url("user", @request.user.url_name),
:request_email => @request.incoming_email,
-
+
:request_text => @request.last_event_forming_initial_request.outgoing_message.body,
}
-
+
render :json => @request_data
end
-
+
def create_request
json = ActiveSupport::JSON.decode(params[:request_json])
request = InfoRequest.new(
@@ -34,7 +34,7 @@ class ApiController < ApplicationController
:external_user_name => json["external_user_name"],
:external_url => json["external_url"]
)
-
+
outgoing_message = OutgoingMessage.new(
:status => 'ready',
:message_type => 'initial_request',
@@ -44,7 +44,7 @@ class ApiController < ApplicationController
:info_request => request
)
request.outgoing_messages << outgoing_message
-
+
# Return an error if the request is invalid
# (Can this ever happen?)
if !request.valid?
@@ -53,7 +53,7 @@ class ApiController < ApplicationController
}
return
end
-
+
# Save the request, and add the corresponding InfoRequestEvent
request.save!
request.log_event("sent",
@@ -62,69 +62,69 @@ class ApiController < ApplicationController
:outgoing_message_id => outgoing_message.id,
:smtp_message_id => nil
)
-
+
# Return the URL and ID number.
render :json => {
'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_str = json["sent_at"]
-
+
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
-
+
if body.nil?
errors << "The 'body' is missing"
elsif body.empty?
errors << "The 'body' is empty"
end
-
+
begin
sent_at = Time.iso8601(sent_at_str)
rescue ArgumentError
errors << "Failed to parse 'sent_at' field as ISO8601 time: #{sent_at_str}"
end
-
+
if direction == "request" && !attachments.nil?
errors << "You cannot attach files to messages in the 'request' direction"
end
-
+
if !errors.empty?
render :json => { "errors" => errors }, :status => 500
return
end
-
+
if direction == "request"
# In the 'request' direction, i.e. what we (Alaveteli) regard as outgoing
-
+
outgoing_message = OutgoingMessage.new(
:info_request => request,
:status => 'ready',
@@ -154,19 +154,19 @@ class ApiController < ApplicationController
:filename => filename
)
end
-
+
mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes)
request.receive(mail, mail.encoded, true)
end
render :json => {
'url' => make_url("request", request.url_title),
- }
+ }
end
-
+
def body_request_events
feed_type = params[:feed_type]
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([
@@ -213,7 +213,7 @@ class ApiController < ApplicationController
@event_data = []
@events.each do |event|
break if event.id == @since_event_id
-
+
request = event.info_request
this_event = {
:request_id => request.id,
@@ -224,13 +224,13 @@ class ApiController < ApplicationController
:request_email => request.incoming_email,
:title => request.title,
:body => event.outgoing_message.body,
-
+
:user_name => request.user_name,
}
if request.user
this_event[:user_url] = main_url(user_url(request.user))
end
-
+
@event_data.push(this_event)
end
render :json => @event_data
@@ -238,14 +238,14 @@ class ApiController < ApplicationController
raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: #{feed_type}")
end
end
-
+
protected
def check_api_key
- raise "Missing required parameter 'k'" if params[:k].nil?
+ raise PermissionDenied.new("Missing required parameter 'k'") if params[:k].nil?
@public_body = PublicBody.find_by_api_key(params[:k].gsub(' ', '+'))
raise PermissionDenied if @public_body.nil?
end
-
+
private
def make_url(*args)
"http://" + Configuration::domain + "/" + args.join("/")
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index b707ae878..a946526b8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -54,10 +54,15 @@ class ApplicationController < ActionController::Base
end
def set_gettext_locale
+ if Configuration::include_default_locale_in_urls == false
+ params_locale = params[:locale] ? params[:locale] : I18n.default_locale
+ else
+ params_locale = params[:locale]
+ end
if Configuration::use_default_browser_language
- requested_locale = params[:locale] || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || I18n.default_locale
+ requested_locale = params_locale || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || I18n.default_locale
else
- requested_locale = params[:locale] || session[:locale] || cookies[:locale] || I18n.default_locale
+ requested_locale = params_locale || session[:locale] || cookies[:locale] || I18n.default_locale
end
requested_locale = FastGettext.best_locale_in(requested_locale)
session[:locale] = FastGettext.set_locale(requested_locale)
@@ -117,17 +122,14 @@ class ApplicationController < ActionController::Base
# Override default error handler, for production sites.
def rescue_action_in_public(exception)
- # Call `set_view_paths` from the theme, if it exists.
+ # Looks for before_filters called something like `set_view_paths_{themename}`. These
+ # are set by the themes.
# Normally, this is called by the theme itself in a
# :before_filter, but when there's an error, this doesn't
# happen. By calling it here, we can ensure error pages are
# still styled according to the theme.
- begin
- set_view_paths
- rescue NameError => e
- if !(e.message =~ /undefined local variable or method `set_view_paths'/)
- raise
- end
+ ActionController::Base.before_filters.select{|f| f.to_s =~ /set_view_paths/}.each do |f|
+ self.send(f)
end
# Make sure expiry time for session is set (before_filters are
# otherwise missed by this override)
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 0cde238cd..3ba636e29 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -226,12 +226,6 @@ class GeneralController < ApplicationController
redirect_to request_url(info_request)
end
- # For debugging
- def fai_test
- sleep 10
- render :text => "awake\n"
- end
-
def custom_css
long_cache
@locale = self.locale_from_params()
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index ab953cb25..6411cf27e 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -77,25 +77,6 @@ module ApplicationHelper
return LanguageNames::get_language_name(locale)
end
- # Use our own algorithm for finding path of cache
- def foi_cache(name = {}, options = nil, &block)
- if @controller.perform_caching
- key = name.merge(:only_path => true)
- key_path = @controller.foi_fragment_cache_path(key)
-
- if @controller.foi_fragment_cache_exists?(key_path)
- cached = @controller.foi_fragment_cache_read(key_path)
- output_buffer.concat(cached)
- return
- end
-
- pos = output_buffer.length
- content = block.call
- @controller.foi_fragment_cache_write(key_path, output_buffer[pos..-1])
- else
- block.call
- end
- end
# (unfortunately) ugly way of getting id of generated form element
# ids
# see http://chrisblunt.com/2009/10/12/rails-getting-the-id-of-form-fields-inside-a-fields_for-block/
@@ -131,5 +112,12 @@ module ApplicationHelper
return "#{exact_date} (#{ago_text})"
end
+ # Note that if the admin interface is proxied via another server, we can't
+ # rely on a sesssion being shared between the front end and admin interface,
+ # so need to check the status of the user.
+ def is_admin?
+ return !session[:using_admin].nil? || (!@user.nil? && @user.super?)
+ end
+
end
diff --git a/app/helpers/link_to_helper.rb b/app/helpers/link_to_helper.rb
index 994da0e87..030fab20b 100755
--- a/app/helpers/link_to_helper.rb
+++ b/app/helpers/link_to_helper.rb
@@ -255,9 +255,11 @@ module LinkToHelper
# Basic date format
def simple_date(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"
- return I18n.l(date.to_date, :format => date_format)
+ return I18n.l(date, :format => date_format)
end
def simple_time(date)
diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb
index a40898aef..2f8a9ab04 100644
--- a/app/models/foi_attachment.rb
+++ b/app/models/foi_attachment.rb
@@ -38,7 +38,7 @@ class FoiAttachment < ActiveRecord::Base
BODY_MAX_DELAY = 5
def directory
- rails_env = ENV['RAILS_ENV']
+ rails_env = Rails.env
if rails_env.nil? || rails_env.empty?
raise "$RAILS_ENV is not set"
end
@@ -67,9 +67,22 @@ class FoiAttachment < ActiveRecord::Base
file.write d
}
update_display_size!
+ encode_cached_body!
@cached_body = d
end
+ # If the original mail part had a charset, it's some kind of string, so assume that
+ # it should be handled as a string in the stated charset, not a bytearray, and then
+ # convert it our default encoding. For ruby 1.8 this is a noop.
+ def encode_cached_body!
+ if RUBY_VERSION.to_f >= 1.9
+ if charset
+ @cached_body.force_encoding(charset)
+ @cached_body = @cached_body.encode(Encoding.default_internal, charset)
+ end
+ end
+ end
+
def body
if @cached_body.nil?
tries = 0
@@ -90,6 +103,7 @@ class FoiAttachment < ActiveRecord::Base
self.incoming_message.parse_raw_email!(force)
retry
end
+ encode_cached_body!
end
return @cached_body
end
@@ -310,31 +324,41 @@ class FoiAttachment < ActiveRecord::Base
# the extractions will also produce image files, which go in the
# current directory, so change to the directory the function caller
# wants everything in
- Dir.chdir(dir) do
- tempfile = Tempfile.new('foiextract', '.')
- tempfile.print self.body
- tempfile.flush
-
- html = nil
- if self.content_type == 'application/pdf'
- # We set a timeout here, because pdftohtml can spiral out of control
- # on some PDF files and we don’t want to crash the whole server.
- html = AlaveteliExternalCommand.run("pdftohtml", "-nodrm", "-zoom", "1.0", "-stdout", "-enc", "UTF-8", "-noframes", tempfile.path, :timeout => 30)
- elsif self.content_type == 'application/rtf'
- html = AlaveteliExternalCommand.run("unrtf", "--html", tempfile.path, :timeout => 120)
- end
-
- if html.nil?
- if self.has_google_docs_viewer?
- html = '' # force error and using Google docs viewer
+
+ html = nil
+ if ['application/pdf', 'application/rtf'].include?(self.content_type)
+ text = self.body
+ Dir.chdir(dir) do
+ if RUBY_VERSION.to_f >= 1.9
+ tempfile = Tempfile.new('foiextract', '.', :encoding => text.encoding)
else
- raise "No HTML conversion available for type " + self.content_type
+ tempfile = Tempfile.new('foiextract', '.')
end
- end
+ tempfile.print text
+ tempfile.flush
+
- tempfile.close
- tempfile.delete
+ if self.content_type == 'application/pdf'
+ # We set a timeout here, because pdftohtml can spiral out of control
+ # on some PDF files and we don't want to crash the whole server.
+ html = AlaveteliExternalCommand.run("pdftohtml", "-nodrm", "-zoom", "1.0", "-stdout", "-enc", "UTF-8", "-noframes", tempfile.path, :timeout => 30)
+ elsif self.content_type == 'application/rtf'
+ html = AlaveteliExternalCommand.run("unrtf", "--html", tempfile.path, :timeout => 120)
+ end
+
+ tempfile.close
+ tempfile.delete
+ end
end
+ if html.nil?
+ if self.has_google_docs_viewer?
+ html = '' # force error and using Google docs viewer
+ else
+ raise "No HTML conversion available for type " + self.content_type
+ end
+ end
+
+
# We need to look at:
# a) Any error code
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index 60828e179..a02d2456a 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -38,14 +38,6 @@ require 'zip/zip'
require 'mapi/msg'
require 'mapi/convert'
-# Monkeypatch! Adding some extra members to store extra info in.
-module TMail
- class Mail
- attr_accessor :url_part_number
- attr_accessor :rfc822_attachment # when a whole email message is attached as text
- attr_accessor :within_rfc822_attachment # for parts within a message attached as text (for getting subject mainly)
- end
-end
class IncomingMessage < ActiveRecord::Base
belongs_to :info_request
@@ -70,34 +62,35 @@ class IncomingMessage < ActiveRecord::Base
'application/zip' => 1,
}
- # Return the structured TMail::Mail object
- # Documentation at http://i.loveruby.net/en/projects/tmail/doc/
+ # Return a cached structured mail object
def mail(force = nil)
if (!force.nil? || @mail.nil?) && !self.raw_email.nil?
- # Hack round bug in TMail's MIME decoding.
- # Report of TMail bug:
- # http://rubyforge.org/tracker/index.php?func=detail&aid=21810&group_id=4512&atid=17370
- copy_of_raw_data = self.raw_email.data.gsub(/; boundary=\s+"/im,'; boundary="')
-
- @mail = TMail::Mail.parse(copy_of_raw_data)
- @mail.base64_decode
+ @mail = MailHandler.mail_from_raw_email(self.raw_email.data)
end
@mail
end
- # Returns the name of the person the incoming message is from, or nil if
- # there isn't one or if there is only an email address. XXX can probably
- # remove from_name_if_present (which is a monkey patch) by just calling
- # .from_addrs[0].name here instead?
+ def empty_from_field?
+ self.mail.from_addrs.nil? || self.mail.from_addrs.size == 0
+ end
+
+ def from_email
+ MailHandler.get_from_address(self.mail)
+ end
+
+ def addresses
+ MailHandler.get_all_addresses(self.mail)
+ end
+
+ def message_id
+ self.mail.message_id
+ end
# Return false if for some reason this is a message that we shouldn't let them reply to
def _calculate_valid_to_reply_to
# check validity of email
- if self.mail.from_addrs.nil? || self.mail.from_addrs.size == 0
- return false
- end
- email = self.mail.from_addrs[0].spec
- if !MySociety::Validate.is_valid_email(email)
+ email = self.from_email
+ if email.nil? || !MySociety::Validate.is_valid_email(email)
return false
end
@@ -107,13 +100,13 @@ class IncomingMessage < ActiveRecord::Base
prefix = email
prefix =~ /^(.*)@/
prefix = $1
- if !prefix.nil? && prefix.downcase.match(/^(postmaster|mailer-daemon|auto_reply|donotreply|no.reply)$/)
+ if !prefix.nil? && prefix.downcase.match(/^(postmaster|mailer-daemon|auto_reply|do.?not.?reply|no.reply)$/)
return false
end
- if !self.mail['return-path'].nil? && self.mail['return-path'].addr == "<>"
+ if MailHandler.empty_return_path?(self.mail)
return false
end
- if !self.mail['auto-submitted'].nil?
+ if !MailHandler.get_auto_submitted(self.mail).nil?
return false
end
return true
@@ -131,13 +124,10 @@ class IncomingMessage < ActiveRecord::Base
self.extract_attachments!
self.sent_at = self.mail.date || self.created_at
self.subject = self.mail.subject
- # XXX can probably remove from_name_if_present (which is a
- # monkey patch) by just calling .from_addrs[0].name here
- # instead?
- self.mail_from = self.mail.from_name_if_present
- begin
- self.mail_from_domain = PublicBody.extract_domain_from_email(self.mail.from_addrs[0].spec)
- rescue NoMethodError
+ self.mail_from = MailHandler.get_from_name(self.mail)
+ if self.from_email
+ self.mail_from_domain = PublicBody.extract_domain_from_email(self.from_email)
+ else
self.mail_from_domain = ""
end
self.valid_to_reply_to = self._calculate_valid_to_reply_to
@@ -183,54 +173,8 @@ class IncomingMessage < ActiveRecord::Base
super
end
- # Number the attachments in depth first tree order, for use in URLs.
- # XXX This fills in part.rfc822_attachment and part.url_part_number within
- # all the parts of the email (see TMail monkeypatch above for how these
- # attributes are added). ensure_parts_counted must be called before using
- # the attributes.
- def ensure_parts_counted
- @count_parts_count = 0
- _count_parts_recursive(self.mail)
- # we carry on using these numeric ids for attachments uudecoded from within text parts
- @count_first_uudecode_count = @count_parts_count
- end
- def _count_parts_recursive(part)
- if part.multipart?
- part.parts.each do |p|
- _count_parts_recursive(p)
- end
- else
- part_filename = TMail::Mail.get_part_file_name(part)
- begin
- if part.content_type == 'message/rfc822'
- # An email attached as text
- # e.g. http://www.whatdotheyknow.com/request/64/response/102
- part.rfc822_attachment = TMail::Mail.parse(part.body)
- elsif part.content_type == 'application/vnd.ms-outlook' || part_filename && AlaveteliFileTypes.filename_to_mimetype(part_filename) == 'application/vnd.ms-outlook'
- # An email attached as an Outlook file
- # e.g. http://www.whatdotheyknow.com/request/chinese_names_for_british_politi
- msg = Mapi::Msg.open(StringIO.new(part.body))
- part.rfc822_attachment = TMail::Mail.parse(msg.to_mime.to_s)
- elsif part.content_type == 'application/ms-tnef'
- # A set of attachments in a TNEF file
- part.rfc822_attachment = TNEF.as_tmail(part.body)
- end
- rescue
- # If attached mail doesn't parse, treat it as text part
- part.rfc822_attachment = nil
- else
- unless part.rfc822_attachment.nil?
- _count_parts_recursive(part.rfc822_attachment)
- end
- end
- if part.rfc822_attachment.nil?
- @count_parts_count += 1
- part.url_part_number = @count_parts_count
- end
- end
- end
# And look up by URL part number to get an attachment
- # XXX relies on extract_attachments calling ensure_parts_counted
+ # XXX relies on extract_attachments calling MailHandler.ensure_parts_counted
def self.get_attachment_by_url_part_number(attachments, found_url_part_number)
attachments.each do |a|
if a.url_part_number == found_url_part_number
@@ -451,105 +395,6 @@ class IncomingMessage < ActiveRecord::Base
return text
end
- # Internal function
- def _get_part_file_name(mail)
- part_file_name = TMail::Mail.get_part_file_name(mail)
- if part_file_name.nil?
- return nil
- end
- part_file_name = part_file_name.dup
- return part_file_name
- end
-
- # (This risks losing info if the unchosen alternative is the only one to contain
- # useful info, but let's worry about that another time)
- def get_attachment_leaves
- force = true
- return _get_attachment_leaves_recursive(self.mail(force))
- end
- def _get_attachment_leaves_recursive(curr_mail, within_rfc822_attachment = nil)
- leaves_found = []
- if curr_mail.multipart?
- if curr_mail.parts.size == 0
- raise "no parts on multipart mail"
- end
-
- if curr_mail.sub_type == 'alternative'
- # Choose best part from alternatives
- best_part = nil
- # Take the last text/plain one, or else the first one
- curr_mail.parts.each do |m|
- if not best_part
- best_part = m
- elsif m.content_type == 'text/plain'
- best_part = m
- end
- end
- # Take an HTML one as even higher priority. (They tend
- # to render better than text/plain, e.g. don't wrap links here:
- # http://www.whatdotheyknow.com/request/amount_and_cost_of_freedom_of_in#incoming-72238 )
- curr_mail.parts.each do |m|
- if m.content_type == 'text/html'
- best_part = m
- end
- end
- leaves_found += _get_attachment_leaves_recursive(best_part, within_rfc822_attachment)
- else
- # Add all parts
- curr_mail.parts.each do |m|
- leaves_found += _get_attachment_leaves_recursive(m, within_rfc822_attachment)
- end
- end
- else
- # XXX Yuck. this section alters various content_type's. That puts
- # it into conflict with ensure_parts_counted which it has to be
- # called both before and after. It will fail with cases of
- # attachments of attachments etc.
- charset = curr_mail.charset # save this, because overwriting content_type also resets charset
- # Don't allow nil content_types
- if curr_mail.content_type.nil?
- curr_mail.content_type = 'application/octet-stream'
- end
- # PDFs often come with this mime type, fix it up for view code
- if curr_mail.content_type == 'application/octet-stream'
- part_file_name = self._get_part_file_name(curr_mail)
- calc_mime = AlaveteliFileTypes.filename_and_content_to_mimetype(part_file_name, curr_mail.body)
- if calc_mime
- curr_mail.content_type = calc_mime
- end
- end
-
- # Use standard content types for Word documents etc.
- curr_mail.content_type = normalise_content_type(curr_mail.content_type)
- if curr_mail.content_type == 'message/rfc822'
- ensure_parts_counted # fills in rfc822_attachment variable
- if curr_mail.rfc822_attachment.nil?
- # Attached mail didn't parse, so treat as text
- curr_mail.content_type = 'text/plain'
- end
- end
- if curr_mail.content_type == 'application/vnd.ms-outlook' || curr_mail.content_type == 'application/ms-tnef'
- ensure_parts_counted # fills in rfc822_attachment variable
- if curr_mail.rfc822_attachment.nil?
- # Attached mail didn't parse, so treat as binary
- curr_mail.content_type = 'application/octet-stream'
- end
- end
- # If the part is an attachment of email
- if curr_mail.content_type == 'message/rfc822' || curr_mail.content_type == 'application/vnd.ms-outlook' || curr_mail.content_type == 'application/ms-tnef'
- ensure_parts_counted # fills in rfc822_attachment variable
- leaves_found += _get_attachment_leaves_recursive(curr_mail.rfc822_attachment, curr_mail.rfc822_attachment)
- else
- # Store leaf
- curr_mail.within_rfc822_attachment = within_rfc822_attachment
- leaves_found += [curr_mail]
- end
- # restore original charset
- curr_mail.charset = charset
- end
- return leaves_found
- end
-
# Removes anything cached about the object in the database, and saves
def clear_in_database_caches!
self.cached_attachment_text_clipped = nil
@@ -612,7 +457,8 @@ class IncomingMessage < ActiveRecord::Base
text = "[ Email has no body, please see attachments ]"
source_charset = "utf-8"
else
- text = part.body # by default, TMail converts to UTF8 in this call
+ # by default, the body (coming from an foi_attachment) should have been converted to utf-8
+ text = part.body
source_charset = part.charset
if part.content_type == 'text/html'
# e.g. http://www.whatdotheyknow.com/request/35/response/177
@@ -620,42 +466,31 @@ class IncomingMessage < ActiveRecord::Base
# convert to text routine. Could instead call a
# sanitize HTML one.
- # If the text isn't UTF8, it means TMail had a problem
+ # If the text isn't UTF8, it means we had a problem
# converting it (invalid characters, etc), and we
# should instead tell elinks to respect the source
# charset
use_charset = "utf-8"
- begin
- text = Iconv.conv('utf-8', 'utf-8', text)
- rescue Iconv::IllegalSequence
- use_charset = source_charset
- end
- text = self.class._get_attachment_text_internal_one_file(part.content_type, text, use_charset)
- end
- end
-
- # If TMail can't convert text, it just returns it, so we sanitise it.
- begin
- # Test if it's good UTF-8
- text = Iconv.conv('utf-8', 'utf-8', text)
- rescue Iconv::IllegalSequence
- # Text looks like unlabelled nonsense,
- # strip out anything that isn't UTF-8
- begin
- source_charset = 'utf-8' if source_charset.nil?
- text = Iconv.conv('utf-8//IGNORE', source_charset, text) +
- _("\n\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]",
- :site_name => Configuration::site_name)
- rescue Iconv::InvalidEncoding, Iconv::IllegalSequence
- if source_charset != "utf-8"
- source_charset = "utf-8"
- retry
+ if RUBY_VERSION.to_f >= 1.9
+ begin
+ text.encode('utf-8')
+ rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
+ use_charset = source_charset
+ end
+ else
+ begin
+ text = Iconv.conv('utf-8', 'utf-8', text)
+ rescue Iconv::IllegalSequence
+ use_charset = source_charset
+ end
end
+ text = MailHandler.get_attachment_text_one_file(part.content_type, text, use_charset)
end
end
+ # If text hasn't been converted, we sanitise it.
+ text = _sanitize_text(text)
# Fix DOS style linefeeds to Unix style ones (or other later regexps won't work)
- # Needed for e.g. http://www.whatdotheyknow.com/request/60/response/98
text = text.gsub(/\r\n/, "\n")
# Compress extra spaces down to save space, and to stop regular expressions
@@ -665,6 +500,51 @@ class IncomingMessage < ActiveRecord::Base
return text
end
+
+ def _sanitize_text(text)
+ if RUBY_VERSION.to_f >= 1.9
+ begin
+ # Test if it's good UTF-8
+ text.encode('utf-8')
+ rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
+ source_charset = 'utf-8' if source_charset.nil?
+ # strip out anything that isn't UTF-8
+ begin
+ text = text.encode("utf-8", :invalid => :replace,
+ :undef => :replace,
+ :replace => "") +
+ _("\n\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]",
+ :site_name => MySociety::Config.get('SITE_NAME', 'Alaveteli'))
+ rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
+ if source_charset != "utf-8"
+ source_charset = "utf-8"
+ retry
+ end
+ end
+ end
+ else
+ begin
+ # Test if it's good UTF-8
+ text = Iconv.conv('utf-8', 'utf-8', text)
+ rescue Iconv::IllegalSequence
+ # Text looks like unlabelled nonsense,
+ # strip out anything that isn't UTF-8
+ begin
+ source_charset = 'utf-8' if source_charset.nil?
+ text = Iconv.conv('utf-8//IGNORE', source_charset, text) +
+ _("\n\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]",
+ :site_name => Configuration::site_name)
+ rescue Iconv::InvalidEncoding, Iconv::IllegalSequence
+ if source_charset != "utf-8"
+ source_charset = "utf-8"
+ retry
+ end
+ end
+ end
+ end
+ text
+ end
+
# Returns part which contains main body text, or nil if there isn't one
def get_main_body_text_part
leaves = self.foi_attachments
@@ -718,7 +598,7 @@ class IncomingMessage < ActiveRecord::Base
filename = uu.match(/^begin\s+[0-9]+\s+(.*)$/)[1]
calc_mime = AlaveteliFileTypes.filename_and_content_to_mimetype(filename, content)
if calc_mime
- calc_mime = normalise_content_type(calc_mime)
+ calc_mime = MailHandler.normalise_content_type(calc_mime)
content_type = calc_mime
else
content_type = 'application/octet-stream'
@@ -747,55 +627,15 @@ class IncomingMessage < ActiveRecord::Base
end
def extract_attachments!
- leaves = get_attachment_leaves # XXX check where else this is called from
- # XXX we have to call ensure_parts_counted after get_attachment_leaves
- # which is really messy.
- ensure_parts_counted
+ force = true
+ attachment_attributes = MailHandler.get_attachment_attributes(self.mail(force))
attachments = []
- for leaf in leaves
- body = leaf.body
- # As leaf.body causes MIME decoding which uses lots of RAM, do garbage collection here
- # to prevent excess memory use. XXX not really sure if this helps reduce
- # peak RAM use overall. Anyway, maybe there is something better to do than this.
- GC.start
- if leaf.within_rfc822_attachment
- within_rfc822_subject = leaf.within_rfc822_attachment.subject
- # Test to see if we are in the first part of the attached
- # RFC822 message and it is text, if so add headers.
- # XXX should probably use hunting algorithm to find main text part, rather than
- # just expect it to be first. This will do for now though.
- # Example request that needs this:
- # http://www.whatdotheyknow.com/request/2923/response/7013/attach/2/Cycle%20Path%20Bank.txt
- if leaf.within_rfc822_attachment == leaf && leaf.content_type == 'text/plain'
- headers = ""
- for header in [ 'Date', 'Subject', 'From', 'To', 'Cc' ]
- if leaf.within_rfc822_attachment.header.include?(header.downcase)
- header_value = leaf.within_rfc822_attachment.header[header.downcase]
- # Example message which has a blank Date header:
- # http://www.whatdotheyknow.com/request/30747/response/80253/attach/html/17/Common%20Purpose%20Advisory%20Group%20Meeting%20Tuesday%202nd%20March.txt.html
- if !header_value.blank?
- headers = headers + header + ": " + header_value.to_s + "\n"
- end
- end
- end
- # XXX call _convert_part_body_to_text here, but need to get charset somehow
- # e.g. http://www.whatdotheyknow.com/request/1593/response/3088/attach/4/Freedom%20of%20Information%20request%20-%20car%20oval%20sticker:%20Article%2020,%20Convention%20on%20Road%20Traffic%201949.txt
- body = headers + "\n" + body
-
- # This is quick way of getting all headers, but instead we only add some a) to
- # make it more usable, b) as at least one authority accidentally leaked security
- # information into a header.
- #attachment.body = leaf.within_rfc822_attachment.port.to_s
- end
- end
- hexdigest = Digest::MD5.hexdigest(body)
- attachment = self.foi_attachments.find_or_create_by_hexdigest(:hexdigest => hexdigest)
- attachment.update_attributes(:url_part_number => leaf.url_part_number,
- :content_type => leaf.content_type,
- :filename => _get_part_file_name(leaf),
- :charset => leaf.charset,
- :within_rfc822_subject => within_rfc822_subject,
- :body => body)
+ attachment_attributes.each do |attrs|
+ attachment = self.foi_attachments.find_or_create_by_hexdigest(:hexdigest => attrs[:hexdigest])
+ body = attrs.delete(:body)
+ attachment.update_attributes(attrs)
+ # Set the body separately as its handling can depend on the value of charset
+ attachment.body = body
attachment.save!
attachments << attachment.id
end
@@ -805,7 +645,7 @@ class IncomingMessage < ActiveRecord::Base
# e.g. for https://secure.mysociety.org/admin/foi/request/show_raw_email/24550
if !main_part.nil?
uudecoded_attachments = _uudecode_and_save_attachments(main_part.body)
- c = @count_first_uudecode_count
+ c = self.mail.count_first_uudecode_count
for uudecode_attachment in uudecoded_attachments
c += 1
uudecode_attachment.url_part_number = c
@@ -897,101 +737,15 @@ class IncomingMessage < ActiveRecord::Base
return self.cached_attachment_text_clipped
end
- def IncomingMessage._get_attachment_text_internal_one_file(content_type, body, charset = 'utf-8')
- # note re. charset: TMail always tries to convert email bodies
- # to UTF8 by default, so normally it should already be that.
- text = ''
- # XXX - tell all these command line tools to return utf-8
- if content_type == 'text/plain'
- text += body + "\n\n"
- else
- tempfile = Tempfile.new('foiextract')
- tempfile.print body
- tempfile.flush
- if content_type == 'application/vnd.ms-word'
- AlaveteliExternalCommand.run("wvText", tempfile.path, tempfile.path + ".txt")
- # Try catdoc if we get into trouble (e.g. for InfoRequestEvent 2701)
- if not File.exists?(tempfile.path + ".txt")
- AlaveteliExternalCommand.run("catdoc", tempfile.path, :append_to => text)
- else
- text += File.read(tempfile.path + ".txt") + "\n\n"
- File.unlink(tempfile.path + ".txt")
- end
- elsif content_type == 'application/rtf'
- # catdoc on RTF prodcues less comments and extra bumf than --text option to unrtf
- AlaveteliExternalCommand.run("catdoc", tempfile.path, :append_to => text)
- elsif content_type == 'text/html'
- # lynx wordwraps links in its output, which then don't
- # get formatted properly by Alaveteli. We use elinks
- # instead, which doesn't do that.
- AlaveteliExternalCommand.run("elinks", "-eval", "set document.codepage.assume = \"#{charset}\"", "-eval", "set document.codepage.force_assumed = 1", "-dump-charset", "utf-8", "-force-html", "-dump",
- tempfile.path, :append_to => text, :env => {"LANG" => "C"})
- elsif content_type == 'application/vnd.ms-excel'
- # Bit crazy using /usr/bin/strings - but xls2csv, xlhtml and
- # py_xls2txt only extract text from cells, not from floating
- # notes. catdoc may be fooled by weird character sets, but will
- # probably do for UK FOI requests.
- AlaveteliExternalCommand.run("/usr/bin/strings", tempfile.path, :append_to => text)
- elsif content_type == 'application/vnd.ms-powerpoint'
- # ppthtml seems to catch more text, but only outputs HTML when
- # we want text, so just use catppt for now
- AlaveteliExternalCommand.run("catppt", tempfile.path, :append_to => text)
- elsif content_type == 'application/pdf'
- AlaveteliExternalCommand.run("pdftotext", tempfile.path, "-", :append_to => text)
- elsif content_type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- # This is Microsoft's XML office document format.
- # Just pull out the main XML file, and strip it of text.
- xml = AlaveteliExternalCommand.run("/usr/bin/unzip", "-qq", "-c", tempfile.path, "word/document.xml")
- if !xml.nil?
- doc = REXML::Document.new(xml)
- text += doc.each_element( './/text()' ){}.join(" ")
- end
- elsif content_type == 'application/zip'
- # recurse into zip files
- begin
- zip_file = Zip::ZipFile.open(tempfile.path)
- text += IncomingMessage._get_attachment_text_from_zip_file(zip_file)
- zip_file.close()
- rescue
- $stderr.puts("Error processing zip file: #{$!.inspect}")
- end
- end
- tempfile.close
- end
- return text
- end
- def IncomingMessage._get_attachment_text_from_zip_file(zip_file)
- text = ""
- for entry in zip_file
- if entry.file?
- filename = entry.to_s
- begin
- body = entry.get_input_stream.read
- rescue
- # move to next attachment silently if there were problems
- # XXX really should reduce this to specific exceptions?
- # e.g. password protected
- next
- end
- calc_mime = AlaveteliFileTypes.filename_to_mimetype(filename)
- if calc_mime
- content_type = calc_mime
- else
- content_type = 'application/octet-stream'
- end
-
- text += _get_attachment_text_internal_one_file(content_type, body)
- end
- end
- return text
- end
def _get_attachment_text_internal
# Extract text from each attachment
text = ''
attachments = self.get_attachments_for_display
for attachment in attachments
- text += IncomingMessage._get_attachment_text_internal_one_file(attachment.content_type, attachment.body, attachment.charset)
+ text += MailHandler.get_attachment_text_one_file(attachment.content_type,
+ attachment.body,
+ attachment.charset)
end
# Remove any bad characters
text = Iconv.conv('utf-8//IGNORE', 'utf-8', text)
@@ -1059,66 +813,12 @@ class IncomingMessage < ActiveRecord::Base
return AlaveteliFileTypes.all_extensions.join(" ")
end
- # Return false if for some reason this is a message that we shouldn't let them reply to
- def valid_to_reply_to?
- # check validity of email
- if self.mail.from_addrs.nil? || self.mail.from_addrs.size == 0
- return false
- end
- email = self.mail.from_addrs[0].spec
- if !MySociety::Validate.is_valid_email(email)
- return false
- end
-
- # reject postmaster - authorities seem to nearly always not respond to
- # email to postmaster, and it tends to only happen after delivery failure.
- # likewise Mailer-Daemon, Auto_Reply...
- prefix = email
- prefix =~ /^(.*)@/
- prefix = $1
- if !prefix.nil? && prefix.downcase.match(/^(postmaster|mailer-daemon|auto_reply|do.?not.?reply|no.reply)$/)
- return false
+ def for_admin_column
+ self.class.content_columns.each do |column|
+ yield(column.human_name, self.send(column.name), column.type.to_s, column.name)
end
- if !self.mail['return-path'].nil? && self.mail['return-path'].addr == "<>"
- return false
- end
- if !self.mail['auto-submitted'].nil?
- return false
- end
- return true
end
- def normalise_content_type(content_type)
- # e.g. http://www.whatdotheyknow.com/request/93/response/250
- if content_type == 'application/excel' or content_type == 'application/msexcel' or content_type == 'application/x-ms-excel'
- content_type = 'application/vnd.ms-excel'
- end
- if content_type == 'application/mspowerpoint' or content_type == 'application/x-ms-powerpoint'
- content_type = 'application/vnd.ms-powerpoint'
- end
- if content_type == 'application/msword' or content_type == 'application/x-ms-word'
- content_type = 'application/vnd.ms-word'
- end
- if content_type == 'application/x-zip-compressed'
- content_type = 'application/zip'
- end
-
- # e.g. http://www.whatdotheyknow.com/request/copy_of_current_swessex_scr_opt#incoming-9928
- if content_type == 'application/acrobat'
- content_type = 'application/pdf'
- end
-
- return content_type
- end
-
- def for_admin_column
- self.class.content_columns.each do |column|
- yield(column.human_name, self.send(column.name), column.type.to_s, column.name)
- end
- end
-
- private :normalise_content_type
-
end
diff --git a/app/models/info_request.rb b/app/models/info_request.rb
index 89893a396..3355b9443 100644
--- a/app/models/info_request.rb
+++ b/app/models/info_request.rb
@@ -138,7 +138,7 @@ class InfoRequest < ActiveRecord::Base
if external_user_name.nil?
fake_slug = "anonymous"
else
- fake_slug = external_user_name.parameterize
+ fake_slug = MySociety::Format.simplify_url_part(external_user_name, 'external_user', 32)
end
(public_body.url_name || "") + "_" + fake_slug
else
@@ -275,7 +275,7 @@ public
return self.magic_email("request-")
end
def incoming_name_and_email
- return TMail::Address.address_from_name_and_email(self.user_name, self.incoming_email).to_s
+ return MailHandler.address_from_name_and_email(self.user_name, self.incoming_email)
end
# Subject lines for emails about the request
@@ -355,12 +355,7 @@ public
def InfoRequest.guess_by_incoming_email(incoming_message)
guesses = []
# 1. Try to guess based on the email address(es)
- addresses =
- (incoming_message.mail.to || []) +
- (incoming_message.mail.cc || []) +
- (incoming_message.mail.envelope_to || [])
- addresses.uniq!
- for address in addresses
+ incoming_message.addresses.each do |address|
id, hash = InfoRequest._extract_id_hash_from_email(address)
guesses.push(InfoRequest.find_by_id(id))
guesses.push(InfoRequest.find_by_idhash(hash))
@@ -419,8 +414,7 @@ public
end
for im in self.incoming_messages
- other_message_id = im.mail.message_id
- if message_id == other_message_id
+ if message_id == im.message_id
return true
end
end
@@ -440,11 +434,11 @@ public
elsif self.allow_new_responses_from == 'anybody'
allow = true
elsif self.allow_new_responses_from == 'authority_only'
- if email.from_addrs.nil? || email.from_addrs.size == 0
+ sender_email = MailHandler.get_from_address(email)
+ if sender_email.nil?
allow = false
reason = _('Only the authority can reply to this request, but there is no "From" address to check against')
else
- sender_email = email.from_addrs[0].spec
sender_domain = PublicBody.extract_domain_from_email(sender_email)
reason = _("Only the authority can reply to this request, and I don't recognise the address this reply was sent from")
allow = false
@@ -713,11 +707,11 @@ public
return self.public_body.is_followupable?
end
def recipient_name_and_email
- return TMail::Address.address_from_name_and_email(
+ return MailHandler.address_from_name_and_email(
_("{{law_used}} requests at {{public_body}}",
:law_used => self.law_used_short,
:public_body => self.public_body.short_or_long_name),
- self.recipient_email).to_s
+ self.recipient_email)
end
# History of some things that have happened
@@ -1130,7 +1124,11 @@ public
}
if deep
- ret[:user] = self.user.json_for_api
+ if self.user
+ ret[:user] = self.user.json_for_api
+ else
+ ret[:user_name] = self.user_name
+ end
ret[:public_body] = self.public_body.json_for_api
ret[:info_request_events] = self.info_request_events.map { |e| e.json_for_api(false) }
end
diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb
index 5a8e3416f..09eba31ab 100644
--- a/app/models/info_request_event.rb
+++ b/app/models/info_request_event.rb
@@ -384,7 +384,7 @@ class InfoRequestEvent < ActiveRecord::Base
if prev_addr.nil? || curr_addr.nil?
return false
end
- return TMail::Address.parse(prev_addr).address == TMail::Address.parse(curr_addr).address
+ return MailHandler.address_from_string(prev_addr) == MailHandler.address_from_string(curr_addr)
end
def json_for_api(deep, snippet_highlight_proc = nil)
diff --git a/app/models/outgoing_mailer.rb b/app/models/outgoing_mailer.rb
index a307bb778..503166b8a 100644
--- a/app/models/outgoing_mailer.rb
+++ b/app/models/outgoing_mailer.rb
@@ -47,7 +47,8 @@ class OutgoingMailer < ApplicationMailer
return info_request.recipient_name_and_email
else
# calling safe_mail_from from so censor rules are run
- return TMail::Address.address_from_name_and_email(incoming_message_followup.safe_mail_from, incoming_message_followup.mail.from_addrs[0].spec).to_s
+ return MailHandler.address_from_name_and_email(incoming_message_followup.safe_mail_from,
+ incoming_message_followup.from_email)
end
end
# Used in the preview of followup
@@ -64,7 +65,7 @@ class OutgoingMailer < ApplicationMailer
if incoming_message_followup.nil? || !incoming_message_followup.valid_to_reply_to?
return info_request.recipient_email
else
- return incoming_message_followup.mail.from_addrs[0].spec
+ return incoming_message_followup.from_email
end
end
# Subject to use for followup
diff --git a/app/models/raw_email.rb b/app/models/raw_email.rb
index bae144931..de7978b82 100644
--- a/app/models/raw_email.rb
+++ b/app/models/raw_email.rb
@@ -22,7 +22,7 @@ class RawEmail < ActiveRecord::Base
if request_id.empty?
raise "Failed to find the id number of the associated request: has it been saved?"
end
-
+
if ENV["RAILS_ENV"] == "test"
return File.join(Rails.root, 'files/raw_email_test')
else
@@ -49,7 +49,7 @@ class RawEmail < ActiveRecord::Base
end
def data
- File.open(self.filepath, "rb").read
+ File.open(self.filepath, "r").read
end
def destroy_file_representation!
diff --git a/app/models/request_mailer.rb b/app/models/request_mailer.rb
index 90c4c6b53..493d6961c 100644
--- a/app/models/request_mailer.rb
+++ b/app/models/request_mailer.rb
@@ -204,15 +204,14 @@ class RequestMailer < ApplicationMailer
#
# That is because we want to be sure we properly record the actual message
# received in its raw form - so any information won't be lost in a round
- # trip via TMail, or by bugs in it, and so we can use something other than
- # TMail at a later date. And so we can offer an option to download the
+ # trip via the mail handler, or by bugs in it, and so we can use something
+ # other than TMail at a later date. And so we can offer an option to download the
# actual original mail sent by the authority in the admin interface (so
# can check that attachment decoding failures are problems in the message,
# not in our code). ]
def self.receive(raw_email)
logger.info "Received mail:\n #{raw_email}" unless logger.nil?
- mail = TMail::Mail.parse(raw_email)
- mail.base64_decode
+ mail = MailHandler.mail_from_raw_email(raw_email)
new.receive(mail, raw_email)
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 70386f7e4..6e1e21481 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -203,7 +203,7 @@ class User < ActiveRecord::Base
# For use in to/from in email messages
def name_and_email
- return TMail::Address.address_from_name_and_email(self.name, self.email).to_s
+ return MailHandler.address_from_name_and_email(self.name, self.email)
end
# The "internal admin" is a special user for internal use.
diff --git a/app/views/comment/_single_comment.rhtml b/app/views/comment/_single_comment.rhtml
index 013e5e107..b645721cf 100644
--- a/app/views/comment/_single_comment.rhtml
+++ b/app/views/comment/_single_comment.rhtml
@@ -11,7 +11,7 @@
</h2>
<div class="comment_in_request_text">
<p>
- <img class="comment_quote" src="/images/quote.png" alt="">
+ <img class="comment_quote" src="/images/quote-marks.png" alt="">
<%= comment.get_body_for_html_display %>
</p>
</div>
diff --git a/app/views/general/_frontpage_new_request.rhtml b/app/views/general/_frontpage_new_request.rhtml
index fd4225069..499b60eb5 100644
--- a/app/views/general/_frontpage_new_request.rhtml
+++ b/app/views/general/_frontpage_new_request.rhtml
@@ -4,4 +4,4 @@
Information<br/>
request</strong>") %>
</h1>
-<a class="link_button_green_large" href="/select_authority"><%= _("Start now &raquo;") %></a>
+<a class="link_button_green_large" href="<%= select_authority_path %>"><%= _("Start now &raquo;") %></a>
diff --git a/app/views/general/_frontpage_search_box.rhtml b/app/views/general/_frontpage_search_box.rhtml
index 6de4eae98..d2718b3a3 100644
--- a/app/views/general/_frontpage_search_box.rhtml
+++ b/app/views/general/_frontpage_search_box.rhtml
@@ -4,7 +4,7 @@
<strong>{{number_of_authorities}} authorities</strong>",
:number_of_requests => InfoRequest.visible.count, :number_of_authorities => PublicBody.visible.count) %>
</h2>
-<form id="search_form" method="post" action="/search">
+<form id="search_form" method="post" action="<%= search_redirect_path %>">
<div>
<input id="query" type="text" size="30" name="query">
<input type="submit" value="<%= _('Search') %>">
diff --git a/app/views/help/_sidebar.rhtml b/app/views/help/_sidebar.rhtml
index 783d35983..2b7ed5647 100644
--- a/app/views/help/_sidebar.rhtml
+++ b/app/views/help/_sidebar.rhtml
@@ -1,19 +1,19 @@
<div id="right_column_flip">
<h2>Help pages</h2>
<ul class="no_bullets">
- <li><%= link_to_unless_current "Introduction", "/help/about" %></li>
- <li><%= link_to_unless_current "Making requests", "/help/requesting" %></li>
- <li><%= link_to_unless_current "Your privacy", "/help/privacy" %></li>
- <li><%= link_to_unless_current "FOI officers", "/help/officers" %></li>
- <li><%= link_to_unless_current "About the software", "/help/alaveteli" %></li>
- <li><%= link_to_unless_current "Credits", "/help/credits" %></li>
- <li><%= link_to_unless_current "Programmers API", "/help/api" %></li>
- <li><%= link_to_unless_current "Advanced search", "/advancedsearch" %></li>
+ <li><%= link_to_unless_current "Introduction", help_about_path %></li>
+ <li><%= link_to_unless_current "Making requests", help_requesting_path %></li>
+ <li><%= link_to_unless_current "Your privacy", help_privacy_path %></li>
+ <li><%= link_to_unless_current "FOI officers", help_officers_path %></li>
+ <li><%= link_to_unless_current "About the software", help_alaveteli_path %></li>
+ <li><%= link_to_unless_current "Credits", help_credits_path %></li>
+ <li><%= link_to_unless_current "Programmers API", help_api_path %></li>
+ <li><%= link_to_unless_current "Advanced search", advanced_search_path %></li>
</ul>
<h2 id="contact">Contact us</h2>
<p>If your question isn't answered here, or you just wanted to let us know
- something about the site, <a href="/help/contact">contact&nbsp;us</a>.
+ something about the site, <a href="<%= help_contact_path %>">contact&nbsp;us</a>.
</p>
</div>
diff --git a/app/views/help/about.rhtml b/app/views/help/about.rhtml
index 9f75cac8b..477f0e750 100644
--- a/app/views/help/about.rhtml
+++ b/app/views/help/about.rhtml
@@ -41,13 +41,13 @@
</dd>
<dt id="updates">How can I keep up with news about WhatDoTheyKnow?<a href="#updates">#</a> </dt>
- <dd>We have a <a href="/blog">blog</a> and a <a href="https://twitter.com/whatdotheyknow">twitter feed</a>.
+ <dd>We have a <a href="<%= blog_path %>">blog</a> and a <a href="https://twitter.com/whatdotheyknow">twitter feed</a>.
</dd>
</dl>
- <p><strong>Next</strong>, read about <a href="/help/requesting">making requests</a> --&gt;
+ <p><strong>Next</strong>, read about <a href="<%= help_requesting_path %>">making requests</a> --&gt;
<div id="hash_link_padding"></div>
</div>
diff --git a/app/views/help/api.rhtml b/app/views/help/api.rhtml
index 76d2992fb..da6253f87 100644
--- a/app/views/help/api.rhtml
+++ b/app/views/help/api.rhtml
@@ -19,7 +19,7 @@
<dt>Linking to new requests</dt>
<dd>
<p>To encourage your users to make links to a particular public authority, use URLs of the form
- <%= link_to new_request_to_body_url(:url_name => "liverpool_city_council") , new_request_to_body_url(:url_name => "liverpool_city_council") %>.
+ <%= link_to new_request_to_body_url(:url_name => "liverpool_city_council") , new_request_to_body_url(:url_name => "liverpool_city_council") %>.
These are the parameters you can add to those URLs, either in the URL or from a form.
<ul>
@@ -34,7 +34,7 @@
<dd>
<p>There are Atom feeds on most pages which list FOI requests, which you can
use to get updates and links in XML format. Find the URL of the Atom feed in
- one of these ways:
+ one of these ways:
<ul>
<li>Look for the <img src="/images/feed-16.png" alt=""> RSS feed links.</li>
<li>Examine the <tt>&lt;link rel="alternate" type="application/atom+xml"&gt;</tt> tag in the head of the HTML. </li>
@@ -43,7 +43,7 @@
<p>In particular, even complicated search queries have Atom feeds.
You can do all sorts of things with them, such as query by authority, by file
- type, by date range, or by status. See the <a href="/search">advanced search
+ type, by date range, or by status. See the <a href="<%= advanced_search_path %>">advanced search
tips</a> for details.
</dd>
@@ -51,18 +51,18 @@
<dd>
<p>Quite a few pages have JSON versions, which let you download information about
objects in a structured form. Find them by:
+ </p>
<ul>
<li>Adding <tt>.json</tt> to the end of the URL. </li>
<li>Look for the <tt>&lt;link rel="alternate" type="application/json"&gt;</tt> tag in the head of the HTML. </li>
</ul>
- </p>
<p>Requests, users and authorities all have JSON versions containing basic
information about them. Every Atom feed has a JSON equivalent, containing
information about the list of events in the feed.
</p>
</dd>
-
+
<dt>Spreadsheet of all authorities</dt>
<dd>
<p>
@@ -73,7 +73,7 @@
</dd>
</dl>
- <p>Please <a href="/help/contact">contact us</a> if you need an API feature that isn't there yet. It's
+ <p>Please <a href="<%= help_contact_path %>">contact us</a> if you need an API feature that isn't there yet. It's
very much a work in progress, and we do add things when people ask us to.</p>
<div id="hash_link_padding"></div>
diff --git a/app/views/help/contact.rhtml b/app/views/help/contact.rhtml
index 37df68f49..fab5017b8 100644
--- a/app/views/help/contact.rhtml
+++ b/app/views/help/contact.rhtml
@@ -9,13 +9,13 @@
<% if !flash[:notice] %>
<h2>Contact an authority to get official information</h2>
<ul>
- <li><a href="/new">Go here</a> to make a request, in public, for information
+ <li><a href="<%= new_request_path %>">Go here</a> to make a request, in public, for information
from public authorities.</li>
<li>
Asking for private information about yourself?
Please read our
- <a href="/help/requesting#data_protection">help page</a>.
+ <a href="<%= help_requesting_path(:anchor => 'data_protection') %>">help page</a>.
</li>
</ul>
@@ -25,10 +25,10 @@
<% if !flash[:notice] %>
<ul>
<li>
- Please read the <a href="/help/about">help page</a> first, as it may
- answer your question quicker.
+ Please read the <a href="<%= help_about_path %>">help page</a> first, as it may
+ answer your question quicker.
</li>
-
+
<li>We'd love to hear how you've found using this site.
Either fill in this form, or send an email to <a
href="mailto:<%=@contact_email%>"><%=@contact_email%></a>
@@ -56,25 +56,25 @@
<% end %>
<p>
- <label class="form_label" for="contact_subject">Subject:</label>
+ <label class="form_label" for="contact_subject">Subject:</label>
<%= f.text_field :subject, :size => 50 %>
</p>
<p>
- <label class="form_label" for="contact_message">Message to website:</label>
+ <label class="form_label" for="contact_message">Message to website:</label>
<%= f.text_area :message, :rows => 10, :cols => 60 %>
</p>
<% if !@last_request.nil? %>
<p>
- <label class="form_label" for="contact_message">Include link to request:</label>
+ <label class="form_label" for="contact_message">Include link to request:</label>
<%=request_link(@last_request) %>
<%= submit_tag "remove", :name => 'remove' %>
</p>
<% end %>
<% if !@last_body.nil? %>
<p>
- <label class="form_label" for="contact_message">Include link to authority:</label>
+ <label class="form_label" for="contact_message">Include link to authority:</label>
<%=public_body_link(@last_body) %>
<%= submit_tag "remove", :name => 'remove' %>
</p>
diff --git a/app/views/help/officers.rhtml b/app/views/help/officers.rhtml
index 3defec62f..b13e225fe 100644
--- a/app/views/help/officers.rhtml
+++ b/app/views/help/officers.rhtml
@@ -19,13 +19,13 @@
</p>
<p>If you have privacy or other concerns, please read the answers below.
You might also like to read the <a
- href="/help/about">introduction to WhatDoTheyKnow</a> to find out more about what
+ href="<%= help_about_path %>">introduction to WhatDoTheyKnow</a> to find out more about what
the site does from the point of view of a user. You can also search the
site to find the authority that you work for, and view the status of
any requests made using the site.
<p>Finally, we welcome comments and
- thoughts from FOI officers, please <a href="/help/contact">get in touch</a>.
+ thoughts from FOI officers, please <a href="<%= help_contact_path %>">get in touch</a>.
</p>
</dd>
@@ -75,13 +75,13 @@
the authority by email. Any delivery failure messages will automatically
appear on the site. You can check the address we're using with the "View FOI
email address" link which appears on the page for the authority. <a
- href="/help/contact">Contact us</a> if there is a better address we can
+ href="<%= help_contact_path %>">Contact us</a> if there is a better address we can
use.</p>
<p>Requests are sometimes not delivered because they are quietly removed by
"spam filters" in the IT department of the authority. Authorities can make
- sure this doesn't happen by asking their IT departments to "whitelist"
+ sure this doesn't happen by asking their IT departments to "whitelist"
any email from <strong>@whatdotheyknow.com</strong>.
- If you <a href="/help/contact">ask us</a> we will resend any request,
+ If you <a href="<%= help_contact_path %>">ask us</a> we will resend any request,
and/or give technical details of delivery so an IT department can chase
up what happened to the message.
</p>
@@ -159,7 +159,7 @@
</li>
</ul>
- <p>If you're getting really nerdy about all this, read the <a href="http://www.ico.gov.uk/upload/documents/library/freedom_of_information/detailed_specialist_guides/timeforcompliance.pdf">detailed ICO guidance</a>.
+ <p>If you're getting really nerdy about all this, read the <a href="http://www.ico.gov.uk/upload/documents/library/freedom_of_information/detailed_specialist_guides/timeforcompliance.pdf">detailed ICO guidance</a>.
Meanwhile, remember that the law says authorities must respond
<strong>promptly</strong>. That's really what matters.</p>
@@ -173,14 +173,14 @@
extension when applying a <strong>public interest test</strong>. Information
Commissioner guidance says that it should only be used in "exceptionally
complex" cases
- (<a href="http://www.ico.gov.uk/upload/documents/library/freedom_of_information/detailed_specialist_guides/foi_good_practice_guidance_4.pdf">FOI Good Practice Guidance No. 4</a>).
+ (<a href="http://www.ico.gov.uk/upload/documents/library/freedom_of_information/detailed_specialist_guides/foi_good_practice_guidance_4.pdf">FOI Good Practice Guidance No. 4</a>).
WhatDoTheyKnow doesn't specifically handle this case, which is why we use the
phrase "should normally have responded by" when the 20 working day time is
- exceeded.
+ exceeded.
</p>
<p>The same guidance says that, even in exceptionally complex cases, no
- Freedom of Information request should take more than <strong>40 working days</strong>
+ Freedom of Information request should take more than <strong>40 working days</strong>
to answer. WhatDoTheyKnow displays requests which are overdue by that much
with stronger wording to indicate they are definitely late.
</p>
@@ -191,7 +191,7 @@
of 40 working days even with the extension (the House of Lords <a
href="http://www.publicwhip.org.uk/division.php?date=2000-10-17&amp;number=1&amp;house=lords">voted
to remove</a> provision for such a time limit during the initial passage
- of the UK Act through Parliament).
+ of the UK Act through Parliament).
</p>
</dd>
@@ -199,7 +199,7 @@
<dd>Instead of email, you can respond to a request directly from your web
browser, including uploading a file. To do this, choose "respond to request" at
- the bottom of the request's page. <a href="/help/contact">Contact us</a> if it
+ the bottom of the request's page. <a href="<%= help_contact_path %>">Contact us</a> if it
is too big for even that (more than, say, 50Mb).
</dd>
@@ -207,17 +207,17 @@
<dd>We consider what officers or servants do in the course of their employment
to be public information. We will only remove content in exceptional
- circumstances, see our <a href="/help/privacy#takedown">take down policy</a>.
+ circumstances, see our <a href="<%= help_privacy_path(:anchor => 'takedown') %>">take down policy</a>.
</dd>
<dt id="mobiles">Do you publish email addresses or mobile phone numbers? <a href="#mobiles">#</a> </dt>
<dd><p>To prevent spam, we automatically remove most emails and some mobile numbers from
- responses to requests. Please <a href="/help/contact">contact us</a> if we've
- missed one.
+ responses to requests. Please <a href="<%= help_contact_path %>">contact us</a> if we've
+ missed one.
For technical reasons we don't always remove them from attachments, such as certain PDFs.</p>
<p>If you need to know what an address was that we've removed, please <a
- href="/help/contact">get in touch with us</a>. Occasionally, an email address
+ href="<%= help_contact_path %>">get in touch with us</a>. Occasionally, an email address
forms an important part of a response and we will post it up in an obscured
form in an annotation.
</dd>
@@ -225,10 +225,10 @@
<dt id="copyright"><a name="commercial"></a>What is your policy on copyright of documents?<a href="#copyright">#</a> </dt>
<dd>Our Freedom of Information law is "applicant blind", so anyone in the
- world can request the same document and get a copy of it.
+ world can request the same document and get a copy of it.
If you think our making a document available on the internet infringes your
- copyright, you may <a href="/help/contact">contact us</a> and ask us
+ copyright, you may <a href="<%= help_contact_path %>">contact us</a> and ask us
to take it down. However, to save tax payers' money by preventing duplicate
requests, and for good public relations, we'd advise you not to do that.
</dd>
@@ -238,8 +238,8 @@
</dl>
- <p><strong>If you haven't already</strong>, read <a href="/help/about">the introduction</a> --&gt;
- <br><strong>Otherwise</strong>, the <a href="/help/credits">credits</a> or the <a href="/help/api">programmers API</a> --&gt;
+ <p><strong>If you haven't already</strong>, read <a href="<%= help_about_path %>">the introduction</a> --&gt;
+ <br><strong>Otherwise</strong>, the <a href="<%= help_credits_path %>">credits</a> or the <a href="<%= help_api_path %>">programmers API</a> --&gt;
<div id="hash_link_padding"></div>
</div>
diff --git a/app/views/help/privacy.rhtml b/app/views/help/privacy.rhtml
index bec0c8c23..8e5293892 100644
--- a/app/views/help/privacy.rhtml
+++ b/app/views/help/privacy.rhtml
@@ -10,7 +10,7 @@
<dd><p>We will not disclose your email address to anyone unless we are obliged to by law,
or you ask us to. This includes the public authority that you are sending a
- request to. They only get to see an email address
+ request to. They only get to see an email address
@whatdotheyknow.com which is specific to that request. </p>
<p>If you send a message to another user on the site, then it will reveal your
email address to them. You will be told that this is going to happen.</p>
@@ -35,7 +35,7 @@
Your name is tangled up with your request, so has to be published as well.
It is only fair, as we're going to publish the name of the civil servant who
writes the response to your request. Using your real name also helps people
- get in touch with you to assist you with your research or to campaign with you.
+ get in touch with you to assist you with your research or to campaign with you.
</p>
<p>By law, you must use your real name for the request to be a valid Freedom of
Information request. See the next question for alternatives if you do not want
@@ -66,16 +66,16 @@ Information Commissioner later about the handling of your request.
<ul>
<li>Use a different form of your name. The guidance says
that "Mr Arthur Thomas Roberts" can make a valid request as "Arthur Roberts",
-"A. T. Roberts", or "Mr Roberts", but <strong>not</strong> as "Arthur" or "A.T.R.".
+"A. T. Roberts", or "Mr Roberts", but <strong>not</strong> as "Arthur" or "A.T.R.".
</li>
<li>Women may use their maiden name.</li>
<li>In most cases, you may use any name by which you are "widely known and/or
is regularly used".
<li>Use the name of an organisation, the name of a company, the trading name of
a company, or the trading name of a sole trader.
-<li>Ask someone else to make the request on your behalf.
+<li>Ask someone else to make the request on your behalf.
<li>You may, if you are really stuck, ask us to make the request on
-your behalf. Please <a href="/help/contact">contact us</a> with
+your behalf. Please <a href="<%= help_contact_path %>">contact us</a> with
a good reason why you cannot make the request yourself and cannot
ask a friend to. We don't have the resources to do this for everyone.
</ul>
@@ -88,19 +88,19 @@ ask a friend to. We don't have the resources to do this for everyone.
<dd>
<p>If a public authority asks you for your full, physical address, reply to them saying
-that section 8.1.b of the FOI Act asks for an "address for correspondence",
-and that the email address you are using is sufficient.
+that section 8.1.b of the FOI Act asks for an "address for correspondence",
+and that the email address you are using is sufficient.
</p>
<p>
The Ministry of Justice has <a href="http://www.justice.gov.uk/guidance/foi-procedural-what.htm">guidance
on this</a> &ndash;
<em>"As well as hard copy written correspondence, requests that are
-transmitted electronically (for example, in emails) are acceptable
+transmitted electronically (for example, in emails) are acceptable
... If a request is received by email and no postal address is given, the email
address should be treated as the return address."
</em>
</p>
-<p>As if that isn't enough, the Information Commissioner's
+<p>As if that isn't enough, the Information Commissioner's
<a href="http://www.ico.gov.uk/upload/documents/library/freedom_of_information/practical_application/foi_hints_for_practitioners_handing_foi_and_eir_requests_2008_final.pdf">Hints for Practitioners</a> say
<em>"Any correspondence could include a request for information. If it is written (this includes e-mail), legible, gives the name of the applicant, an address for reply (which could be electronic), and includes a description of the information required, then it will fall within the scope of the legislation."</em>
</p>
@@ -141,10 +141,10 @@ see the section on <a href="#real_name">pseudonyms</a>.</p>
<dt id="takedown">Can you take down personal information about me? <a href="#takedown">#</a> </dt>
-<dd>
+<dd>
<p>If you see any personal information about you on the site which you'd like
-us to remove or hide, then please <a href="/help/contact">let us know</a>.
+us to remove or hide, then please <a href="<%= help_contact_path %>">let us know</a>.
Specify exactly what information you believe to be problematic and why, and
where it appears on the site.</p>
@@ -165,8 +165,8 @@ which outweighs the public interest, and must demonstrate that efforts have
been made to conceal the name on the organisation's own website.</p>
<p>For all other requests we apply a public interest test to decide
-whether information should be removed.
-<a href="http://www.statutelaw.gov.uk/content.aspx?ActiveTextDocId=3190650"> Section 32</a>
+whether information should be removed.
+<a href="http://www.statutelaw.gov.uk/content.aspx?ActiveTextDocId=3190650"> Section 32</a>
of the Data Protection Act 1998 permits us to do this, as the material we
publish is journalistic. We cannot easily edit many types of attachments (such
as PDFs, or Microsoft Word or Excel files), so we will usually ask
@@ -177,7 +177,7 @@ that authorities resend these with the personal information removed.</p>
</dl>
-<p><strong>Learn more</strong> from the help for <a href="/help/officers">FOI officers</a> --&gt;
+<p><strong>Learn more</strong> from the help for <a href="<%= help_officers_path %>">FOI officers</a> --&gt;
<div id="hash_link_padding"></div>
</div>
diff --git a/app/views/help/requesting.rhtml b/app/views/help/requesting.rhtml
index af8f2e45d..e7cfdd199 100644
--- a/app/views/help/requesting.rhtml
+++ b/app/views/help/requesting.rhtml
@@ -20,7 +20,7 @@
<li>Don't worry excessively about getting the right authority. If you get it
wrong, they ought to advise you who to make the request to instead.
</li>
- <li>If you've got a thorny case, please <a href="/help/contact">contact us</a> for help.</li>
+ <li>If you've got a thorny case, please <a href="<%= help_contact_path %>">contact us</a> for help.</li>
</ul>
</dd>
@@ -30,7 +30,7 @@
<dt id="missing_body">You're missing the public authority that I want to request from! <a href="#missing_body">#</a> </dt>
<dd>
- <p>Please <a href="/help/contact">contact us</a> with the name of the public authority and,
+ <p>Please <a href="<%= help_contact_path %>">contact us</a> with the name of the public authority and,
if you can find it, their contact email address for Freedom of Information requests.
</p>
<p>If you'd like to help add a whole category of public authority to the site, we'd love
@@ -47,11 +47,11 @@
<ul>
<li> Those formally subject to the FOI Act</li>
- <li> Those formally subject to the Environmental Regulations (a less well
+ <li> Those formally subject to the Environmental Regulations (a less well
defined group)</li>
<li> Those which voluntarily comply with the FOI Act</li>
<li> Those which aren't subject to the Act but we think should be, on grounds
- such as them having significant public responsibilities.
+ such as them having significant public responsibilities.
</li>
</ul>
@@ -132,7 +132,7 @@
<p>Even if they are not prompt, in nearly all cases they must respond within
20 working days. If you had to clarify your request, or they are a school,
or one or two other cases, then they may have more time
- (<a href="/help/officers#days">full details</a>).
+ (<a href="<%= help_officers_path(:anchor => 'days') %>">full details</a>).
<p>WhatDoTheyKnow will email you if you don't get a timely response. You can
then send the public authority a message to remind them, and tell them if they
@@ -158,24 +158,24 @@
checking that they received the request. It was sent to them by email.
</li>
<li>If they have not received it, the problem is most likely due to
- "spam filters". Refer the authority to the measures in the answer
- '<a href="/help/officers#spam_problems">I can see a request on WhatDoTheyKnow, but we never got it by email!</a>'
- in the FOI officers section of this help.
+ "spam filters". Refer the authority to the measures in the answer
+ '<a href="<%= help_officers_path(:anchor => 'spam_problems') %>">I can see a request on WhatDoTheyKnow, but we never got it by email!</a>'
+ in the FOI officers section of this help.
</li>
<li>If you're still having no luck, then you can ask for an internal review,
and then complain to the Information Commissioner about the authority.
- Read our page '<a href="/help/unhappy">Unhappy about the response you got?</a>'.
+ Read our page '<a href="<%= help_general_path(:action => 'unhappy') %>">Unhappy about the response you got?</a>'.
</ul>
</dd>
<dt id="not_satifised">What if I'm not satisfied with the response? <a href="#not_satifised">#</a> </dt>
<dd>If you didn't get the information you asked for, or you didn't get it in time,
- then read our page '<a href="/help/unhappy">Unhappy about the response you got?</a>'.
+ then read our page '<a href="<%= help_general_path(:action => 'unhappy') %>">Unhappy about the response you got?</a>'.
</dd>
<dt id="reuse">It says I can't re-use the information I got!<a href="#reuse">#</a> </dt>
<dd>
- <p>Authorities often add legal boilerplate about the
+ <p>Authorities often add legal boilerplate about the
"<a href="http://www.opsi.gov.uk/si/si2005/20051515">Re-Use of Public Sector
Information Regulations 2005</a>", which at first glance implies you may not
be able do anything with the information.
@@ -184,7 +184,7 @@
<p>You can, of course, write articles about the information or summarise it, or
quote parts of it. We also think you should feel free to republish the
information in full, just as we do, even though in theory you might not be
- allowed to do so. See <a href="/help/officers#copyright">our policy on copyright</a>.</p>
+ allowed to do so. See <a href="<%= help_officers_path(:anchor => 'copyright') %>">our policy on copyright</a>.</p>
</dd>
@@ -199,7 +199,7 @@
the process is very similar. There are differences around time
limits for compliance.
See the <a href="http://www.itspublicknowledge.info/nmsruntime/saveasdialog.asp?lID=1858&amp;sID=321">Scottish
- Information Commissioner's guidance</a> for details.</p>
+ Information Commissioner's guidance</a> for details.</p>
</dd>
<dt id="data_protection">Can I request information about myself? <a href="#data_protection">#</a> </dt>
@@ -216,7 +216,7 @@
website) explains how to do this.</p>
<p>If you see that somebody has included personal information, perhaps
- unwittingly, in a request, please <a href="/help/contact">contact us</a>
+ unwittingly, in a request, please <a href="<%= help_contact_path %>">contact us</a>
immediately so we can remove it.</p>
</dd>
@@ -228,7 +228,7 @@
to read. </p>
<p>You should contact the public authority directly if you would like to
make a request in private. If you're interested in buying a system which helps
- you manage FOI requests in secret, then <a href="/help/contact">contact us</a>.
+ you manage FOI requests in secret, then <a href="<%= help_contact_path %>">contact us</a>.
</p>
</dd>
@@ -237,7 +237,7 @@
<dd>
<p>Some public authorities, such as <a href="http://www.whatdotheyknow.com/body/south_east_water">South East Water</a>,
don't come under the Freedom of Information Act, but do come under another law called
- the Environmental Information Regulations (EIR).
+ the Environmental Information Regulations (EIR).
</p>
<p>It's a very similar law, so you make a request
@@ -250,7 +250,7 @@
<p>You can, of course, request environmental information from other
authorities. Just make a Freedom of Information (FOI) request as normal. The
authority has a duty to work out if the Environmental Information Regulations
- (EIR) is the more appropriate legislation to reply under.
+ (EIR) is the more appropriate legislation to reply under.
</p>
</dd>
@@ -275,7 +275,7 @@
<dt id="moderation">How do you moderate request annotations? <a href="#moderation">#</a> </dt>
- <dd>
+ <dd>
<p>Annotations on WhatDoTheyKnow are to help
people get the information they want, or to give them pointers to places they
can go to help them act on it. We reserve the right to remove anything else.
@@ -286,7 +286,7 @@
</dl>
- <p><strong>Next</strong>, read about <a href="/help/privacy">your privacy</a> --&gt;
+ <p><strong>Next</strong>, read about <a href="<%= help_privacy_path %>">your privacy</a> --&gt;
<div id="hash_link_padding"></div>
</div>
diff --git a/app/views/help/unhappy.rhtml b/app/views/help/unhappy.rhtml
index 4f3c67b9e..2b00341c2 100644
--- a/app/views/help/unhappy.rhtml
+++ b/app/views/help/unhappy.rhtml
@@ -2,7 +2,7 @@
<% if !@info_request.nil? %>
-<h1>Unhappy about the response you got
+<h1>Unhappy about the response you got
to your request '<%=request_link(@info_request) %>'?
</h1>
<% else %>
@@ -58,10 +58,10 @@ authority, then <a href="http://www.itspublicknowledge.info/YourRights/HowToApp
to the Scottish Information Commissioner</a>.
</p>
-<p>To make it easier to send the relevant information to the
+<p>To make it easier to send the relevant information to the
Information Commissioner, either
<% if !@info_request.nil? %>
- include a link to your request
+ include a link to your request
<strong><%=h main_url(request_url(@info_request)) %></strong>
<% else %>
include a link to your request on <%= site_name %>
@@ -86,8 +86,8 @@ get the information by <strong>other means...</strong></p>
<ul>
<li>Make a <strong>new FOI request</strong> for summary information, or for
-documentation relating indirectly to matters in your refused request.
-<a href="/help/contact">Ask us for ideas</a> if you're stuck.</li>
+documentation relating indirectly to matters in your refused request.
+<a href="<%= help_contact_path %>">Ask us for ideas</a> if you're stuck.</li>
<li>If any <strong>other public authorities</strong> or publicly owned companies are involved,
then make FOI requests to them.</li>
<li>Write to <strong>your MP</strong> or other politician using <a
@@ -95,13 +95,13 @@ href="http://www.writetothem.com">WriteToThem</a> and ask for their help
finding the answer. MPs can write directly to ministers or departments, and
can ask written questions in the House of Commons. Councillors in local authorities
can talk directly to council officers.</li>
-<li>Ask <strong>other researchers</strong> who are interested in a similar
+<li>Ask <strong>other researchers</strong> who are interested in a similar
issue to yours for ideas. You can sometimes find them by browsing this site;
contact any registered user from their page. There may be an Internet
forum or group that they hang out in. If it is a local matter, use <a
-href="http://www.groupsnearyou.com">GroupsNearYou</a> to find such a
+href="http://www.groupsnearyou.com">GroupsNearYou</a> to find such a
forum.</li>
-<li><strong>Start a pledge</strong> on <a href="http://www.pledgebank.com">PledgeBank</a> to get
+<li><strong>Start a pledge</strong> on <a href="http://www.pledgebank.com">PledgeBank</a> to get
others to act together with you. For example, you could arrange a meeting with
staff from the authority. Or you could form a small local campaigns group.
</ul>
diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml
index 76bdbd2dd..6ac7064a7 100644
--- a/app/views/layouts/default.rhtml
+++ b/app/views/layouts/default.rhtml
@@ -12,7 +12,7 @@
<link rel="shortcut icon" href="/favicon.ico">
<%= render :partial => 'general/stylesheet_includes' %>
- <% if session[:using_admin] %>
+ <% if is_admin? %>
<%= stylesheet_link_tag "/adminbootstraptheme/stylesheets/admin", :title => "Main", :rel => "stylesheet" %>
<% end %>
@@ -63,15 +63,15 @@
</script>
<% end %>
-<% if session[:using_admin] %>
+<% if is_admin? %>
<%= render :partial => 'admin_general/admin_navbar' %>
<% end %>
<% if !@popup_banner.blank? %>
<div id="everypage" class="jshide">
- <p style="float:right"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;"><%= _('Close') %></a></p>
+ <p class="popup-close"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;"><%= _('Close') %></a></p>
<%= @popup_banner %>
- <p style="text-align: right"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;"><%= _('Close') %></a></p>
+ <p class="popup-close"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;"><%= _('Close') %></a></p>
</div>
<% end %>
@@ -100,7 +100,7 @@
<% end %>
<div id="navigation_search">
- <form id="navigation_search_form" method="post" action="/search">
+ <form id="navigation_search_form" method="post" action="<%= search_redirect_path %>">
<p>
<%= text_field_tag 'query', params[:query], { :size => 40, :id => "navigation_search_query" } %>
<input id="navigation_search_button" type="submit" value="search">
@@ -140,11 +140,11 @@
</div>
<%
unless Configuration::ga_code.empty? || (@user && @user.super?) %>
- <script>
+ <script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
- <script>
+ <script type="text/javascript">
var pageTracker = _gat._getTracker("<%= Configuration::ga_code %>");
pageTracker._trackPageview();
</script>
diff --git a/app/views/request/_correspondence.rhtml b/app/views/request/_correspondence.rhtml
index bcfc93657..99c6c7d26 100644
--- a/app/views/request/_correspondence.rhtml
+++ b/app/views/request/_correspondence.rhtml
@@ -1,5 +1,5 @@
<div class="ff-print-fix"></div>
-<%
+<%
if !info_request_event.nil? && info_request_event.event_type == 'response'
incoming_message = info_request_event.incoming_message
end
@@ -21,9 +21,9 @@ if not incoming_message.nil?
<p class="event_actions">
<% if !@user.nil? && @user.admin_page_links? %>
- <%= link_to "Admin", admin_url("request/show_raw_email/" + incoming_message.raw_email_id.to_s) %> |
+ <%= link_to "Admin", admin_url("request/show_raw_email/" + incoming_message.raw_email_id.to_s) %> |
<% end %>
- <%= link_to _("Link to this"), incoming_message_url(incoming_message), :class => "link_to_this" %>
+ <%= link_to _("Link to this"), incoming_message_url(incoming_message), :class => "link_to_this" %>
</p>
</div>
<%
@@ -39,28 +39,28 @@ elsif [ 'sent', 'followup_sent' ].include?(info_request_event.event_type)
<%= render :partial => 'bubble', :locals => { :body => outgoing_message.get_body_for_html_display(), :attachments => nil } %>
- <p class="event_actions">
+ <p class="event_actions">
<% if outgoing_message.status == 'ready' && !@info_request.is_external? %>
<strong>Warning:</strong> This message has <strong>not yet been sent</strong> for an unknown reason.
- <% end %>
+ <% end %>
<!-- Can use this to get name of who followup was too, if say you
play with proper from display, but not sure needed
<% if outgoing_message.message_type == 'followup' && !outgoing_message.incoming_message_followup.nil? && !outgoing_message.incoming_message_followup.safe_mail_from.nil? %>
- Follow up sent to: <%=h outgoing_message.incoming_message_followup.safe_mail_from %>
- <% end %>
+ Follow up sent to: <%=h outgoing_message.incoming_message_followup.safe_mail_from %>
+ <% end %>
-->
- <%= link_to _("Link to this"), outgoing_message_url(outgoing_message), :class => "link_to_this" %>
+ <%= link_to _("Link to this"), outgoing_message_url(outgoing_message), :class => "link_to_this" %>
</p>
</div>
<% elsif [ 'resent', 'followup_resent' ].include?(info_request_event.event_type) %>
- <div class="outgoing correspondence" id="outgoing-<%=outgoing_message.id.to_s%>">
+ <div class="outgoing correspondence" id="outgoing-<%=info_request_event.outgoing_message.id.to_s%>">
<h2>
<%= simple_date(info_request_event.created_at) %>
</h2>
- <p class="event_plain">
- Sent
+ <p class="event_plain">
+ Sent
<% if info_request_event.outgoing_message.message_type == 'initial_request' %>
request
<% elsif info_request_event.outgoing_message.message_type == 'followup' %>
@@ -72,7 +72,7 @@ elsif [ 'sent', 'followup_sent' ].include?(info_request_event.event_type)
to <%= public_body_link(@info_request.public_body) %> again<% if not info_request_event.same_email_as_previous_send? %>, using a new contact address<% end %>.
</p>
</div>
-<% elsif info_request_event.event_type == 'comment'
+<% elsif info_request_event.event_type == 'comment'
comment = info_request_event.comment
%>
<%= render :partial => 'comment/single_comment', :locals => { :comment => comment } %>
diff --git a/app/views/request/select_authority.rhtml b/app/views/request/select_authority.rhtml
index 521136f8e..1166c3ff9 100644
--- a/app/views/request/select_authority.rhtml
+++ b/app/views/request/select_authority.rhtml
@@ -31,7 +31,7 @@
<div id="authority_selection">
<% form_tag({:controller => "request", :action => "select_authority"}, {:id => "search_form", :method => "get"}) do %>
- <p>
+ <div>
<p>
<%= _('First, type in the <strong>name of the UK public authority</strong> you\'d
like information from. <strong>By law, they have to respond</strong>
@@ -40,7 +40,7 @@
<%= text_field_tag 'query', params[:query], { :size => 30 } %>
<%= hidden_field_tag 'bodies', 1 %>
<%= submit_tag _('Search') %>
- </p>
+ </div>
<% end %>
<div id="typeahead_response">
<% if !@xapian_requests.nil? %>
diff --git a/app/views/request/show.rhtml b/app/views/request/show.rhtml
index cf1f971d9..7aff1aeab 100644
--- a/app/views/request/show.rhtml
+++ b/app/views/request/show.rhtml
@@ -22,8 +22,6 @@
</div>
<% end %>
-<%= render :partial => 'sidebar' %>
-
<div id="left_column">
<h1><%=h(@info_request.title)%></h1>
@@ -148,3 +146,4 @@
<%= render :partial => 'after_actions' %>
</div>
+<%= render :partial => 'sidebar' %>
diff --git a/app/views/user/_show_user_info.rhtml b/app/views/user/_show_user_info.rhtml
index 5dfecee1e..3c229e9ce 100644
--- a/app/views/user/_show_user_info.rhtml
+++ b/app/views/user/_show_user_info.rhtml
@@ -1,7 +1,7 @@
<% if !@display_user.get_about_me_for_html_display.empty? || @is_you %>
<div class="user_about_me">
- <img class="comment_quote" src="/images/quote.png" alt="">
+ <img class="comment_quote" src="/images/quote-marks.png" alt="">
<%= @display_user.get_about_me_for_html_display %>
<% if @is_you %>
(<%= link_to _("edit text about you"), set_profile_about_me_url() %>)
diff --git a/app/views/user/sign.rhtml b/app/views/user/sign.rhtml
index 4704ea95a..6a1979155 100644
--- a/app/views/user/sign.rhtml
+++ b/app/views/user/sign.rhtml
@@ -1,16 +1,16 @@
+
<% if !@post_redirect.nil? && @post_redirect.reason_params[:user_name] %>
<% @title = _("Sign in") %>
-
<div id="sign_alone">
<p id="sign_in_reason">
<% if @post_redirect.reason_params[:web].empty? %>
<%= _('Please sign in as ')%><%= link_to h(@post_redirect.reason_params[:user_name]), @post_redirect.reason_params[:user_url] %>.
<% else %>
- <%= @post_redirect.reason_params[:web] %>,
+ <%= @post_redirect.reason_params[:web] %>,
<%= _('please sign in as ')%><%= link_to h(@post_redirect.reason_params[:user_name]), @post_redirect.reason_params[:user_url] %>.
<% end %>
- </p>
+ </p>
<% if @post_redirect.post_params["controller"] == "admin_general" %>
<p id="superuser_message">Don't have a superuser account yet? <%= link_to "Sign in as the emergency user", @post_redirect.uri + "?emergency=1" %></p>
<% end %>
@@ -22,7 +22,16 @@
<% else %>
<% @title = _('Sign in or make a new account') %>
- <div id="sign_together">
+ <div id="sign_together">
+ <% if !@post_redirect.nil? %>
+ <p id="sign_in_reason">
+ <% if @post_redirect.reason_params[:web].empty? %>
+ <%= _('Please sign in or make a new account.') %>
+ <% else %>
+ <%= _('{{reason}}, please sign in or make a new account.', :reason => @post_redirect.reason_params[:web]) %>
+ <% end %>
+ </p>
+ <% end %>
<div id="left_half">
<h1><%= _('Sign in') %></h1>
<%= render :partial => 'signin', :locals => { :sign_in_as_existing_user => false } %>