aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/actionmailer_patches.rb15
-rw-r--r--lib/alaveteli_external_command.rb6
-rw-r--r--lib/i18n_fixes.rb2
-rw-r--r--lib/mail_handler/mail_handler.rb2
-rw-r--r--lib/quiet_opener.rb37
-rw-r--r--lib/tasks/import.rake12
-rw-r--r--lib/tasks/themes.rake138
-rw-r--r--lib/tasks/translation.rake7
-rw-r--r--lib/world_foi_websites.rb15
-rw-r--r--lib/xapian_queries.rb85
10 files changed, 224 insertions, 95 deletions
diff --git a/lib/actionmailer_patches.rb b/lib/actionmailer_patches.rb
deleted file mode 100644
index 600d3c8cc..000000000
--- a/lib/actionmailer_patches.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# Monkey patch for CVE-2013-4389
-# derived from http://seclists.org/oss-sec/2013/q4/118 to fix
-# a possible DoS vulnerability in the log subscriber component of
-# Action Mailer.
-
-require 'action_mailer'
-module ActionMailer
- class LogSubscriber < ActiveSupport::LogSubscriber
- def deliver(event)
- recipients = Array.wrap(event.payload[:to]).join(', ')
- info("\nSent mail to #{recipients} (#{event.duration.round(1)}ms)")
- debug(event.payload[:mail])
- end
- end
-end
diff --git a/lib/alaveteli_external_command.rb b/lib/alaveteli_external_command.rb
index fbdee8a62..086a461c8 100644
--- a/lib/alaveteli_external_command.rb
+++ b/lib/alaveteli_external_command.rb
@@ -44,7 +44,11 @@ module AlaveteliExternalCommand
end
xc.run(opts[:stdin_string] || "", opts[:env] || {})
- if xc.status != 0
+ if !xc.exited
+ # Crash or timeout
+ $stderr.puts("#{program_name} #{args.join(' ')}:exited abnormally")
+ return nil
+ elsif xc.status != 0
# Error
$stderr.puts("Error from #{program_name} #{args.join(' ')}:")
$stderr.print(xc.err)
diff --git a/lib/i18n_fixes.rb b/lib/i18n_fixes.rb
index 9f0849e75..64c370477 100644
--- a/lib/i18n_fixes.rb
+++ b/lib/i18n_fixes.rb
@@ -35,7 +35,7 @@ def gettext_interpolate(string, values)
pattern, key = $1, $1.to_sym
if !values.include?(key)
- raise I18n::MissingInterpolationArgument.new(pattern, string)
+ raise I18n::MissingInterpolationArgument.new(pattern, string, values)
else
v = values[key].to_s
if safe && !v.html_safe?
diff --git a/lib/mail_handler/mail_handler.rb b/lib/mail_handler/mail_handler.rb
index 918f91180..53033d440 100644
--- a/lib/mail_handler/mail_handler.rb
+++ b/lib/mail_handler/mail_handler.rb
@@ -59,7 +59,7 @@ module MailHandler
end
# e.g. http://www.whatdotheyknow.com/request/copy_of_current_swessex_scr_opt#incoming-9928
- if content_type == 'application/acrobat'
+ if content_type == 'application/acrobat' or content_type == 'document/pdf'
content_type = 'application/pdf'
end
diff --git a/lib/quiet_opener.rb b/lib/quiet_opener.rb
index ae6605c43..16ea27b8e 100644
--- a/lib/quiet_opener.rb
+++ b/lib/quiet_opener.rb
@@ -1,6 +1,8 @@
require 'open-uri'
require 'net-purge'
-require 'net/http/local'
+if RUBY_VERSION.to_f < 2.0
+ require 'net/http/local'
+end
def quietly_try_to_open(url)
begin
@@ -12,17 +14,36 @@ def quietly_try_to_open(url)
return result
end
+# On Ruby versions before 2.0, we need to use the net-http-local gem
+# to force the use of 127.0.0.1 as the local interface for the
+# connection. However, at the time of writing this gem doesn't work
+# on Ruby 2.0 and it's not necessary with that Ruby version - one can
+# supply a :local_host option to Net::HTTP:start. So, this helper
+# function is to abstract away that difference, and can be used as you
+# would Net::HTTP.start(host) when passed a block.
+def http_from_localhost(host)
+ if RUBY_VERSION.to_f >= 2.0
+ Net::HTTP.start(host, :local_host => '127.0.0.1') do |http|
+ yield http
+ end
+ else
+ Net::HTTP.bind '127.0.0.1' do
+ Net::HTTP.start(host) do |http|
+ yield http
+ end
+ end
+ end
+end
+
def quietly_try_to_purge(host, url)
begin
result = ""
result_body = ""
- Net::HTTP.bind '127.0.0.1' do
- Net::HTTP.start(host) {|http|
- request = Net::HTTP::Purge.new(url)
- response = http.request(request)
- result = response.code
- result_body = response.body
- }
+ http_from_localhost(host) do |http|
+ request = Net::HTTP::Purge.new(url)
+ response = http.request(request)
+ result = response.code
+ result_body = response.body
end
rescue OpenURI::HTTPError, SocketError, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET, Errno::ENETUNREACH
Rails.logger.warn("PURGE: Unable to reach host #{host}")
diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake
index 0e8397fde..c8183c745 100644
--- a/lib/tasks/import.rake
+++ b/lib/tasks/import.rake
@@ -54,12 +54,12 @@ namespace :import do
STDERR.puts "Now importing the public bodies..."
# Now it's (probably) safe to try to import:
- errors, notes = PublicBody.import_csv(tmp_csv.path,
- tag='',
- tag_behaviour='replace',
- dryrun,
- editor="#{ENV['USER']} (Unix user)",
- I18n.available_locales) do |row_number, fields|
+ errors, notes = PublicBody.import_csv_from_file(tmp_csv.path,
+ tag='',
+ tag_behaviour='replace',
+ dryrun,
+ editor="#{ENV['USER']} (Unix user)",
+ I18n.available_locales) do |row_number, fields|
percent_complete = (100 * row_number.to_f / number_of_rows).to_i
STDERR.print "#{row_number} out of #{number_of_rows} "
STDERR.puts "(#{percent_complete}% complete)"
diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake
index 65b142a63..4a864d141 100644
--- a/lib/tasks/themes.rake
+++ b/lib/tasks/themes.rake
@@ -1,104 +1,123 @@
+require Rails.root.join('commonlib', 'rblib', 'git')
+
namespace :themes do
- def plugin_dir
+ # Alias the module so we don't need the MySociety prefix here
+ Git = MySociety::Git
+
+ def all_themes_dir
File.join(Rails.root,"lib","themes")
end
def theme_dir(theme_name)
- File.join(plugin_dir, theme_name)
+ File.join(all_themes_dir, theme_name)
end
- def old_theme_dir(theme_name)
+ def old_all_themes_dir(theme_name)
File.join(Rails.root, "vendor", "plugins", theme_name)
end
def possible_theme_dirs(theme_name)
- [theme_dir(theme_name), old_theme_dir(theme_name)]
- end
-
- def checkout(commitish)
- puts "Checking out #{commitish}" if verbose
- system "git checkout #{commitish}"
+ [theme_dir(theme_name), old_all_themes_dir(theme_name)]
end
- def checkout_tag(version)
- checkout usage_tag(version)
- end
-
- def checkout_remote_branch(branch)
- checkout "origin/#{branch}"
+ def installed?(theme_name)
+ possible_theme_dirs(theme_name).any? { |dir| File.directory? dir }
end
def usage_tag(version)
"use-with-alaveteli-#{version}"
end
- def install_theme_using_git(name, uri, verbose=false, options={})
- install_path = theme_dir(name)
- Dir.chdir(plugin_dir) do
- clone_command = "git clone #{uri} #{name}"
- if system(clone_command)
- Dir.chdir install_path do
- # First try to checkout a specific branch of the theme
- tag_checked_out = checkout_remote_branch(AlaveteliConfiguration::theme_branch) if AlaveteliConfiguration::theme_branch
- if !tag_checked_out
- # try to checkout a tag exactly matching ALAVETELI VERSION
- tag_checked_out = checkout_tag(ALAVETELI_VERSION)
- end
- if ! tag_checked_out
- # if we're on a hotfix release (four sequence elements or more),
- # look for a usage tag matching the minor release (three sequence elements)
- # and check that out if found
- if hotfix_version = /^(\d+\.\d+\.\d+)(\.\d+)+/.match(ALAVETELI_VERSION)
- base_version = hotfix_version[1]
- tag_checked_out = checkout_tag(base_version)
- end
- end
- if ! tag_checked_out
- puts "No specific tag for this version: using HEAD" if verbose
- end
- puts "removing: .git .gitignore" if verbose
- rm_rf %w(.git .gitignore)
- end
- else
- rm_rf install_path
- raise "#{clone_command} failed! Stopping."
- end
- end
- end
-
def uninstall(theme_name, verbose=false)
possible_theme_dirs(theme_name).each do |dir|
if File.directory?(dir)
run_hook(theme_name, 'uninstall', verbose)
- puts "Removing '#{dir}'" if verbose
- rm_r dir
- else
- puts "Plugin doesn't exist: #{dir}"
end
end
end
def run_hook(theme_name, hook_name, verbose=false)
- hook_file = File.join(theme_dir(theme_name), "#{hook_name}.rb")
+ directory = theme_dir(theme_name)
+ hook_file = File.join(directory, "#{hook_name}.rb")
if File.exist? hook_file
- puts "Running #{hook_name} hook for #{theme_name}" if verbose
+ puts "Running #{hook_name} hook in #{directory}" if verbose
load hook_file
end
end
- def installed?(theme_name)
- possible_theme_dirs(theme_name).any? { |dir| File.directory? dir }
+ def move_old_theme(old_theme_directory)
+ puts "There was an old-style theme at #{old_theme_directory}" if verbose
+ moved_directory = "#{old_theme_directory}-moved"
+ begin
+ File.rename old_theme_directory, moved_directory
+ rescue Errno::ENOTEMPTY, Errno::EEXIST
+ raise "Tried to move #{old_theme_directory} out of the way, " \
+ "but #{moved_directory} already existed"
+ end
+ end
+
+ def committishes_to_try
+ result = []
+ theme_branch = AlaveteliConfiguration::theme_branch
+ result.push "origin/#{theme_branch}" if theme_branch
+ result.push usage_tag(ALAVETELI_VERSION)
+ hotfix_match = /^(\d+\.\d+\.\d+)(\.\d+)+/.match(ALAVETELI_VERSION)
+ result.push usage_tag(hotfix_match[1]) if hotfix_match
+ result
+ end
+
+ def checkout_best_option(theme_name)
+ theme_directory = theme_dir theme_name
+ all_failed = true
+ committishes_to_try.each do |committish|
+ if Git.committish_exists? theme_directory, committish
+ puts "Checking out #{committish}" if verbose
+ Git.checkout theme_directory, committish
+ all_failed = false
+ break
+ else
+ puts "Failed to find #{committish}; skipping..." if verbose
+ end
+ end
+ puts "Falling to using HEAD instead" if all_failed and verbose
end
def install_theme(theme_url, verbose, deprecated=false)
- FileUtils.mkdir_p plugin_dir
+ FileUtils.mkdir_p all_themes_dir
deprecation_string = deprecated ? " using deprecated THEME_URL" : ""
theme_name = theme_url_to_theme_name theme_url
puts "Installing theme #{theme_name}#{deprecation_string} from #{theme_url}"
+ # Make sure any uninstall hooks have been run:
uninstall(theme_name, verbose) if installed?(theme_name)
- install_theme_using_git(theme_name, theme_url, verbose)
+ theme_directory = theme_dir theme_name
+ # Is there an old-style theme directory there? If so, move it
+ # out of the way so that there's no risk that work is lost:
+ if File.directory? theme_directory
+ unless Git.non_bare_repository? theme_directory
+ move_old_theme theme_directory
+ end
+ end
+ # If there isn't a directory there already, clone it into place:
+ unless File.directory? theme_directory
+ unless system "git", "clone", theme_url, theme_directory
+ raise "Cloning from #{theme_url} to #{theme_directory} failed"
+ end
+ end
+ # Set the URL for origin in case it has changed, and fetch from there:
+ Git.remote_set_url theme_directory, 'origin', theme_url
+ Git.fetch theme_directory, 'origin'
+ # Check that checking-out a new commit will be safe:
+ unless Git.status_clean theme_directory
+ raise "There were uncommitted changes in #{theme_directory}"
+ end
+ unless Git.is_HEAD_pushed? theme_directory
+ raise "The current work in #{theme_directory} is unpushed"
+ end
+ # Now try to checkout various commits in order of preference:
+ checkout_best_option theme_name
+ # Finally run the install hooks:
run_hook(theme_name, 'install', verbose)
run_hook(theme_name, 'post_install', verbose)
end
@@ -112,4 +131,5 @@ namespace :themes do
install_theme(AlaveteliConfiguration::theme_url, verbose, deprecated=true)
end
end
+
end
diff --git a/lib/tasks/translation.rake b/lib/tasks/translation.rake
index 6458d9268..b1f9d0b71 100644
--- a/lib/tasks/translation.rake
+++ b/lib/tasks/translation.rake
@@ -66,9 +66,10 @@ namespace :translation do
'Hello!')
write_email(user_contact_email, 'Contact email (user to user)', output_file)
- admin_contact_email = ContactMailer.from_admin_message(info_request.user,
- 'A test message',
- 'Hello!')
+ admin_contact_email = ContactMailer.from_admin_message(info_request.user.name,
+ info_request.user.email,
+ 'A test message',
+ 'Hello!')
write_email(admin_contact_email, 'Contact email (admin to user)', output_file)
# request mailer
diff --git a/lib/world_foi_websites.rb b/lib/world_foi_websites.rb
index c3f3655df..50976c897 100644
--- a/lib/world_foi_websites.rb
+++ b/lib/world_foi_websites.rb
@@ -53,7 +53,20 @@ class WorldFOIWebsites
{:name => "Informace pro Vsechny",
:country_name => "Česká republika",
:country_iso_code => "CZ",
- :url => "http://www.infoprovsechny.cz"}
+ :url => "http://www.infoprovsechny.cz"},
+ {:name => "¿Qué Sabés?",
+ :country_name => "Uruguay",
+ :country_iso_code => "UY",
+ :url => "http://www.quesabes.org/"},
+ {:name => "Nu Vă Supărați",
+ :country_name => "România",
+ :country_iso_code => "RO",
+ :url => "http://nuvasuparati.info/"},
+ {:name => "Marsoum41",
+ :country_name => "تونس",
+ :country_iso_code => "TN",
+ :url => "http://www.marsoum41.org"}
+
]
return world_foi_websites
end
diff --git a/lib/xapian_queries.rb b/lib/xapian_queries.rb
new file mode 100644
index 000000000..b3599740a
--- /dev/null
+++ b/lib/xapian_queries.rb
@@ -0,0 +1,85 @@
+module XapianQueries
+
+ # These methods take some filter criteria expressed in a hash and convert them
+ # into a xapian query referencing the terms and values stored by InfoRequestEvent.
+ # Note that the params are request params and may contain irrelevant keys
+
+ def get_request_variety_from_params(params)
+ query = ""
+ sortby = "newest"
+ varieties = []
+ if params[:request_variety] && !(query =~ /variety:/)
+ if params[:request_variety].include? "sent"
+ varieties -= ['variety:sent', 'variety:followup_sent', 'variety:response', 'variety:comment']
+ varieties << ['variety:sent', 'variety:followup_sent']
+ end
+ if params[:request_variety].include? "response"
+ varieties << ['variety:response']
+ end
+ if params[:request_variety].include? "comment"
+ varieties << ['variety:comment']
+ end
+ end
+ if !varieties.empty?
+ query = " (#{varieties.join(' OR ')})"
+ end
+ return query
+ end
+
+ def get_status_from_params(params)
+ query = ""
+ if params[:latest_status]
+ statuses = []
+ if params[:latest_status].class == String
+ params[:latest_status] = [params[:latest_status]]
+ end
+ if params[:latest_status].include?("recent") || params[:latest_status].include?("all")
+ query += " (variety:sent OR variety:followup_sent OR variety:response OR variety:comment)"
+ end
+ if params[:latest_status].include? "successful"
+ statuses << ['latest_status:successful', 'latest_status:partially_successful']
+ end
+ if params[:latest_status].include? "unsuccessful"
+ statuses << ['latest_status:rejected', 'latest_status:not_held']
+ end
+ if params[:latest_status].include? "awaiting"
+ statuses << ['latest_status:waiting_response', 'latest_status:waiting_clarification', 'waiting_classification:true', 'latest_status:internal_review','latest_status:gone_postal', 'latest_status:error_message', 'latest_status:requires_admin']
+ end
+ if params[:latest_status].include? "internal_review"
+ statuses << ['status:internal_review']
+ end
+ if params[:latest_status].include? "other"
+ statuses << ['latest_status:gone_postal', 'latest_status:error_message', 'latest_status:requires_admin', 'latest_status:user_withdrawn']
+ end
+ if params[:latest_status].include? "gone_postal"
+ statuses << ['latest_status:gone_postal']
+ end
+ if !statuses.empty?
+ query = " (#{statuses.join(' OR ')})"
+ end
+ end
+ return query
+ end
+
+ def get_date_range_from_params(params)
+ query = ""
+ if params.has_key?(:request_date_after) && !params.has_key?(:request_date_before)
+ params[:request_date_before] = Time.now.strftime("%d/%m/%Y")
+ query += " #{params[:request_date_after]}..#{params[:request_date_before]}"
+ elsif !params.has_key?(:request_date_after) && params.has_key?(:request_date_before)
+ params[:request_date_after] = "01/01/2001"
+ end
+ if params.has_key?(:request_date_after)
+ query = " #{params[:request_date_after]}..#{params[:request_date_before]}"
+ end
+ return query
+ end
+
+ def make_query_from_params(params)
+ query = params[:query] || "" if query.nil?
+ query += get_date_range_from_params(params)
+ query += get_request_variety_from_params(params)
+ query += get_status_from_params(params)
+ return query
+ end
+end