diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/request_controller.rb | 67 | ||||
-rw-r--r-- | app/models/incoming_message.rb | 45 | ||||
-rw-r--r-- | app/views/layouts/default.rhtml | 3 | ||||
-rw-r--r-- | app/views/request/_after_actions.rhtml | 6 | ||||
-rw-r--r-- | app/views/request/simple_correspondence.rhtml | 45 |
5 files changed, 127 insertions, 39 deletions
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb index 12b5247b5..b615cc834 100644 --- a/app/controllers/request_controller.rb +++ b/app/controllers/request_controller.rb @@ -7,6 +7,8 @@ # $Id: request_controller.rb,v 1.192 2009-10-19 19:26:40 francis Exp $ require 'alaveteli_file_types' +require 'zip/zip' +require 'open-uri' class RequestController < ApplicationController before_filter :check_read_only, :only => [ :new, :show_response, :describe_state, :upload_response ] @@ -67,7 +69,6 @@ class RequestController < ApplicationController @status = @info_request.calculate_status @collapse_quotes = params[:unfold] ? false : true @update_status = params[:update_status] ? true : false - @is_owning_user = @info_request.is_owning_user?(authenticated_user) @old_unclassified = @info_request.is_old_unclassified? && !authenticated_user.nil? if @update_status @@ -101,7 +102,7 @@ class RequestController < ApplicationController # For send followup link at bottom @last_response = @info_request.get_last_response - + @is_owning_user = @info_request.is_owning_user?(authenticated_user) respond_to do |format| format.html { @has_json = true; render :template => 'request/show'} format.json { render :json => @info_request.json_for_api(true) } @@ -754,5 +755,67 @@ class RequestController < ApplicationController render :partial => "request/search_ahead.rhtml" end + + def download_entire_request + @locale = self.locale_from_params() + PublicBody.with_locale(@locale) do + info_request = InfoRequest.find_by_url_title(params[:url_title]) + if info_request.nil? + raise ActiveRecord::RecordNotFound.new("Request not found") + end + if authenticated?( + :web => _("To download the zip file"), + :email => _("Then you can download a zip file of {{info_request_title}}.",:info_request_title=>info_request.title), + :email_subject => _("Log in to download a zip file of {{info_request_title}}",:info_request_title=>info_request.title) + ) + updated = Digest::SHA1.hexdigest(info_request.get_last_event.created_at.to_s + info_request.updated_at.to_s) + @url_path = "/download/#{updated[0..1]}/#{updated}/#{params[:url_title]}.zip" + file_path = File.join(File.dirname(__FILE__), '../../cache/zips', @url_path) + if !File.exists?(file_path) + FileUtils.mkdir_p(File.dirname(file_path)) + Zip::ZipFile.open(file_path, Zip::ZipFile::CREATE) { |zipfile| + convert_command = MySociety::Config.get("HTML_TO_PDF_COMMAND") + done = false + if File.exists?(convert_command) + domain = MySociety::Config.get("DOMAIN") + url = "http://#{domain}#{request_url(info_request)}?print_stylesheet=1" + tempfile = Tempfile.new('foihtml2pdf') + output = AlaveteliExternalCommand.run(convert_command, url, tempfile.path) + if !output.nil? + zipfile.get_output_stream("correspondence.pdf") { |f| + f.puts(File.open(tempfile.path).read) + } + done = true + else + logger.error("Could not convert info request #{info_request.id} to PDF") + end + tempfile.close + else + logger.warn("No HTML -> PDF converter found at #{convert_command}") + end + if !done + @info_request = info_request + @info_request_events = info_request.info_request_events + template = File.read(File.join(File.dirname(__FILE__), "..", "views", "request", "simple_correspondence.rhtml")) + output = ERB.new(template).result(binding) + zipfile.get_output_stream("correspondence.txt") { |f| + f.puts(output) + } + end + for message in info_request.incoming_messages + attachments = message.get_attachments_for_display + for attachment in attachments + zipfile.get_output_stream(attachment.display_filename) { |f| + f.puts(attachment.body) + } + end + end + } + File.chmod(0644, file_path) + end + redirect_to @url_path + end + end + end end diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb index edc395ff4..c19f1b6e3 100644 --- a/app/models/incoming_message.rb +++ b/app/models/incoming_message.rb @@ -29,7 +29,6 @@ # general not specific to IncomingMessage. require 'alaveteli_file_types' -require 'external_command' require 'htmlentities' require 'rexml/document' require 'zip/zip' @@ -1121,38 +1120,38 @@ class IncomingMessage < ActiveRecord::Base tempfile.print body tempfile.flush if content_type == 'application/vnd.ms-word' - external_command("/usr/bin/wvText", tempfile.path, tempfile.path + ".txt") + AlaveteliExternalCommand.run("/usr/bin/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") - external_command("/usr/bin/catdoc", tempfile.path, :append_to => text) + AlaveteliExternalCommand.run("/usr/bin/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 - external_command("/usr/bin/catdoc", tempfile.path, :append_to => text) + AlaveteliExternalCommand.run("/usr/bin/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. - external_command("/usr/bin/elinks", "-eval", "'set document.codepage.assume = \"utf-8\"'", "-dump-charset", "utf-8", "-force-html", "-dump", + AlaveteliExternalCommand.run("/usr/bin/elinks", "-eval", "'set document.codepage.assume = \"utf-8\"'", "-dump-charset", "utf-8", "-force-html", "-dump", tempfile.path, :append_to => text) elsif content_type == 'application/vnd.ms-excel' # Bit crazy using /usr/bin/strings - but xls2csv, xlhtml and # py_xls2txt only extract text from cells, not from floating # notes. catdoc may be fooled by weird character sets, but will # probably do for UK FOI requests. - external_command("/usr/bin/strings", tempfile.path, :append_to => text) + AlaveteliExternalCommand.run("/usr/bin/strings", tempfile.path, :append_to => text) elsif content_type == 'application/vnd.ms-powerpoint' # ppthtml seems to catch more text, but only outputs HTML when # we want text, so just use catppt for now - external_command("/usr/bin/catppt", tempfile.path, :append_to => text) + AlaveteliExternalCommand.run("/usr/bin/catppt", tempfile.path, :append_to => text) elsif content_type == 'application/pdf' - external_command("/usr/bin/pdftotext", tempfile.path, "-", :append_to => text) + AlaveteliExternalCommand.run("/usr/bin/pdftotext", tempfile.path, "-", :append_to => text) elsif content_type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' # This is Microsoft's XML office document format. # Just pull out the main XML file, and strip it of text. - xml = external_command("/usr/bin/unzip", "-qq", "-c", tempfile.path, "word/document.xml") + xml = AlaveteliExternalCommand.run("/usr/bin/unzip", "-qq", "-c", tempfile.path, "word/document.xml") if !xml.nil? doc = REXML::Document.new(xml) text += doc.each_element( './/text()' ){}.join(" ") @@ -1341,34 +1340,6 @@ class IncomingMessage < ActiveRecord::Base end private :normalise_content_type - def self.external_command(program_name, *args) - # Run an external program, and return its output. - # Standard error is suppressed unless the program - # fails (i.e. returns a non-zero exit status). - opts = {} - if !args.empty? && args[-1].is_a?(Hash) - opts = args.pop - end - - xc = ExternalCommand.new(program_name, *args) - if opts.has_key? :append_to - xc.out = opts[:append_to] - end - xc.run() - if xc.status != 0 - # Error - $stderr.puts("Error from #{program_name} #{args.join(' ')}:") - $stderr.print(xc.err) - return nil - else - if opts.has_key? :append_to - opts[:append_to] << "\n\n" - else - return xc.out - end - end - end - private_class_method :external_command end diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml index 8812f50a6..5ad6ccecb 100644 --- a/app/views/layouts/default.rhtml +++ b/app/views/layouts/default.rhtml @@ -21,6 +21,9 @@ <%= stylesheet_link_tag 'fonts', :rel => "stylesheet", :media => "all" %> <%= stylesheet_link_tag 'theme', :rel => "stylesheet", :media => "all" %> <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "print" %> + <% if !params[:print_stylesheet].nil? %> + <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "all" %> + <% end %> <%= javascript_include_tag 'jquery.js', 'jquery-ui.min','jquery.cookie.js', 'general.js' %> <%= stylesheet_link_tag 'admin-theme/jquery-ui-1.8.15.custom.css', :rel => 'stylesheet'%> <!--[if LT IE 7]> diff --git a/app/views/request/_after_actions.rhtml b/app/views/request/_after_actions.rhtml index 797ecaea5..30bcf3046 100644 --- a/app/views/request/_after_actions.rhtml +++ b/app/views/request/_after_actions.rhtml @@ -36,6 +36,9 @@ <li> <%= link_to _("Request an internal review"), show_response_no_followup_url(:id => @info_request.id, :incoming_message_id => nil) + "?internal_review=1#followup" %> </li> + <li> + <%= link_to _("Download a zip file containing all the above correspondence"), download_entire_request_url(:url_title => @info_request.url_title) %> + </li> </ul> </div> @@ -45,6 +48,9 @@ <li> <%= link_to _("Respond to request"), upload_response_url(:url_title => @info_request.url_title) %> </li> + <li> + <%= link_to _("Download a zip file containing all the above correspondence"), download_entire_request_url(:url_title => @info_request.url_title) %> + </li> </ul> </div> </div> diff --git a/app/views/request/simple_correspondence.rhtml b/app/views/request/simple_correspondence.rhtml new file mode 100644 index 000000000..45b90b84b --- /dev/null +++ b/app/views/request/simple_correspondence.rhtml @@ -0,0 +1,45 @@ +<%= _('This is a plain-text version of the Freedom of Information request "{{request_title}}". The latest, full version is available online at {{full_url}}', :request_title => @info_request.title, :full_url => "http://#{MySociety::Config.get('DOMAIN')}#{show_request_path(:url_title=>@info_request.url_title)}") %>. + +<% for info_request_event in @info_request_events %> +<% + incoming_message = nil + if info_request_event.visible + if !info_request_event.nil? && info_request_event.event_type == 'response' + incoming_message = info_request_event.incoming_message + end + + + if not incoming_message.nil? + if !incoming_message.safe_mail_from.nil? && incoming_message.safe_mail_from.strip != @info_request.public_body.name.strip %> +<%= _('From:') %> <%= incoming_message.safe_mail_from %><% end + if incoming_message.safe_mail_from.nil? || (incoming_message.mail_from_domain == @info_request.public_body.request_email_domain) %>, <%= @info_request.public_body.name %><% end %> +<%= _('To:') %> <%= @info_request.user.name %> +<%= _('Date:') %> <%= simple_date(incoming_message.sent_at) %> + +<%= incoming_message.get_body_for_quoting %> +<% incoming_message.get_attachments_for_display.each do |a| %> + <%= _('Attachment:') %> <%= a.display_filename %> (<%= a.display_size %>) + <% end %> +<% +elsif [ 'sent', 'followup_sent' ].include?(info_request_event.event_type) + outgoing_message = info_request_event.outgoing_message + %> +<%= _('From:') %> <%= @info_request.user.name %> +<%= _('To:') %> <%= @info_request.public_body.name %> +<%= _('Date:') %> <%= simple_date(info_request_event.created_at) %> +<% + text = outgoing_message.body.strip + outgoing_message.remove_privacy_sensitive_things!(text) %> + +<%= text %> +<% elsif [ 'resent', 'followup_resent' ].include?(info_request_event.event_type) %> +<%= _('Date:') %> <%= simple_date(info_request_event.created_at) %> +Sent <% if info_request_event.outgoing_message.message_type == 'initial_request' %> request <% elsif info_request_event.outgoing_message.message_type == 'followup' %> a follow up <% else %> <% raise "unknown message_type" %><% end %> to <%= public_body_link(@info_request.public_body) %> again<% if not info_request_event.same_email_as_previous_send? %>, using a new contact address<% end %>. + +<% elsif info_request_event.event_type == 'comment' + comment = info_request_event.comment +%> +<%= _("{{username}} left an annotation:", :username =>comment.user.name) %> (<%= simple_date(comment.created_at || Time.now) %>) +<%= comment.body.strip %> +<% end %> +-------------------------------<% end %><% end %> |