diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/application_controller.rb | 40 | ||||
-rw-r--r-- | app/controllers/general_controller.rb | 15 | ||||
-rw-r--r-- | app/controllers/request_controller.rb | 17 | ||||
-rw-r--r-- | app/models/foi_attachment.rb | 8 | ||||
-rw-r--r-- | app/models/incoming_message.rb | 40 | ||||
-rw-r--r-- | app/views/general/search.rhtml | 3 |
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 %> |