aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin_request_controller.rb2
-rw-r--r--app/controllers/api_controller.rb72
-rw-r--r--app/controllers/application_controller.rb9
-rw-r--r--app/models/foi_attachment.rb68
-rw-r--r--app/models/incoming_message.rb475
-rw-r--r--app/models/info_request.rb6
-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.rhtml10
-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.rhtml6
17 files changed, 272 insertions, 540 deletions
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index 1de63be59..c7c8d4972 100644
--- a/app/controllers/admin_request_controller.rb
+++ b/app/controllers/admin_request_controller.rb
@@ -277,7 +277,7 @@ class AdminRequestController < AdminController
if params[:incoming_message_id]
incoming_message = IncomingMessage.find(params[:incoming_message_id])
- email = incoming_message.from_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
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 f9649c868..320d0cc50 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)
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 123319125..a02d2456a 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -70,41 +70,27 @@ class IncomingMessage < ActiveRecord::Base
@mail
end
- def from_address
- self.mail.from_addrs[0].address
- end
-
def empty_from_field?
self.mail.from_addrs.nil? || self.mail.from_addrs.size == 0
end
def from_email
- self.mail.from_addrs[0].spec
+ MailHandler.get_from_address(self.mail)
end
def addresses
- ((self.mail.to || []) +
- (self.mail.cc || []) +
- (self.mail.envelope_to || [])).uniq
+ MailHandler.get_all_addresses(self.mail)
end
def message_id
self.mail.message_id
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?
-
# 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 empty_from_field?
- return false
- end
email = self.from_email
- if !MySociety::Validate.is_valid_email(email)
+ if email.nil? || !MySociety::Validate.is_valid_email(email)
return false
end
@@ -114,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
@@ -138,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 = MailHandler.get_from_name(self.mail)
+ if self.from_email
self.mail_from_domain = PublicBody.extract_domain_from_email(self.from_email)
- rescue NoMethodError
+ else
self.mail_from_domain = ""
end
self.valid_to_reply_to = self._calculate_valid_to_reply_to
@@ -190,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 monkeypatches in lib/mail_handler/tmail_extensions and
- # lib/mail_handler/mail_extensions 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 = MailHandler.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 = MailHandler.mail_from_raw_email(part.body, decode=false)
- 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 = MailHandler.mail_from_raw_email(msg.to_mime.to_s, decode=false)
- elsif part.content_type == 'application/ms-tnef'
- # A set of attachments in a TNEF file
- part.rfc822_attachment = MailHandler.mail_from_tnef(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
@@ -458,95 +395,6 @@ class IncomingMessage < ActiveRecord::Base
return text
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 = MailHandler.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
@@ -609,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
@@ -617,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
@@ -662,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
@@ -715,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'
@@ -744,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 => MailHandler.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
@@ -802,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
@@ -894,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)
@@ -1056,65 +813,11 @@ 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 empty_from_field?
- return false
- end
- email = self.from_email
- 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
- 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'
+ 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 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 194f8e105..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
@@ -434,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
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 facddce41..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>
@@ -62,7 +62,7 @@
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 8c4ae588b..6ac7064a7 100644
--- a/app/views/layouts/default.rhtml
+++ b/app/views/layouts/default.rhtml
@@ -69,9 +69,9 @@
<% 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">