aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin_censor_rule_controller.rb4
-rw-r--r--app/controllers/admin_controller.rb31
-rw-r--r--app/controllers/admin_general_controller.rb2
-rw-r--r--app/controllers/admin_public_body_controller.rb8
-rw-r--r--app/controllers/admin_request_controller.rb18
-rw-r--r--app/controllers/application_controller.rb14
-rw-r--r--app/controllers/general_controller.rb8
-rw-r--r--app/controllers/public_body_controller.rb33
-rw-r--r--app/controllers/request_controller.rb4
-rw-r--r--app/controllers/services_controller.rb6
-rw-r--r--app/controllers/track_controller.rb2
-rw-r--r--app/controllers/user_controller.rb5
-rw-r--r--app/helpers/application_helper.rb8
-rw-r--r--app/models/exim_log.rb129
-rw-r--r--app/models/incoming_message.rb32
-rw-r--r--app/models/info_request.rb23
-rw-r--r--app/models/mail_server_log.rb201
-rw-r--r--app/models/mail_server_log_done.rb (renamed from app/models/exim_log_done.rb)11
-rw-r--r--app/models/outgoing_message.rb2
-rw-r--r--app/models/public_body.rb49
-rw-r--r--app/models/track_thing.rb7
-rw-r--r--app/models/user.rb13
-rw-r--r--app/views/admin_general/debug.rhtml2
-rw-r--r--app/views/admin_public_body/_form.rhtml3
-rw-r--r--app/views/admin_public_body/import_csv.rhtml2
-rw-r--r--app/views/admin_public_body/show.rhtml4
-rw-r--r--app/views/admin_request/show.rhtml10
-rw-r--r--app/views/general/_frontpage_bodies_list.rhtml17
-rw-r--r--app/views/general/_frontpage_new_request.rhtml7
-rw-r--r--app/views/general/_frontpage_requests_list.rhtml35
-rw-r--r--app/views/general/_frontpage_search_box.rhtml12
-rw-r--r--app/views/general/blog.rhtml47
-rw-r--r--app/views/general/frontpage.rhtml76
-rw-r--r--app/views/layouts/default.rhtml18
-rw-r--r--app/views/public_body/show.rhtml3
-rw-r--r--app/views/request/_request_filter_form.rhtml30
-rw-r--r--app/views/request/_request_listing_via_event.rhtml10
37 files changed, 494 insertions, 392 deletions
diff --git a/app/controllers/admin_censor_rule_controller.rb b/app/controllers/admin_censor_rule_controller.rb
index dca312b8b..5381921bf 100644
--- a/app/controllers/admin_censor_rule_controller.rb
+++ b/app/controllers/admin_censor_rule_controller.rb
@@ -15,7 +15,7 @@ class AdminCensorRuleController < AdminController
end
def create
- params[:censor_rule][:last_edit_editor] = admin_http_auth_user()
+ params[:censor_rule][:last_edit_editor] = admin_current_user()
@censor_rule = CensorRule.new(params[:censor_rule])
if @censor_rule.save
if !@censor_rule.info_request.nil?
@@ -42,7 +42,7 @@ class AdminCensorRuleController < AdminController
end
def update
- params[:censor_rule][:last_edit_editor] = admin_http_auth_user()
+ params[:censor_rule][:last_edit_editor] = admin_current_user()
@censor_rule = CensorRule.find(params[:id])
if @censor_rule.update_attributes(params[:censor_rule])
if !@censor_rule.info_request.nil?
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index dd966c4af..d7933b212 100644
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -45,12 +45,36 @@ class AdminController < ApplicationController
end
end
+ # For administration interface, return display name of authenticated user
+ def admin_current_user
+ if Configuration::skip_admin_auth
+ admin_http_auth_user
+ else
+ session[:admin_name]
+ end
+ end
+
+ # If we're skipping Alaveteli admin authentication, assume that the environment
+ # will give us an authenticated user name
+ def admin_http_auth_user
+ # This needs special magic in mongrel: http://www.ruby-forum.com/topic/83067
+ # Hence the second clause which reads X-Forwarded-User header if available.
+ # See the rewrite rules in conf/httpd.conf which set X-Forwarded-User
+ if request.env["REMOTE_USER"]
+ return request.env["REMOTE_USER"]
+ elsif request.env["HTTP_X_FORWARDED_USER"]
+ return request.env["HTTP_X_FORWARDED_USER"]
+ else
+ return "*unknown*";
+ end
+ end
+
def authenticate
if Configuration::skip_admin_auth
session[:using_admin] = 1
return
else
- if session[:using_admin].nil?
+ if session[:using_admin].nil? || session[:admin_name].nil?
if params[:emergency].nil?
if authenticated?(
:web => _("To log into the administrative interface"),
@@ -59,11 +83,12 @@ class AdminController < ApplicationController
:user_name => "a superuser")
if !@user.nil? && @user.admin_level == "super"
session[:using_admin] = 1
- request.env['REMOTE_USER'] = @user.url_name
+ session[:admin_name] = @user.url_name
else
session[:using_admin] = nil
session[:user_id] = nil
+ session[:admin_name] = nil
self.authenticate
end
end
@@ -71,7 +96,7 @@ class AdminController < ApplicationController
authenticate_or_request_with_http_basic do |user_name, password|
if user_name == Configuration::admin_username && password == Configuration::admin_password
session[:using_admin] = 1
- request.env['REMOTE_USER'] = user_name
+ session[:admin_name] = user_name
else
request_http_basic_authentication
end
diff --git a/app/controllers/admin_general_controller.rb b/app/controllers/admin_general_controller.rb
index 5176eb8db..9f4c398c1 100644
--- a/app/controllers/admin_general_controller.rb
+++ b/app/controllers/admin_general_controller.rb
@@ -120,7 +120,7 @@ class AdminGeneralController < AdminController
end
def debug
- @http_auth_user = admin_http_auth_user
+ @admin_current_user = admin_current_user
@current_commit = `git log -1 --format="%H"`
@current_branch = `git branch | perl -ne 'print $1 if /^\\* (.*)/'`
@current_version = `git describe --always --tags`
diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb
index e64925bde..ac12e97b2 100644
--- a/app/controllers/admin_public_body_controller.rb
+++ b/app/controllers/admin_public_body_controller.rb
@@ -88,7 +88,7 @@ class AdminPublicBodyController < AdminController
def create
PublicBody.with_locale(I18n.default_locale) do
- params[:public_body][:last_edit_editor] = admin_http_auth_user()
+ params[:public_body][:last_edit_editor] = admin_current_user()
@public_body = PublicBody.new(params[:public_body])
if @public_body.save
flash[:notice] = 'PublicBody was successfully created.'
@@ -107,7 +107,7 @@ class AdminPublicBodyController < AdminController
def update
PublicBody.with_locale(I18n.default_locale) do
- params[:public_body][:last_edit_editor] = admin_http_auth_user()
+ params[:public_body][:last_edit_editor] = admin_current_user()
@public_body = PublicBody.find(params[:id])
if @public_body.update_attributes(params[:public_body])
flash[:notice] = 'PublicBody was successfully updated.'
@@ -157,7 +157,7 @@ class AdminPublicBodyController < AdminController
params[:tag],
params[:tag_behaviour],
true,
- admin_http_auth_user(),
+ admin_current_user(),
I18n.available_locales)
if errors.size == 0
@@ -171,7 +171,7 @@ class AdminPublicBodyController < AdminController
params[:tag],
params[:tag_behaviour],
false,
- admin_http_auth_user(),
+ admin_current_user(),
I18n.available_locales)
if errors.size != 0
raise "dry run mismatched real run"
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index c97ef7f1e..3e574b10f 100644
--- a/app/controllers/admin_request_controller.rb
+++ b/app/controllers/admin_request_controller.rb
@@ -85,7 +85,7 @@ class AdminRequestController < AdminController
if @info_request.valid?
@info_request.save!
@info_request.log_event("edit",
- { :editor => admin_http_auth_user(),
+ { :editor => admin_current_user(),
:old_title => old_title, :title => @info_request.title,
:old_prominence => old_prominence, :prominence => @info_request.prominence,
:old_described_state => old_described_state, :described_state => @info_request.described_state,
@@ -128,7 +128,7 @@ class AdminRequestController < AdminController
@outgoing_message.fully_destroy
@outgoing_message.info_request.log_event("destroy_outgoing",
- { :editor => admin_http_auth_user(), :deleted_outgoing_message_id => outgoing_message_id })
+ { :editor => admin_current_user(), :deleted_outgoing_message_id => outgoing_message_id })
flash[:notice] = 'Outgoing message successfully destroyed.'
redirect_to request_admin_url(@info_request)
@@ -141,7 +141,7 @@ class AdminRequestController < AdminController
if @outgoing_message.update_attributes(params[:outgoing_message])
@outgoing_message.info_request.log_event("edit_outgoing",
- { :outgoing_message_id => @outgoing_message.id, :editor => admin_http_auth_user(),
+ { :outgoing_message_id => @outgoing_message.id, :editor => admin_current_user(),
:old_body => old_body, :body => @outgoing_message.body })
flash[:notice] = 'Outgoing message successfully updated.'
redirect_to request_admin_url(@outgoing_message.info_request)
@@ -163,7 +163,7 @@ class AdminRequestController < AdminController
if @comment.update_attributes(params[:comment])
@comment.info_request.log_event("edit_comment",
- { :comment_id => @comment.id, :editor => admin_http_auth_user(),
+ { :comment_id => @comment.id, :editor => admin_current_user(),
:old_body => old_body, :body => @comment.body,
:old_visible => old_visible, :visible => @comment.visible,
})
@@ -182,7 +182,7 @@ class AdminRequestController < AdminController
@incoming_message.fully_destroy
@incoming_message.info_request.log_event("destroy_incoming",
- { :editor => admin_http_auth_user(), :deleted_incoming_message_id => incoming_message_id })
+ { :editor => admin_current_user(), :deleted_incoming_message_id => incoming_message_id })
# expire cached files
expire_for_request(@info_request)
flash[:notice] = 'Incoming message successfully destroyed.'
@@ -213,7 +213,7 @@ class AdminRequestController < AdminController
incoming_message_id = incoming_message.id
incoming_message.info_request.log_event("redeliver_incoming", {
- :editor => admin_http_auth_user(),
+ :editor => admin_current_user(),
:destination_request => destination_request.id,
:deleted_incoming_message_id => incoming_message_id
})
@@ -239,7 +239,7 @@ class AdminRequestController < AdminController
info_request.user = destination_user
info_request.save!
info_request.log_event("move_request", {
- :editor => admin_http_auth_user(),
+ :editor => admin_current_user(),
:old_user_url_name => old_user.url_name,
:user_url_name => destination_user.url_name
})
@@ -257,7 +257,7 @@ class AdminRequestController < AdminController
info_request.public_body = destination_public_body
info_request.save!
info_request.log_event("move_request", {
- :editor => admin_http_auth_user(),
+ :editor => admin_current_user(),
:old_public_body_url_name => old_public_body.url_name,
:public_body_url_name => destination_public_body.url_name
})
@@ -367,7 +367,7 @@ class AdminRequestController < AdminController
info_request.prominence = "requester_only"
info_request.log_event("hide", {
- :editor => admin_http_auth_user(),
+ :editor => admin_current_user(),
:reason => params[:reason],
:subject => subject,
:explanation => explanation
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index f29015c63..3f3c169ae 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -340,20 +340,6 @@ class ApplicationController < ActionController::Base
end
- # For administration interface, return display name of authenticated user
- def admin_http_auth_user
- # This needs special magic in mongrel: http://www.ruby-forum.com/topic/83067
- # Hence the second clause which reads X-Forwarded-User header if available.
- # See the rewrite rules in conf/httpd.conf which set X-Forwarded-User
- if request.env["REMOTE_USER"]
- return request.env["REMOTE_USER"]
- elsif request.env["HTTP_X_FORWARDED_USER"]
- return request.env["HTTP_X_FORWARDED_USER"]
- else
- return "*unknown*";
- end
- end
-
# Convert URL name for sort by order, to Xapian query
def order_to_sort_by(sortby)
if sortby.nil?
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 150b433ec..0cde238cd 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -29,7 +29,7 @@ class GeneralController < ApplicationController
PublicBody.with_locale(@locale) do
if body_short_names.empty?
# This is too slow
- @popular_bodies = PublicBody.find(:all,
+ @popular_bodies = PublicBody.visible.find(:all,
:order => "info_requests_count desc",
:limit => 32,
:conditions => conditions,
@@ -58,6 +58,8 @@ class GeneralController < ApplicationController
xapian_object = perform_search([InfoRequestEvent], query, sortby, 'request_title_collapse', max_count-@request_events.count)
more_events = xapian_object.results.map { |r| r[:model] }
@request_events += more_events
+ # Overall we still want the list sorted with the newest first
+ @request_events.sort!{|e1,e2| e2.created_at <=> e1.created_at}
else
@request_events_all_successful = true
end
@@ -71,7 +73,9 @@ class GeneralController < ApplicationController
def blog
medium_cache
@feed_autodetect = []
- @feed_url = "#{Configuration::blog_feed}?lang=#{self.locale_from_params()}"
+ @feed_url = Configuration::blog_feed
+ separator = @feed_url.include?('?') ? '&' : '?'
+ @feed_url = "#{@feed_url}#{separator}lang=#{self.locale_from_params()}"
@blog_items = []
if not @feed_url.empty?
content = quietly_try_to_open(@feed_url)
diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb
index b34e89b8d..8a4a65820 100644
--- a/app/controllers/public_body_controller.rb
+++ b/app/controllers/public_body_controller.rb
@@ -146,38 +146,7 @@ class PublicBodyController < ApplicationController
end
def list_all_csv
- public_bodies = PublicBody.find(:all, :order => 'url_name',
- :include => [:translations, :tags])
- report = FasterCSV.generate() do |csv|
- csv << [
- 'Name',
- 'Short name',
- # deliberately not including 'Request email'
- 'URL name',
- 'Tags',
- 'Home page',
- 'Publication scheme',
- 'Created at',
- 'Updated at',
- 'Version',
- ]
- public_bodies.each do |public_body|
- csv << [
- public_body.name,
- public_body.short_name,
- # DO NOT include request_email (we don't want to make it
- # easy to spam all authorities with requests)
- public_body.url_name,
- public_body.tag_string,
- public_body.calculated_home_page,
- public_body.publication_scheme,
- public_body.created_at,
- public_body.updated_at,
- public_body.version,
- ]
- end
- end
- send_data(report, :type=> 'text/csv; charset=utf-8; header=present',
+ send_data(PublicBody.export_csv, :type=> 'text/csv; charset=utf-8; header=present',
:filename => 'all-authorities.csv',
:disposition =>'attachment', :encoding => 'utf8')
end
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index 3296db6b7..c732a4b32 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -44,7 +44,7 @@ class RequestController < ApplicationController
end
def show
- if !Configuration::varnish_host.nil?
+ if !Configuration::varnish_host.blank?
# If varnish is set up to accept PURGEs, then cache for a
# long time
long_cache
@@ -876,7 +876,7 @@ class RequestController < ApplicationController
Zip::ZipFile.open(file_path, Zip::ZipFile::CREATE) { |zipfile|
convert_command = Configuration::html_to_pdf_command
done = false
- if File.exists?(convert_command)
+ if !convert_command.blank? && File.exists?(convert_command)
url = "http://#{Configuration::domain}#{request_url(info_request)}?print_stylesheet=1"
tempfile = Tempfile.new('foihtml2pdf')
output = AlaveteliExternalCommand.run(convert_command, url, tempfile.path)
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index ead5d73b7..38bf51772 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -9,13 +9,13 @@ class ServicesController < ApplicationController
iso_country_code = Configuration::iso_country_code.downcase
if country_from_ip.downcase != iso_country_code
found_country = WorldFOIWebsites.by_code(country_from_ip)
- found_country_name = !found_country.nil? && found_country[:country_name]
old_fgt_locale = FastGettext.locale
begin
FastGettext.locale = FastGettext.best_locale_in(request.env['HTTP_ACCEPT_LANGUAGE'])
- if found_country_name
- text = _("Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}", :country_name => found_country_name, :link_to_website => "<a href=\"#{found_country[:url]}\">#{found_country[:name]}</a>")
+ if found_country && found_country[:country_name] && found_country[:url] && found_country[:name]
+ text = _("Hello! You can make Freedom of Information requests within {{country_name}} at {{link_to_website}}",
+ :country_name => found_country[:country_name], :link_to_website => "<a href=\"#{found_country[:url]}\">#{found_country[:name]}</a>")
else
current_country = WorldFOIWebsites.by_code(iso_country_code)[:country_name]
text = _("Hello! We have an <a href=\"/help/alaveteli?country_name=#{CGI.escape(current_country)}\">important message</a> for visitors outside {{country_name}}", :country_name => current_country)
diff --git a/app/controllers/track_controller.rb b/app/controllers/track_controller.rb
index 8e76b4c9f..51e081c88 100644
--- a/app/controllers/track_controller.rb
+++ b/app/controllers/track_controller.rb
@@ -180,7 +180,7 @@ class TrackController < ApplicationController
new_medium = params[:track_medium]
if new_medium == 'delete'
track_thing.destroy
- flash[:notice] = _("You are no longer following {{track_description}}", :track_description => track_thing.params[:list_description])
+ flash[:notice] = _("You are no longer following {{track_description}}.", :track_description => track_thing.params[:list_description])
redirect_to params[:r]
# Reuse code like this if we let medium change again.
#elsif new_medium == 'email_daily'
diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb
index 810b3321e..4ee527bae 100644
--- a/app/controllers/user_controller.rb
+++ b/app/controllers/user_controller.rb
@@ -119,13 +119,13 @@ class UserController < ApplicationController
@track_things = TrackThing.find(:all, :conditions => ["tracking_user_id = ? and track_medium = ?", @display_user.id, 'email_daily'], :order => 'created_at desc')
for track_thing in @track_things
# XXX factor out of track_mailer.rb
- xapian_object = InfoRequest.full_search([InfoRequestEvent], track_thing.track_query, 'described_at', true, nil, 20, 1)
+ xapian_object = InfoRequest.full_search([InfoRequestEvent], track_thing.track_query, 'described_at', true, nil, 20, 1)
feed_results += xapian_object.results.map {|x| x[:model]}
end
end
@feed_results = Array(feed_results).sort {|x,y| y.created_at <=> x.created_at}.first(20)
-
+
respond_to do |format|
format.html { @has_json = true }
format.json { render :json => @display_user.json_for_api }
@@ -244,6 +244,7 @@ class UserController < ApplicationController
session[:user_circumstance] = nil
session[:remember_me] = false
session[:using_admin] = nil
+ session[:admin_name] = nil
end
def signout
self._do_signout
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 090359f1f..ab953cb25 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -43,7 +43,7 @@ module ApplicationHelper
end
content_tag(:div,
- content_tag(:ul, error_messages),
+ content_tag(:ul, error_messages.join),
html
)
else
@@ -108,7 +108,7 @@ module ApplicationHelper
end
def form_tag_id(object_name, method_name, locale=nil)
- if locale.nil?
+ if locale.nil?
return "#{sanitized_object_name(object_name.to_s)}_#{sanitized_method_name(method_name.to_s)}"
else
return "#{sanitized_object_name(object_name.to_s)}_#{sanitized_method_name(method_name.to_s)}__#{locale.to_s}"
@@ -131,9 +131,5 @@ module ApplicationHelper
return "#{exact_date} (#{ago_text})"
end
- def is_admin?
- return !session[:using_admin].nil? || (!@user.nil? && @user.admin_level == "super")
- end
-
end
diff --git a/app/models/exim_log.rb b/app/models/exim_log.rb
deleted file mode 100644
index abe198493..000000000
--- a/app/models/exim_log.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-# == Schema Information
-# Schema version: 114
-#
-# Table name: exim_logs
-#
-# id :integer not null, primary key
-# exim_log_done_id :integer
-# info_request_id :integer
-# order :integer not null
-# line :text not null
-# created_at :datetime not null
-# updated_at :datetime not null
-#
-
-# models/exim_log.rb:
-# We load log file lines for requests in here, for display in the admin interface.
-#
-# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-class EximLog < ActiveRecord::Base
- belongs_to :info_request
- belongs_to :exim_log_done
-
- # Load in exim log file from disk, or update if we already have it
- # Assumes files are named with date, rather than cyclically.
- # Doesn't do anything if file hasn't been modified since it was last loaded.
- def EximLog.load_file(file_name)
- file_name_db = file_name
- is_gz = false
- if file_name.include?(".gz")
- is_gz = true
- file_name_db = file_name.gsub(".gz", "")
- end
-
- modified = File::stat(file_name).mtime
- raise "EximLog.load_file: file not found " + file_name if modified.nil?
-
- ActiveRecord::Base.transaction do
- # see if we already have it
- done = EximLogDone.find_by_filename(file_name_db)
- if !done.nil?
- if modified.utc == done.last_stat.utc
- # already have that, nothing to do
- return
- end
- EximLog.delete_all "exim_log_done_id = " + done.id.to_s
- end
- if !done
- done = EximLogDone.new
- done.filename = file_name_db
- end
- done.last_stat = modified
-
- # scan the file
- if is_gz
- f = Zlib::GzipReader.open(file_name)
- else
- f = File.open(file_name, 'r')
- end
- order = 0
- for line in f
- order = order + 1
- email_domain = Configuration::incoming_email_domain
- emails = line.scan(/request-[^\s]+@#{email_domain}/).sort.uniq
- for email in emails
- info_request = InfoRequest.find_by_incoming_email(email)
- if !info_request.nil?
- exim_log = EximLog.new
- exim_log.info_request = info_request
- exim_log.exim_log_done = done
- exim_log.line = line
- exim_log.order = order
- exim_log.save!
- end
- end
- end
-
- # update done structure so we know when we last read this file
- done.save!
- end
- end
-
- # Check that the last day of requests has been sent in Exim and we got the
- # lines. Writes any errors to STDERR. This check is really mainly to
- # check the envelope from is the request address, as Ruby is quite
- # flaky with regard to that, and it is important for anti-spam reasons.
- # XXX does this really check that, as the exim log just wouldn't pick
- # up at all if the requests weren't sent that way as there would be
- # no request- email in it?
- def EximLog.check_recent_requests_have_been_sent
- # Get all requests sent for from 2 to 10 days ago. The 2 day gap is
- # because we load exim log lines via cron at best an hour after they
- # are made)
- irs = InfoRequest.find(:all, :conditions => [ "created_at < ? and created_at > ? and user_id is not null", Time.now() - 2.day, Time.now() - 10.days ] )
-
- # Go through each request and check it
- ok = true
- for ir in irs
- # Look for line showing request was sent
- found = false
- for exim_log in ir.exim_logs
- test_outgoing = " <= " + ir.incoming_email + " "
- if exim_log.line.include?(test_outgoing)
- # Check the from value is the same (it always will be, but may as well
- # be sure we are parsing the exim line right)
- envelope_from = " from <" + ir.incoming_email + "> "
- if !exim_log.line.include?(envelope_from)
- $stderr.puts("unexpected parsing of exim line: [#{exim_log.line.chomp}]")
- else
- found = true
- end
- end
- end
- if !found
- # It's very important the envelope from is set for avoiding spam filter reasons - this
- # effectively acts as a check for that.
- $stderr.puts("failed to find request sending Exim line for request id " + ir.id.to_s + " " + ir.url_title + " (check envelope from is being set to request address in Ruby, and load-exim-logs crontab is working)") # *** don't comment out this STDERR line, it is the point of the function!
- ok = false
- end
- end
-
- return ok
- end
-
-end
-
-
-
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index fcb4671c5..60828e179 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -1,3 +1,5 @@
+# coding: utf-8
+
# == Schema Information
# Schema version: 114
#
@@ -17,9 +19,6 @@
# last_parsed :datetime
# mail_from :text
# sent_at :datetime
-#
-
-# encoding: UTF-8
# models/incoming_message.rb:
# An (email) message from really anybody to be logged with a request. e.g. A
@@ -75,11 +74,10 @@ class IncomingMessage < ActiveRecord::Base
# Documentation at http://i.loveruby.net/en/projects/tmail/doc/
def mail(force = nil)
if (!force.nil? || @mail.nil?) && !self.raw_email.nil?
- # Hack round bug in TMail's MIME decoding. Example request which provokes it:
- # http://www.whatdotheyknow.com/request/reviews_of_unduly_lenient_senten#incoming-4830
+ # 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+"/ims,'; boundary="')
+ copy_of_raw_data = self.raw_email.data.gsub(/; boundary=\s+"/im,'; boundary="')
@mail = TMail::Mail.parse(copy_of_raw_data)
@mail.base64_decode
@@ -291,7 +289,7 @@ class IncomingMessage < ActiveRecord::Base
logger.warn "Unable to compress PDF; problem with your pdftk version?"
end
if !recompressed_text.nil? && !recompressed_text.empty?
- text[0..-1] = recompressed_text # [0..-1] makes it change the 'text' string in place
+ text.replace recompressed_text
end
end
end
@@ -345,16 +343,15 @@ class IncomingMessage < ActiveRecord::Base
name = Regexp.escape(self.info_request.user_name)
# To end of message sections
- # http://www.whatdotheyknow.com/request/university_investment_in_the_arm
- text.gsub!(/^#{name}[^\n]+\nSent by:[^\n]+\n.*/ims, "\n\n" + replacement)
+ text.gsub!(/^\s?#{name}[^\n]+\n([^\n]+\n)?\s?Sent by:[^\n]+\n.*/im, "\n\n" + replacement)
# Some other sort of forwarding quoting
- # http://www.whatdotheyknow.com/request/224/response/326
- text.gsub!(/^#{name}[^\n]+\n[0-9\/:\s]+\s+To\s+FOI requests at.*/ims, "\n\n" + replacement)
+ text.gsub!(/^\s?#{name}\s+To\s+FOI requests at.*/im, "\n\n" + replacement)
+
- # http://www.whatdotheyknow.com/request/how_do_the_pct_deal_with_retirin_33#incoming-930
# http://www.whatdotheyknow.com/request/229/response/809
- text.gsub!(/^From: [^\n]+\nSent: [^\n]+\nTo:\s+['"?]#{name}['"]?\nSubject:.*/ims, "\n\n" + replacement)
+ text.gsub!(/^\s?From: [^\n]+\n\s?Sent: [^\n]+\n\s?To:\s+['"]?#{name}['"]?\n\s?Subject:.*/im, "\n\n" + replacement)
+
return text
@@ -397,7 +394,7 @@ class IncomingMessage < ActiveRecord::Base
# http://www.whatdotheyknow.com/request/police_powers_to_inform_car_insu
# http://www.whatdotheyknow.com/request/secured_convictions_aided_by_cct
multiline_original_message = '(' + '''>>>.* \d\d/\d\d/\d\d\d\d\s+\d\d:\d\d(?::\d\d)?\s*>>>''' + ')'
- text.gsub!(/^(#{multiline_original_message}\n.*)$/ms, replacement)
+ text.gsub!(/^(#{multiline_original_message}\n.*)$/m, replacement)
# Single line sections
text.gsub!(/^(>.*\n)/, replacement)
@@ -568,7 +565,7 @@ class IncomingMessage < ActiveRecord::Base
text = self.get_main_body_text_internal
# Strip the uudecode parts from main text
# - this also effectively does a .dup as well, so text mods don't alter original
- text = text.split(/^begin.+^`\n^end\n/sm).join(" ")
+ text = text.split(/^begin.+^`\n^end\n/m).join(" ")
if text.size > 1000000 # 1 MB ish
raise "main body text more than 1 MB, need to implement clipping like for attachment text, or there is some other MIME decoding problem or similar"
@@ -580,7 +577,8 @@ class IncomingMessage < ActiveRecord::Base
# Remove existing quoted sections
folded_quoted_text = self.remove_lotus_quoting(text, 'FOLDED_QUOTED_SECTION')
- folded_quoted_text = IncomingMessage.remove_quoted_sections(text, "FOLDED_QUOTED_SECTION")
+ folded_quoted_text = IncomingMessage.remove_quoted_sections(folded_quoted_text, "FOLDED_QUOTED_SECTION")
+
self.cached_main_body_text_unfolded = text
self.cached_main_body_text_folded = folded_quoted_text
self.save!
@@ -706,7 +704,7 @@ class IncomingMessage < ActiveRecord::Base
# Returns attachments that are uuencoded in main body part
def _uudecode_and_save_attachments(text)
# Find any uudecoded things buried in it, yeuchly
- uus = text.scan(/^begin.+^`\n^end\n/sm)
+ uus = text.scan(/^begin.+^`\n^end\n/m)
attachments = []
for uu in uus
# Decode the string
diff --git a/app/models/info_request.rb b/app/models/info_request.rb
index 85168e6d4..89893a396 100644
--- a/app/models/info_request.rb
+++ b/app/models/info_request.rb
@@ -47,10 +47,12 @@ class InfoRequest < ActiveRecord::Base
has_many :track_things, :order => 'created_at desc'
has_many :comments, :order => 'created_at'
has_many :censor_rules, :order => 'created_at desc'
- has_many :exim_logs, :order => 'exim_log_done_id'
+ has_many :mail_server_logs, :order => 'mail_server_log_done_id'
has_tag_string
+ named_scope :visible, :conditions => {:prominence => "normal"}
+
# user described state (also update in info_request_event, admin_request/edit.rhtml)
validate :must_be_valid_state
@@ -582,12 +584,11 @@ public
# waiting_classification
# waiting_response_overdue
# waiting_response_very_overdue
- def calculate_status
- if @@custom_states_loaded
- return self.theme_calculate_status
- else
- self.base_calculate_status
+ def calculate_status(cached_value_ok=false)
+ if cached_value_ok && @cached_calculated_status
+ return @cached_calculated_status
end
+ @cached_calculated_status = @@custom_states_loaded ? self.theme_calculate_status : self.base_calculate_status
end
def base_calculate_status
@@ -869,8 +870,8 @@ public
end
end
- def display_status
- InfoRequest.get_status_description(self.calculate_status)
+ def display_status(cached_value_ok=false)
+ InfoRequest.get_status_description(self.calculate_status(cached_value_ok))
end
# Completely delete this request and all objects depending on it
@@ -884,8 +885,8 @@ public
info_request_event.track_things_sent_emails.each { |a| a.destroy }
info_request_event.destroy
end
- self.exim_logs.each do |exim_log|
- exim_log.destroy
+ self.mail_server_logs.each do |mail_server_log|
+ mail_server_log.destroy
end
self.outgoing_messages.each { |a| a.destroy }
self.incoming_messages.each { |a| a.destroy }
@@ -1138,7 +1139,7 @@ public
before_save :purge_in_cache
def purge_in_cache
- if !Configuration::varnish_host.nil? && !self.id.nil?
+ if !Configuration::varnish_host.blank? && !self.id.nil?
# we only do this for existing info_requests (new ones have a nil id)
path = url_for(:controller => 'request', :action => 'show', :url_title => self.url_title, :only_path => true, :locale => :none)
req = PurgeRequest.find_by_url(path)
diff --git a/app/models/mail_server_log.rb b/app/models/mail_server_log.rb
new file mode 100644
index 000000000..755584b90
--- /dev/null
+++ b/app/models/mail_server_log.rb
@@ -0,0 +1,201 @@
+# == Schema Information
+# Schema version: 20121010214348
+#
+# Table name: mail_server_logs
+#
+# id :integer not null, primary key
+# mail_server_log_done_id :integer
+# info_request_id :integer
+# order :integer not null
+# line :text not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+# We load log file lines for requests in here, for display in the admin interface.
+#
+# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
+# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+#
+# $Id: exim_log.rb,v 1.14 2009-09-17 21:10:05 francis Exp $
+
+class MailServerLog < ActiveRecord::Base
+ belongs_to :info_request
+ belongs_to :mail_server_log_done
+
+ # Load in exim or postfix log file from disk, or update if we already have it
+ # Assumes files are named with date, rather than cyclically.
+ # Doesn't do anything if file hasn't been modified since it was last loaded.
+ # Note: If you do use rotated log files (rather than files named by date), at some
+ # point old loaded log lines will get deleted in the database.
+ def MailServerLog.load_file(file_name)
+ is_gz = file_name.include?(".gz")
+ file_name_db = is_gz ? file_name.gsub(".gz", "") : file_name
+
+ modified = File.stat(file_name).mtime
+ raise "MailServerLog.load_file: file not found " + file_name if modified.nil?
+
+ ActiveRecord::Base.transaction do
+ # see if we already have it
+ done = MailServerLogDone.find_by_filename(file_name_db)
+ if done
+ if modified.utc == done.last_stat.utc
+ # already have that, nothing to do
+ return
+ else
+ MailServerLog.delete_all "mail_server_log_done_id = " + done.id.to_s
+ end
+ else
+ done = MailServerLogDone.new(:filename => file_name_db)
+ end
+ done.last_stat = modified
+ # update done structure so we know when we last read this file
+ done.save!
+
+ f = is_gz ? Zlib::GzipReader.open(file_name) : File.open(file_name, 'r')
+ case(Configuration::mta_log_type.to_sym)
+ when :exim
+ load_exim_log_data(f, done)
+ when :postfix
+ load_postfix_log_data(f, done)
+ else
+ raise "Unexpected MTA type: #{type}"
+ end
+ end
+ end
+
+ # Scan the file
+ def MailServerLog.load_exim_log_data(f, done)
+ order = 0
+ f.each do |line|
+ order = order + 1
+ emails = email_addresses_on_line(line)
+ for email in emails
+ info_request = InfoRequest.find_by_incoming_email(email)
+ if info_request
+ info_request.mail_server_logs.create!(:line => line, :order => order, :mail_server_log_done => done)
+ else
+ puts "Warning: Could not find request with email #{email}"
+ end
+ end
+ end
+ end
+
+ def MailServerLog.load_postfix_log_data(f, done)
+ order = 0
+ emails = scan_for_postfix_queue_ids(f)
+ # Go back to the beginning of the file
+ f.rewind
+ f.each do |line|
+ order = order + 1
+ queue_id = extract_postfix_queue_id_from_syslog_line(line)
+ if emails.has_key?(queue_id)
+ emails[queue_id].each do |email|
+ info_request = InfoRequest.find_by_incoming_email(email)
+ if info_request
+ info_request.mail_server_logs.create!(:line => line, :order => order, :mail_server_log_done => done)
+ else
+ puts "Warning: Could not find request with email #{email}"
+ end
+ end
+ end
+ end
+ end
+
+ def MailServerLog.scan_for_postfix_queue_ids(f)
+ result = {}
+ f.each do |line|
+ emails = email_addresses_on_line(line)
+ queue_id = extract_postfix_queue_id_from_syslog_line(line)
+ result[queue_id] = [] unless result.has_key?(queue_id)
+ result[queue_id] = (result[queue_id] + emails).uniq
+ end
+ result
+ end
+
+ # Retuns nil if there is no queue id
+ def MailServerLog.extract_postfix_queue_id_from_syslog_line(line)
+ # Assume the log file was written using syslog and parse accordingly
+ m = SyslogProtocol.parse("<13>" + line).content.match(/^\S+: (\S+):/)
+ m[1] if m
+ end
+
+ # We also check the email prefix so that we could, for instance, separately handle a staging and production
+ # instance running on the same server with different email prefixes.
+ def MailServerLog.email_addresses_on_line(line)
+ prefix = Regexp::quote(Configuration::incoming_email_prefix)
+ domain = Regexp::quote(Configuration::incoming_email_domain)
+ line.scan(/#{prefix}request-[^\s]+@#{domain}/).sort.uniq
+ end
+
+ def MailServerLog.request_sent?(ir)
+ case(Configuration::mta_log_type.to_sym)
+ when :exim
+ request_exim_sent?(ir)
+ when :postfix
+ request_postfix_sent?(ir)
+ else
+ raise "Unexpected MTA type: #{type}"
+ end
+ end
+
+ # Look at the log for a request and check that an email was delivered
+ def MailServerLog.request_exim_sent?(ir)
+ # Look for line showing request was sent
+ found = false
+ ir.mail_server_logs.each do |mail_server_log|
+ test_outgoing = " <= " + ir.incoming_email + " "
+ if mail_server_log.line.include?(test_outgoing)
+ # Check the from value is the same (it always will be, but may as well
+ # be sure we are parsing the exim line right)
+ envelope_from = " from <" + ir.incoming_email + "> "
+ if !mail_server_log.line.include?(envelope_from)
+ $stderr.puts("unexpected parsing of exim line: [#{mail_server_log.line.chomp}]")
+ else
+ found = true
+ end
+ end
+ end
+ found
+ end
+
+ def MailServerLog.request_postfix_sent?(ir)
+ # dsn=2.0.0 is the magic word that says that postfix delivered the email
+ # See http://tools.ietf.org/html/rfc3464
+ ir.mail_server_logs.any? { |l| l.line.include?("dsn=2.0.0") }
+ end
+
+ # Check that the last day of requests has been sent in Exim or Postfix and we got the
+ # lines. Writes any errors to STDERR. This check is really mainly to
+ # check the envelope from is the request address, as Ruby is quite
+ # flaky with regard to that, and it is important for anti-spam reasons.
+ # XXX does this really check that, as the log just wouldn't pick
+ # up at all if the requests weren't sent that way as there would be
+ # no request- email in it?
+ #
+ # NB: There can be several emails involved in a request. This just checks that
+ # at least one of them has been succesfully sent.
+ #
+ def MailServerLog.check_recent_requests_have_been_sent
+ # Get all requests sent for from 2 to 10 days ago. The 2 day gap is
+ # because we load mail server log lines via cron at best an hour after they
+ # are made)
+ irs = InfoRequest.find(:all, :conditions => [ "created_at < ? and created_at > ? and user_id is not null", Time.now() - 2.day, Time.now() - 10.days ] )
+
+ # Go through each request and check it
+ ok = true
+ irs.each do |ir|
+ unless request_sent?(ir)
+ # It's very important the envelope from is set for avoiding spam filter reasons - this
+ # effectively acts as a check for that.
+ $stderr.puts("failed to find request sending in MTA logs for request id " + ir.id.to_s + " " + ir.url_title + " (check envelope from is being set to request address in Ruby, and load-mail-server-logs crontab is working)") # *** don't comment out this STDERR line, it is the point of the function!
+ ok = false
+ end
+ end
+ ok
+ end
+
+end
+
+
+
diff --git a/app/models/exim_log_done.rb b/app/models/mail_server_log_done.rb
index 86574a4cd..3fb20f0b3 100644
--- a/app/models/exim_log_done.rb
+++ b/app/models/mail_server_log_done.rb
@@ -1,7 +1,7 @@
# == Schema Information
-# Schema version: 114
+# Schema version: 20121010214348
#
-# Table name: exim_log_dones
+# Table name: mail_server_log_dones
#
# id :integer not null, primary key
# filename :text not null
@@ -10,14 +10,13 @@
# updated_at :datetime not null
#
-# models/exim_log_done.rb:
-# Stores that a particular exim file has been loaded in, see exim_log.rb
+# Stores that a particular mail server log file has been loaded in, see mail_server_log.rb
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-class EximLogDone < ActiveRecord::Base
- has_many :exim_logs
+class MailServerLogDone < ActiveRecord::Base
+ has_many :mail_server_logs
end
diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb
index 0e547d493..2e98e1021 100644
--- a/app/models/outgoing_message.rb
+++ b/app/models/outgoing_message.rb
@@ -151,7 +151,7 @@ class OutgoingMessage < ActiveRecord::Base
raise "Message id #{self.id} has type '#{self.message_type}' which validate can't handle"
end
end
- if self.body =~ /#{get_signoff}\s*\Z/ms
+ if self.body =~ /#{get_signoff}\s*\Z/m
errors.add(:body, _("Please sign at the bottom with your name, or alter the \"%{signoff}\" signature" % { :signoff => get_signoff }))
end
if !MySociety::Validate.uses_mixed_capitals(self.body)
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 34bcd332c..57fe27767 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -17,7 +17,7 @@
# notes :text default(""), not null
# first_letter :string(255) not null
# publication_scheme :text default(""), not null
-# api_key :string(255)
+# api_key :string(255) not null
# info_requests_count :integer default(0), not null
#
@@ -42,6 +42,12 @@ class PublicBody < ActiveRecord::Base
has_tag_string
before_save :set_api_key, :set_default_publication_scheme
+ # Every public body except for the internal admin one is visible
+ named_scope :visible, lambda {
+ {
+ :conditions => "public_bodies.id <> #{PublicBody.internal_admin_body.id}"
+ }
+ }
translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme
@@ -407,7 +413,7 @@ class PublicBody < ActiveRecord::Base
next
end
- field_list = ['name', 'short_name', 'request_email', 'notes', 'publication_scheme', 'home_page', 'tag_string']
+ field_list = ['name', 'short_name', 'request_email', 'notes', 'publication_scheme', 'disclosure_log', 'home_page', 'tag_string']
if public_body = bodies_by_name[name] # Existing public body
available_locales.each do |locale|
@@ -494,6 +500,45 @@ class PublicBody < ActiveRecord::Base
return [errors, notes]
end
+ # Returns all public bodies (except for the internal admin authority) as csv
+ def self.export_csv
+ public_bodies = PublicBody.visible.find(:all, :order => 'url_name',
+ :include => [:translations, :tags])
+ FasterCSV.generate() do |csv|
+ csv << [
+ 'Name',
+ 'Short name',
+ # deliberately not including 'Request email'
+ 'URL name',
+ 'Tags',
+ 'Home page',
+ 'Publication scheme',
+ 'Disclosure log',
+ 'Notes',
+ 'Created at',
+ 'Updated at',
+ 'Version',
+ ]
+ public_bodies.each do |public_body|
+ csv << [
+ public_body.name,
+ public_body.short_name,
+ # DO NOT include request_email (we don't want to make it
+ # easy to spam all authorities with requests)
+ public_body.url_name,
+ public_body.tag_string,
+ public_body.calculated_home_page,
+ public_body.publication_scheme,
+ public_body.disclosure_log,
+ public_body.notes,
+ public_body.created_at,
+ public_body.updated_at,
+ public_body.version,
+ ]
+ end
+ end
+ end
+
# Does this user have the power of FOI officer for this body?
def is_foi_officer?(user)
user_domain = user.email_domain
diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb
index d1cef4d4d..2a61eb858 100644
--- a/app/models/track_thing.rb
+++ b/app/models/track_thing.rb
@@ -107,7 +107,12 @@ class TrackThing < ActiveRecord::Base
end
descriptions = []
if varieties.include? _("requests")
- descriptions << _("requests which are {{list_of_statuses}}", :list_of_statuses => Array(statuses).sort.join(_(' or ')))
+ if statuses.empty?
+ # HACK: Relies on the 'descriptions.sort' below to luckily put this first
+ descriptions << _("all requests")
+ else
+ descriptions << _("requests which are {{list_of_statuses}}", :list_of_statuses => Array(statuses).sort.join(_(' or ')))
+ end
varieties -= [_("requests")]
end
if descriptions.empty? and varieties.empty?
diff --git a/app/models/user.rb b/app/models/user.rb
index 59f6c971c..70386f7e4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -246,6 +246,11 @@ class User < ActiveRecord::Base
# Does the user magically gain powers as if they owned every request?
# e.g. Can classify it
def owns_every_request?
+ self.super?
+ end
+
+ # Does this user have extraordinary powers?
+ def super?
self.admin_level == 'super'
end
@@ -255,18 +260,18 @@ class User < ActiveRecord::Base
# Can the user see every request, even hidden ones?
def User.view_hidden_requests?(user)
- !user.nil? && user.admin_level == 'super'
+ !user.nil? && user.super?
end
# Should the user be kept logged into their own account
# if they follow a /c/ redirect link belonging to another user?
def User.stay_logged_in_on_redirect?(user)
- !user.nil? && user.admin_level == 'super'
+ !user.nil? && user.super?
end
# Does the user get "(admin)" links on each page on the main site?
def admin_page_links?
- self.admin_level == 'super'
+ self.super?
end
# Is it public that they are banned?
def public_banned?
@@ -281,7 +286,7 @@ class User < ActiveRecord::Base
return false if self.no_limit
# Has the user issued as many as MAX_REQUESTS_PER_USER_PER_DAY requests in the past 24 hours?
- return false if Configuration::max_requests_per_user_per_day.nil?
+ return false if Configuration::max_requests_per_user_per_day.blank?
recent_requests = InfoRequest.count(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id])
return (recent_requests >= Configuration::max_requests_per_user_per_day)
diff --git a/app/views/admin_general/debug.rhtml b/app/views/admin_general/debug.rhtml
index d7bf1c6da..99488ba0c 100644
--- a/app/views/admin_general/debug.rhtml
+++ b/app/views/admin_general/debug.rhtml
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<p>You are <%= h @http_auth_user %></p>
+<p>You are <%= h @admin_current_user %></p>
<h2>Version numbers</h2>
diff --git a/app/views/admin_public_body/_form.rhtml b/app/views/admin_public_body/_form.rhtml
index d854b53f5..0d6ae51e2 100644
--- a/app/views/admin_public_body/_form.rhtml
+++ b/app/views/admin_public_body/_form.rhtml
@@ -38,6 +38,9 @@
<p><label for="<%= form_tag_id(t.object_name, :publication_scheme, locale) %>">Publication scheme URL</label><br/>
<%= t.text_field :publication_scheme, :size => 60, :id => form_tag_id(t.object_name, :publication_scheme, locale) %></p>
+ <p><label for="<%= form_tag_id(t.object_name, :disclosure_log, locale) %>">Disclosure log URL</label><br/>
+ <%= t.text_field :disclosure_log, :size => 60, :id => form_tag_id(t.object_name, :disclosure_log, locale) %></p>
+
<p><label for="<%= form_tag_id(t.object_name, :notes, locale) %>">Public notes</label> <small>(HTML, for users to consider when making FOI requests to the authority)</small><br/>
<%= t.text_area :notes, :rows => 3, :cols => 60, :id => form_tag_id(t.object_name, :notes, locale) %></p>
</div>
diff --git a/app/views/admin_public_body/import_csv.rhtml b/app/views/admin_public_body/import_csv.rhtml
index 4a03d0665..62908ba52 100644
--- a/app/views/admin_public_body/import_csv.rhtml
+++ b/app/views/admin_public_body/import_csv.rhtml
@@ -51,7 +51,7 @@
</blockquote>
<p>Supported fields: name (i18n), short_name (i18n), request_email (i18n), notes (i18n),
- publication_scheme (i18n), home_page, tag_string (tags separated by spaces).</p>
+ publication_scheme (i18n), disclosure_log (i18n), home_page, tag_string (tags separated by spaces).</p>
<p><strong>Note:</strong> Choose <strong>dry run</strong> to test, without
actually altering the database. Choose <strong>upload</strong> to actually
diff --git a/app/views/admin_public_body/show.rhtml b/app/views/admin_public_body/show.rhtml
index fa17d4027..094007c02 100644
--- a/app/views/admin_public_body/show.rhtml
+++ b/app/views/admin_public_body/show.rhtml
@@ -9,9 +9,9 @@
for column in columns %>
<b><%= column.human_name %>:</b>
- <% if column.name == 'home_page' and !column.name.empty? %>
+ <% if ['home_page', 'publication_scheme', 'disclosure_log'].include? column.name %>
<%= link_to(h(@public_body.send(column.name)), @public_body.send(column.name)) %>
- <% elsif column.name == 'request_email' and !column.name.empty? %>
+ <% elsif column.name == 'request_email' %>
<%= link_to(h(@public_body.send(column.name)), "mailto:#{@public_body.send(column.name)}") %>
<% if !@public_body.is_requestable? %>
(not requestable due to: <%=h @public_body.not_requestable_reason %><% if @public_body.is_followupable? %>; but followupable<% end %>)
diff --git a/app/views/admin_request/show.rhtml b/app/views/admin_request/show.rhtml
index 9d939eb35..2541fd323 100644
--- a/app/views/admin_request/show.rhtml
+++ b/app/views/admin_request/show.rhtml
@@ -213,15 +213,15 @@
-<h2>Exim delivery logs</h2>
+<h2>Mail server delivery logs</h2>
<p><i>(Lines containing the request incoming email address, updated hourly.)</i></p>
-<% for exim_log_done_id, exim_logs in @info_request.exim_logs.group_by(&:exim_log_done_id) %>
- <!-- <h3><%=h exim_logs[0].exim_log_done.filename %></h3> -->
- <pre><% for exim_log in exim_logs %><%=h exim_log.line%><% end %></pre>
+<% for mail_server_log_done_id, mail_server_logs in @info_request.mail_server_logs.group_by(&:mail_server_log_done_id) %>
+ <!-- <h3><%=h mail_server_logs[0].mail_server_log_done.filename %></h3> -->
+ <pre><% for mail_server_log in mail_server_logs %><%=h mail_server_log.line%><% end %></pre>
<% end %>
-<% if @info_request.exim_logs.size == 0 %>
+<% if @info_request.mail_server_logs.size == 0 %>
<p>None (perhaps this is an old or a very new request)</p>
<% end %>
diff --git a/app/views/general/_frontpage_bodies_list.rhtml b/app/views/general/_frontpage_bodies_list.rhtml
new file mode 100644
index 000000000..503b38953
--- /dev/null
+++ b/app/views/general/_frontpage_bodies_list.rhtml
@@ -0,0 +1,17 @@
+<% if @popular_bodies.size > 0 %>
+ <div id="examples_0">
+ <h3><%= _("Who can I request information from?") %></h3>
+ <%= _("{{site_name}} covers requests to {{number_of_authorities}} authorities, including:",
+ :site_name => site_name, :number_of_authorities => PublicBody.visible.count) %>
+ <ul>
+ <% for popular_body in @popular_bodies %>
+ <li><%=public_body_link(popular_body)%>
+ <%= n_('%d request', '%d requests', popular_body.info_requests_count) % popular_body.info_requests_count %>
+ </li>
+ <% end%>
+ </ul>
+ <p><strong>
+ <%= link_to _('Browse all authorities...'), list_public_bodies_default %>
+ </strong></p>
+ </div>
+<% end %>
diff --git a/app/views/general/_frontpage_new_request.rhtml b/app/views/general/_frontpage_new_request.rhtml
new file mode 100644
index 000000000..fd4225069
--- /dev/null
+++ b/app/views/general/_frontpage_new_request.rhtml
@@ -0,0 +1,7 @@
+<h1>
+ <%= _("Make a new<br/>
+ <strong>Freedom <span>of</span><br/>
+ Information<br/>
+ request</strong>") %>
+</h1>
+<a class="link_button_green_large" href="/select_authority"><%= _("Start now &raquo;") %></a>
diff --git a/app/views/general/_frontpage_requests_list.rhtml b/app/views/general/_frontpage_requests_list.rhtml
new file mode 100644
index 000000000..3b0efb65e
--- /dev/null
+++ b/app/views/general/_frontpage_requests_list.rhtml
@@ -0,0 +1,35 @@
+<div id="examples_1">
+ <h3>
+ <% if @request_events_all_successful %>
+ <%= _("What information has been released?") %>
+ <% else %>
+ <%= _("What information has been requested?") %>
+ <% end %>
+ </h3>
+ <%= _("{{site_name}} users have made {{number_of_requests}} requests, including:",
+ :site_name => site_name, :number_of_requests => InfoRequest.visible.count) %>
+ <ul>
+ <% for event in @request_events %>
+ <li>
+ <% if @request_events_all_successful %>
+ <%= _("{{public_body_link}} answered a request about",
+ :public_body_link => public_body_link(event.info_request.public_body)) %>
+ <% else %>
+ <%= _("{{public_body_link}} was sent a request about",
+ :public_body_link => public_body_link(event.info_request.public_body)) %>
+ <% end %>
+
+ <%=link_to h(event.info_request.title), request_url(event.info_request)%>
+ <%= _('{{length_of_time}} ago', :length_of_time => time_ago_in_words(event.described_at)) %>
+ <p class="excerpt" onclick="document.location.href='<%=request_url(event.info_request)%>'"><%= excerpt(event.search_text_main(true), "", 200) %></p>
+ </li>
+ <% end %>
+ </ul>
+ <p><strong>
+ <% if @request_events_all_successful %>
+ <%=link_to _('More successful requests...'), request_list_successful_url %>
+ <% else %>
+ <%=link_to _('More requests...'), request_list_all_url %>
+ <% end %>
+ </strong></p>
+</div>
diff --git a/app/views/general/_frontpage_search_box.rhtml b/app/views/general/_frontpage_search_box.rhtml
new file mode 100644
index 000000000..6de4eae98
--- /dev/null
+++ b/app/views/general/_frontpage_search_box.rhtml
@@ -0,0 +1,12 @@
+<h2>
+ <%= _("Search over<br/>
+ <strong>{{number_of_requests}} requests</strong> <span>and</span><br/>
+ <strong>{{number_of_authorities}} authorities</strong>",
+ :number_of_requests => InfoRequest.visible.count, :number_of_authorities => PublicBody.visible.count) %>
+</h2>
+<form id="search_form" method="post" action="/search">
+ <div>
+ <input id="query" type="text" size="30" name="query">
+ <input type="submit" value="<%= _('Search') %>">
+ </div>
+</form>
diff --git a/app/views/general/blog.rhtml b/app/views/general/blog.rhtml
index a80f167d8..5258e9bbd 100644
--- a/app/views/general/blog.rhtml
+++ b/app/views/general/blog.rhtml
@@ -7,53 +7,34 @@
<img src="/images/twitter-16.png" alt="twitter icon" class="twitter-icon"> <a href="https://twitter.com/<%= @twitter_user %>"><%= _("Follow us on twitter") %></a><br/><br/>
<img src="/images/feed-16.png" alt="RSS icon" valign="middle"> <a href="<%= @feed_url %>"><%= _("Subscribe to blog") %></a>
</div>
+ <% if Configuration::twitter_widget_id %>
<div id="twitter">
- <script src="http://widgets.twimg.com/j/2/widget.js"></script>
- <script type="text/javascript">
- new TWTR.Widget({
- version: 2,
- type: 'profile',
- rpp: 15,
- interval: 6000,
- width: 'auto',
- height: 500,
- theme: {
- shell: {
- background: '#eaeaea',
- color: '#000000'
- },
- tweets: {
- background: '#ffffff',
- color: '#000000',
- links: '#0b004a'
- }
- },
- features: {
- scrollbar: false,
- loop: false,
- live: false,
- hashtags: true,
- timestamp: true,
- avatars: true,
- behavior: 'all'
- }
- }).render().setUser('<%=@twitter_user %>').start();
- </script>
+ <a class="twitter-timeline" data-dnt=true href="https://twitter.com/<%= Configuration::twitter_username %>" data-widget-id="<%= Configuration::twitter_widget_id %>">Tweets by @<%= Configuration::twitter_username %></a>
+ <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
+ <% end %>
</div>
<% end %>
<div id="left_column">
<h1><%=@title %></h1>
-
+
<div id="blog">
<% for item in @blog_items: %>
<div class="blog_post">
<h2 id="<%= Time.parse(item['pubDate'][0]).to_i %>"><a href="<%=item['link']%>"><%=h item['title'] %></a></h2>
<p class="subtitle"><%= _("Posted on {{date}} by {{author}}", :date=>simple_date(Time.parse(item['pubDate'][0])), :author=>item['creator']) %></p>
- <div><%= item['encoded'] %></div>
+ <div>
+ <% if item['encoded'] %>
+ <%= item['encoded'] %>
+ <% elsif item['description'] %>
+ <%= item['description'] %>
+ <% end %>
+ </div>
<p><em>
+ <% if item['comments'] %>
<a href="<%=item['comments'][0]%>"><%= _("{{number_of_comments}} comments", :number_of_comments=>item['comments'][1]) %></a>
+ <% end %>
</em>
</p>
</div>
diff --git a/app/views/general/frontpage.rhtml b/app/views/general/frontpage.rhtml
index e2d74a5e2..acc7f4095 100644
--- a/app/views/general/frontpage.rhtml
+++ b/app/views/general/frontpage.rhtml
@@ -1,28 +1,11 @@
<% view_cache :ttl => 5.minutes.to_i, :tag => I18n.locale do %>
<div id="frontpage_splash">
<div id="left_column">
- <h1>
- <%= _("Make a new<br/>
- <strong>Freedom <span>of</span><br/>
- Information<br/>
- request</strong>") %>
- </h1>
- <a class="link_button_green_large" href="/select_authority"><%= _("Start now &raquo;") %></a>
+ <%= render :partial => "frontpage_new_request" %>
</div>
<div id="right_column">
<div id="frontpage_search_box">
- <h2>
- <%= _("Search over<br/>
- <strong>{{number_of_requests}} requests</strong> <span>and</span><br/>
- <strong>{{number_of_authorities}} authorities</strong>",
- :number_of_requests => InfoRequest.count, :number_of_authorities => PublicBody.count) %>
- </h2>
- <% form_tag({:action => "search_redirect"}, {:id => "search_form"}) do %>
- <div>
- <%= text_field_tag 'query', params[:query], { :size => 30 } %>
- <%= submit_tag _('Search') %>
- </div>
- <% end %>
+ <%= render :partial => "frontpage_search_box" %>
</div>
<div id="frontpage_right_to_know">
<%= render :partial => 'frontpage_intro_sentence' %>
@@ -30,55 +13,8 @@
</div>
<div style="clear:both"></div>
</div>
-
-<div id="frontpage_examples">
- <% if @popular_bodies.size > 0 %>
- <div id="examples_0">
- <h3><%= _("Who can I request information from?") %></h3>
- <%= _("{{site_name}} covers requests to {{number_of_authorities}} authorities, including:",
- :site_name => site_name, :number_of_authorities => PublicBody.count) %>
- <ul>
- <% for popular_body in @popular_bodies %>
- <li><%=public_body_link(popular_body)%>
- <%= n_('%d request', '%d requests', popular_body.info_requests_count) % popular_body.info_requests_count %>
- </li>
- <% end%>
- </ul>
- <p><strong>
- <%= link_to _('Browse all authorities...'), list_public_bodies_default %>
- </strong></p>
- </div>
- <% end %>
-
- <div id="examples_1">
- <h3>
- <% if @request_events_all_successful %>
- <%= _("What information has been released?") %>
- <% else %>
- <%= _("What information has been requested?") %>
- <% end %>
- </h3>
- <%= _("{{site_name}} users have made {{number_of_requests}} requests, including:",
- :site_name => site_name, :number_of_requests => InfoRequest.count) %>
- <ul>
- <% for event in @request_events %>
- <li>
- <%= public_body_link(event.info_request.public_body) %> <%= _('answered a request about') %>
- <%=link_to h(event.info_request.title), request_url(event.info_request)%>
- <%= _('{{length_of_time}} ago', :length_of_time => time_ago_in_words(event.described_at)) %>
- <p class="excerpt" onclick="document.location.href='<%=request_url(event.info_request)%>'"><%= excerpt(event.search_text_main(true), "", 200) %></p>
- </li>
- <% end %>
- </ul>
- <p><strong>
- <% if @request_events_all_successful %>
- <%=link_to _('More successful requests...'), request_list_successful_url %>
- <% else %>
- <%=link_to _('More requests...'), request_list_all_url %>
- <% end %>
- </strong></p>
- </div>
-</div>
-
-
+ <div id="frontpage_examples">
+ <%= render :partial => "frontpage_bodies_list" %>
+ <%= render :partial => "frontpage_requests_list" %>
+ </div>
<% end %>
diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml
index 0dd493fd0..76bdbd2dd 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 is_admin? %>
+ <% if session[:using_admin] %>
<%= stylesheet_link_tag "/adminbootstraptheme/stylesheets/admin", :title => "Main", :rel => "stylesheet" %>
<% end %>
@@ -41,7 +41,7 @@
<%= render :partial => 'general/before_head_end' %>
</head>
- <body class="<%= 'admin' if is_admin? %> <%= 'front' if params[:action] == 'frontpage' %>">
+ <body class="<%= 'front' if params[:action] == 'frontpage' %>">
<% if Configuration::force_registration_on_new_request && !@user %>
<%= javascript_include_tag 'jquery.fancybox-1.3.4.pack' %>
<script type="text/javascript">
@@ -100,12 +100,12 @@
<% end %>
<div id="navigation_search">
- <% form_tag({:controller => "general", :action => "search_redirect"}, {:id => "navigation_search_form"}) do %>
- <p>
- <%= text_field_tag 'query', params[:query], { :size => 40, :id => "navigation_search_query" } %>
- <%= submit_tag 'search', :id => "navigation_search_button" %>
- </p>
- <% end %>
+ <form id="navigation_search_form" method="post" action="/search">
+ <p>
+ <%= text_field_tag 'query', params[:query], { :size => 40, :id => "navigation_search_query" } %>
+ <input id="navigation_search_button" type="submit" value="search">
+ </p>
+ </form>
</div>
<%= render :partial => 'general/orglink' %>
@@ -139,7 +139,7 @@
<input type="text">
</div>
<%
- unless Configuration::ga_code.empty? %>
+ unless Configuration::ga_code.empty? || (@user && @user.super?) %>
<script>
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"));
diff --git a/app/views/public_body/show.rhtml b/app/views/public_body/show.rhtml
index b56556d5d..e13f9d1c0 100644
--- a/app/views/public_body/show.rhtml
+++ b/app/views/public_body/show.rhtml
@@ -14,6 +14,9 @@
<% if !@public_body.publication_scheme.empty? %>
<%= link_to _('Publication scheme'), @public_body.publication_scheme %><br>
<% end %>
+ <% unless @public_body.disclosure_log.empty? %>
+ <%= link_to _('Disclosure log'), @public_body.disclosure_log %><br>
+ <% end %>
<% if @public_body.has_tag?("charity") %>
<% for tag_value in @public_body.get_tag_values("charity") %>
<% if tag_value.match(/^SC/) %>
diff --git a/app/views/request/_request_filter_form.rhtml b/app/views/request/_request_filter_form.rhtml
index fa760bf74..0c215a9b6 100644
--- a/app/views/request/_request_filter_form.rhtml
+++ b/app/views/request/_request_filter_form.rhtml
@@ -27,22 +27,24 @@
</div>
<div class="list-filter-item">
<h3 class="title"><%= _("Showing") %></h3>
- <% statuses = [["all", _("all requests")],
- ["successful", _("successful requests")],
- ["unsuccessful", _("unsuccessful requests")],
- ["awaiting", _("unresolved requests")]] %>
- <% for status, label in statuses %>
- <% if params[:view] != status %>
- <% if params[:controller] == "public_body" %>
- <%= link_to label, url_for(:controller => "public_body", :action => "show", :view => status, :url_name => @public_body.url_name) + "?" + request.query_string + '#results' %>
+ <div class="filter-request-types">
+ <% statuses = [["all", _("all requests")],
+ ["successful", _("successful requests")],
+ ["unsuccessful", _("unsuccessful requests")],
+ ["awaiting", _("unresolved requests")]] %>
+ <% for status, label in statuses %>
+ <% if params[:view] != status %>
+ <% if params[:controller] == "public_body" %>
+ <%= link_to label, url_for(:controller => "public_body", :action => "show", :view => status, :url_name => @public_body.url_name) + "?" + request.query_string + '#results' %>
+ <% else %>
+ <%= link_to label, url_for(:controller => "request", :action => "list", :view => status) + "?" + request.query_string + '#results' %>
+ <% end %>
<% else %>
- <%= link_to label, url_for(:controller => "request", :action => "list", :view => status) + "?" + request.query_string + '#results' %>
+ <%= label %>
<% end %>
- <% else %>
- <%= label %>
- <% end %>
- <%= "|" unless statuses.last[0] == status %>
- <% end %>
+ <%= "|" unless statuses.last[0] == status %>
+ <% end %>
+ </div>
</div>
<div class="list-filter-item">
diff --git a/app/views/request/_request_listing_via_event.rhtml b/app/views/request/_request_listing_via_event.rhtml
index e3abfe393..ee1cc079a 100644
--- a/app/views/request/_request_listing_via_event.rhtml
+++ b/app/views/request/_request_listing_via_event.rhtml
@@ -17,13 +17,13 @@ end %>
</span>
<div class="requester">
<% if event.event_type == 'sent' %>
- <%= _('Request sent to {{public_body_name}} by {{info_request_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>request_user_link_absolute(info_request),:date=>simple_date(event.created_at )) %>
+ <%= _('Request sent to {{public_body_name}} by {{info_request_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>request_user_link_absolute(info_request),:date=>simple_date(event.created_at )) %>
<% elsif event.event_type == 'followup_sent' %>
<%=event.display_status %>
- <%= _('sent to {{public_body_name}} by {{info_request_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>request_user_link_absolute(info_request),:date=>simple_date(event.created_at )) %>
+ <%= _('sent to {{public_body_name}} by {{info_request_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>request_user_link_absolute(info_request),:date=>simple_date(event.created_at )) %>
<% elsif event.event_type == 'response' %>
<%=event.display_status %>
- <%= _('by {{public_body_name}} to {{info_request_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>request_user_link_absolute(info_request),:date=>simple_date(event.created_at )) %>
+ <%= _('by {{public_body_name}} to {{info_request_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>request_user_link_absolute(info_request),:date=>simple_date(event.created_at )) %>
<% elsif event.event_type == 'comment' %>
<%= _('Request to {{public_body_name}} by {{info_request_user}}. Annotated by {{event_comment_user}} on {{date}}.',:public_body_name=>public_body_link_absolute(info_request.public_body),:info_request_user=>user_link_absolute(info_request.user),:event_comment_user=>user_link_absolute(event.comment.user),:date=>simple_date(event.created_at)) %>
<% else %>
@@ -35,12 +35,12 @@ end %>
</div>
<span class="bottomline icon_<%= info_request.calculate_status %>">
<strong>
- <%= info_request.display_status %>
+ <%= info_request.display_status(cached_value_ok=true) %>
</strong><br>
</span>
</div>
<div class="request_right">
- <span class="desc">
+ <span class="desc">
<%= highlight_and_excerpt(event.search_text_main(true), @highlight_words, 150) %>
</span>
</div>