aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/application_controller.rb40
-rw-r--r--app/controllers/general_controller.rb15
-rw-r--r--app/controllers/request_controller.rb17
-rw-r--r--app/models/foi_attachment.rb8
-rw-r--r--app/models/incoming_message.rb40
-rw-r--r--app/views/general/search.rhtml3
6 files changed, 62 insertions, 61 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 2633aca4d..0c8544932 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -366,23 +366,31 @@ class ApplicationController < ActionController::Base
return (params[:page] || "1").to_i
end
def perform_search_typeahead(query, model)
- # strip out unintended search operators - see
- # https://github.com/sebbacon/alaveteli/issues/328
- # XXX this is a result of the OR hack below -- should fix by
- # allowing a parameter to perform_search to control the
- # default operator!
- query = query.strip.gsub(/(\s-\s|&|\(|\))/, "")
- query = query.split(/ +(?![-+]+)/)
- if query.last.nil? || query.last.strip.length < 3
+ query_words = query.split(/ +(?![-+]+)/)
+ if query_words.last.nil? || query_words.last.strip.length < 3
xapian_requests = nil
else
- query = query.join(' OR ') # XXX: HACK for OR instead of default AND!
if model == PublicBody
collapse = nil
elsif model == InfoRequestEvent
collapse = 'request_collapse'
end
- xapian_requests = perform_search([model], query, 'relevant', collapse, 5)
+ options = {
+ :offset => 0,
+ :limit => 5,
+ :sort_by_prefix => nil,
+ :sort_by_ascending => true,
+ :collapse_by_prefix => collapse,
+ }
+ ActsAsXapian.readable_init
+ old_default_op = ActsAsXapian.query_parser.default_op
+ ActsAsXapian.query_parser.default_op = Xapian::Query::OP_OR
+ user_query = ActsAsXapian.query_parser.parse_query(
+ query,
+ Xapian::QueryParser::FLAG_LOVEHATE | Xapian::QueryParser::FLAG_PARTIAL |
+ Xapian::QueryParser::FLAG_SPELLING_CORRECTION)
+ xapian_requests = ActsAsXapian::Search.new([model], query, options, user_query)
+ ActsAsXapian.query_parser.default_op = old_default_op
end
return xapian_requests
end
@@ -504,12 +512,22 @@ class ApplicationController < ActionController::Base
default = MySociety::Config.get('ISO_COUNTRY_CODE', '')
country = ""
if !gaze.empty?
- country = open("#{gaze}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}").read.strip
+ country = quietly_try_to_open("#{gaze}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}")
end
country = default if country.empty?
return country
end
+ def quietly_try_to_open(url)
+ begin
+ result = open(url).read.strip
+ rescue OpenURI::HTTPError, SocketError
+ logger.warn("Unable to open third-party URL #{url}")
+ result = ""
+ end
+ return result
+ end
+
# URL generating functions are needed by all controllers (for redirects),
# views (for links) and mailers (for use in emails), so include them into
# all of all.
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 6cdfb9d5f..d28f4deec 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -71,14 +71,15 @@ class GeneralController < ApplicationController
medium_cache
@feed_autodetect = []
@feed_url = "#{MySociety::Config.get('BLOG_FEED', '')}?lang=#{self.locale_from_params()}"
+ @blog_items = []
if not @feed_url.empty?
- content = open(@feed_url).read
- @data = XmlSimple.xml_in(content)
- @channel = @data['channel'][0]
- @blog_items = @channel['item']
- @feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}]
- else
- @blog_items = []
+ content = quietly_try_to_open(@feed_url)
+ if !content.empty?
+ @data = XmlSimple.xml_in(content)
+ @channel = @data['channel'][0]
+ @blog_items = @channel['item']
+ @feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}]
+ end
end
@twitter_user = MySociety::Config.get('TWITTER_USERNAME', '')
end
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index 8714f03cf..1c7aeedcc 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -604,15 +604,12 @@ class RequestController < ApplicationController
before_filter :authenticate_attachment, :only => [ :get_attachment, :get_attachment_as_html ]
def authenticate_attachment
- if request.path =~ /\/$/ || !(params[:part] =~ /^\d+$/)
- raise PermissionDenied.new("Directory listing not allowed")
- else
- # Test for hidden
- incoming_message = IncomingMessage.find(params[:incoming_message_id])
- if !incoming_message.info_request.user_can_view?(authenticated_user)
- @info_request = incoming_message.info_request # used by view
- render :template => 'request/hidden', :status => 410 # gone
- end
+ # Test for hidden
+ incoming_message = IncomingMessage.find(params[:incoming_message_id])
+ raise ActiveRecord::RecordNotFound.new("Message not found") if incoming_message.nil?
+ if !incoming_message.info_request.user_can_view?(authenticated_user)
+ @info_request = incoming_message.info_request # used by view
+ render :template => 'request/hidden', :status => 410 # gone
end
end
@@ -624,8 +621,8 @@ class RequestController < ApplicationController
else
key = params.merge(:only_path => true)
key_path = foi_fragment_cache_path(key)
-
if foi_fragment_cache_exists?(key_path)
+ raise PermissionDenied.new("Directory listing not allowed") if File.directory?(key_path)
cached = foi_fragment_cache_read(key_path)
response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name].join("/")) || 'application/octet-stream'
render_for_text(cached)
diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb
index 20c40abea..74346227b 100644
--- a/app/models/foi_attachment.rb
+++ b/app/models/foi_attachment.rb
@@ -312,13 +312,9 @@ class FoiAttachment < ActiveRecord::Base
tempfile.flush
if self.content_type == 'application/pdf'
- IO.popen("/usr/bin/pdftohtml -nodrm -zoom 1.0 -stdout -enc UTF-8 -noframes " + tempfile.path + "", "r") do |child|
- html = child.read()
- end
+ html = AlaveteliExternalCommand.run("pdftohtml", "-nodrm", "-zoom", "1.0", "-stdout", "-enc", "UTF-8", "-noframes", tempfile.path)
elsif self.content_type == 'application/rtf'
- IO.popen("/usr/bin/unrtf --html " + tempfile.path + "", "r") do |child|
- html = child.read()
- end
+ html = AlaveteliExternalCommand.run("unrtf", "--html", tempfile.path)
elsif self.has_google_docs_viewer?
html = '' # force error and using Google docs viewer
else
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index 2186d50dc..91f1cf7c0 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -266,11 +266,7 @@ class IncomingMessage < ActiveRecord::Base
# Special cases for some content types
if content_type == 'application/pdf'
uncompressed_text = nil
- IO.popen("#{`which pdftk`.chomp} - output - uncompress", "r+") do |child|
- child.write(text)
- child.close_write()
- uncompressed_text = child.read()
- end
+ uncompressed_text = AlaveteliExternalCommand.run("pdftk", "-", "output", "-", "uncompress", :stdin_string => text)
# if we managed to uncompress the PDF...
if !uncompressed_text.nil? && !uncompressed_text.empty?
# then censor stuff (making a copy so can compare again in a bit)
@@ -281,15 +277,11 @@ class IncomingMessage < ActiveRecord::Base
# then use the altered file (recompressed)
recompressed_text = nil
if MySociety::Config.get('USE_GHOSTSCRIPT_COMPRESSION') == true
- command = "gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=- -"
+ command = ["gs", "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4", "-dPDFSETTINGS=/screen", "-dNOPAUSE", "-dQUIET", "-dBATCH", "-sOutputFile=-", "-"]
else
- command = "#{`which pdftk`.chomp} - output - compress"
- end
- IO.popen(command, "r+") do |child|
- child.write(censored_uncompressed_text)
- child.close_write()
- recompressed_text = child.read()
+ command = ["pdftk", "-", "output", "-", "compress"]
end
+ recompressed_text = AlaveteliExternalCommand.run(*(command + [{:stdin_string=>censored_uncompressed_text}]))
if recompressed_text.nil? || recompressed_text.empty?
# buggy versions of pdftk sometimes fail on
# compression, I don't see it's a disaster in
@@ -325,8 +317,8 @@ class IncomingMessage < ActiveRecord::Base
emails = ascii_chars.scan(MySociety::Validate.email_find_regexp)
# Convert back to UCS-2, making a mask at the same time
emails.map! {|email| [
- Iconv.conv('ucs-2', 'ascii', email[0]),
- Iconv.conv('ucs-2', 'ascii', email[0].gsub(/[^@.]/, 'x'))
+ Iconv.conv('ucs-2le', 'ascii', email[0]),
+ Iconv.conv('ucs-2le', 'ascii', email[0].gsub(/[^@.]/, 'x'))
] }
# Now search and replace the UCS-2 email with the UCS-2 mask
for email, mask in emails
@@ -638,7 +630,7 @@ 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 UT8 in this call
+ text = part.body # by default, TMail converts to UTF8 in this call
source_charset = part.charset
if part.content_type == 'text/html'
# e.g. http://www.whatdotheyknow.com/request/35/response/177
@@ -738,9 +730,7 @@ class IncomingMessage < ActiveRecord::Base
tempfile = Tempfile.new('foiuu')
tempfile.print uu
tempfile.flush
- IO.popen("/usr/bin/uudecode " + tempfile.path + " -o -", "r") do |child|
- content = child.read()
- end
+ content = AlaveteliExternalCommand.run("uudecode", "-o", "/dev/stdout", tempfile.path)
tempfile.close
# Make attachment type from it, working out filename and mime type
filename = uu.match(/^begin\s+[0-9]+\s+(.*)$/)[1]
@@ -938,23 +928,23 @@ class IncomingMessage < ActiveRecord::Base
tempfile.print body
tempfile.flush
if content_type == 'application/vnd.ms-word'
- AlaveteliExternalCommand.run(`which wvText`.chomp, tempfile.path, tempfile.path + ".txt")
+ 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(`which catdoc`.chomp, tempfile.path, :append_to => text)
+ 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(`which catdoc`.chomp, tempfile.path, :append_to => text)
+ 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(`which elinks`.chomp, "-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)
+ 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
@@ -964,9 +954,9 @@ class IncomingMessage < ActiveRecord::Base
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(`which catppt`.chomp, tempfile.path, :append_to => text)
+ AlaveteliExternalCommand.run("catppt", tempfile.path, :append_to => text)
elsif content_type == 'application/pdf'
- AlaveteliExternalCommand.run(`which pdftotext`.chomp, tempfile.path, "-", :append_to => text)
+ 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.
diff --git a/app/views/general/search.rhtml b/app/views/general/search.rhtml
index 43aa9785a..fe6229293 100644
--- a/app/views/general/search.rhtml
+++ b/app/views/general/search.rhtml
@@ -7,7 +7,7 @@
<% if @query.nil? %>
<% @title = _("Search Freedom of Information requests, public authorities and users") %>
<% elsif @total_hits == 0 %>
- <% @title = _('There were no requests matching your query.') %>
+ <% @title = _('There were no results matching your query.') %>
<% else %>
<% @title = _("Results page {{page_number}}", :page_number => @page.to_s) %>
<% end%>
@@ -166,7 +166,6 @@
<%= will_paginate WillPaginate::Collection.new(@page, @bodies_per_page, @xapian_bodies.matches_estimated) %>
<% elsif @bodies && !@query.nil? && @xapian_bodies.results.size == 0 && @page == 1 %>
- <h2 class="publicbody_results"><%= _('No public authorities found') %></h2>
<% if @spelling_correction %>
<p id="did_you_mean"><%= _('Did you mean: {{correction}}', :correction => search_link(@spelling_correction, @postfix)) %></p>
<% end %>