aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/admin_request_controller.rb38
-rw-r--r--app/controllers/request_controller.rb43
-rw-r--r--app/models/public_body.rb24
-rw-r--r--app/models/request_mailer.rb27
-rw-r--r--app/views/admin_request/show.rhtml4
-rw-r--r--app/views/comment/new.rhtml81
-rw-r--r--app/views/request/show.rhtml8
-rw-r--r--app/views/request/upload_response.rhtml34
-rw-r--r--app/views/request_mailer/fake_response.rhtml1
-rw-r--r--config/routes.rb4
-rw-r--r--public/stylesheets/main.css8
-rw-r--r--todo.txt18
12 files changed, 231 insertions, 59 deletions
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index a4f21adae..99da8eb53 100644
--- a/app/controllers/admin_request_controller.rb
+++ b/app/controllers/admin_request_controller.rb
@@ -4,7 +4,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: admin_request_controller.rb,v 1.16 2008-07-28 18:04:38 francis Exp $
+# $Id: admin_request_controller.rb,v 1.17 2008-09-02 17:44:14 francis Exp $
class AdminRequestController < ApplicationController
layout "admin"
@@ -142,6 +142,42 @@ class AdminRequestController < ApplicationController
redirect_to request_admin_url(destination_request)
end
+ def generate_upload_url
+ info_request = InfoRequest.find(params[:id])
+
+ if params[:incoming_message_id]
+ incoming_message = IncomingMessage.find(params[:incoming_message_id])
+ email = incoming_message.mail.from_addrs[0].address
+ name = incoming_message.safe_mail_from || info_request.public_body.name
+ else
+ email = info_request.public_body.request_email
+ name = info_request.public_body.name
+ end
+
+ user = User.find_user_by_email(email)
+ if not user
+ user = User.new(:name => name, :email => email, :password => PostRedirect.generate_random_token)
+ user.save!
+ end
+
+ if !info_request.public_body.is_foi_officer?(user)
+ flash[:notice] = user.email + " is not an email at the domain @" + info_request.public_body.foi_officer_domain_required + ", so won't be able to upload."
+ redirect_to request_admin_url(info_request)
+ return
+ end
+
+ # Bejeeps, look, sometimes a URL is something that belongs in a model, jesus.
+ # XXX hammer this square peg into the round MVC hole - should be calling main_url(upload_response_url())
+ post_redirect = PostRedirect.new(
+ :uri => upload_response_url(:url_title => info_request.url_title),
+ :user_id => user.id)
+ post_redirect.save!
+ url = confirm_url(:email_token => post_redirect.email_token)
+
+ flash[:notice] = 'Send "' + name + '" &lt;<a href="mailto:' + email + '">' + email + '</a>&gt; this URL: <a href="' + url + '">' + url + "</a> - it will log them in and let them upload a response to this request."
+ redirect_to request_admin_url(info_request)
+ end
+
private
end
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index ac025b94a..3a66af95c 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -4,7 +4,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: request_controller.rb,v 1.103 2008-09-02 14:57:31 francis Exp $
+# $Id: request_controller.rb,v 1.104 2008-09-02 17:44:14 francis Exp $
class RequestController < ApplicationController
@@ -345,5 +345,46 @@ class RequestController < ApplicationController
render :text => @attachment.body
end
+ # FOI officers can upload a response
+ def upload_response
+ @info_request = InfoRequest.find_by_url_title(params[:url_title])
+
+ @reason_params = {
+ :web => "To upload a response, you must be logged in using an email address from " + CGI.escapeHTML(@info_request.public_body.name),
+ :email => "Then you can upload an FOI response. ",
+ :email_subject => "Confirm your account on WhatDoTheyKnow.com"
+ }
+ if !authenticated?(@reason_params)
+ return
+ end
+
+ if !@info_request.public_body.is_foi_officer?(@user)
+ @reason_params[:user_name] = "an email @" + @info_request.public_body.foi_officer_domain_required
+ render :template => 'user/wrong_user'
+ return
+ end
+
+ if params[:submitted_upload_response]
+ file_name = nil
+ file_content = nil
+ if params[:file_1].class.to_s == "ActionController::UploadedTempfile"
+ file_name = params[:file_1].original_filename
+ file_content = params[:file_1].read
+ end
+ body = params[:body] || ""
+
+ if file_name.nil? && body.empty?
+ flash[:error] = "Please type a message and/or choose a file containing your response."
+ return
+ end
+
+ mail = RequestMailer.create_fake_response(@info_request, @user, body, file_name, file_content)
+ @info_request.receive(mail, mail.encoded)
+ flash[:notice] = "Thank you for responding to this FOI request! Your response has been published below, and a link to your response has been emailed to " + CGI.escapeHTML(@info_request.user.name) + "."
+ redirect_to request_url(@info_request)
+ return
+ end
+ end
+
end
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 2b9546d39..e05efc77e 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -23,7 +23,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: public_body.rb,v 1.102 2008-08-31 12:46:52 francis Exp $
+# $Id: public_body.rb,v 1.103 2008-09-02 17:44:14 francis Exp $
require 'csv'
require 'set'
@@ -366,6 +366,28 @@ class PublicBody < ActiveRecord::Base
return [errors, notes]
end
+ # Does this user have the power of FOI officer for this body?
+ def is_foi_officer?(user)
+ user_domain = user.email
+ user_domain =~ /@(.*)/
+ user_domain = $1
+
+ our_domain = self.request_email
+ our_domain =~ /@(.*)/
+ our_domain = $1
+
+ if user_domain.nil? or our_domain.nil?
+ return false
+ end
+
+ return our_domain == user_domain
+ end
+ def foi_officer_domain_required
+ our_domain = self.request_email
+ our_domain =~ /@(.*)/
+ return $1
+ end
+
end
diff --git a/app/models/request_mailer.rb b/app/models/request_mailer.rb
index 7762121e4..93b170aed 100644
--- a/app/models/request_mailer.rb
+++ b/app/models/request_mailer.rb
@@ -4,7 +4,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: request_mailer.rb,v 1.52 2008-09-01 16:14:01 francis Exp $
+# $Id: request_mailer.rb,v 1.53 2008-09-02 17:44:14 francis Exp $
class RequestMailer < ApplicationMailer
@@ -43,6 +43,30 @@ class RequestMailer < ApplicationMailer
end
end
+ # Used when an FOI officer uploads a response from their web browser - this is
+ # the "fake" email used to store in the same format in the database as if they
+ # had emailed it.
+ def fake_response(info_request, from_user, body, attachment_name, attachment_content)
+ @from = from_user.name_and_email
+ @recipients = info_request.incoming_name_and_email
+ @body = {
+ :body => body
+ }
+ if !attachment_name.nil? && !attachment_content.nil?
+ IncomingMessage # load global filename_to_mimetype XXX should move filename_to_mimetype to proper namespace
+ calc_mime = filename_to_mimetype(attachment_name)
+ if calc_mime
+ content_type = calc_mime
+ else
+ content_type = 'application/octet-stream'
+ end
+
+ attachment :content_type => content_type,
+ :body => attachment_content,
+ :filename => attachment_name
+ end
+ end
+
# Incoming message arrived for a request, but new responses have been stopped.
def stopped_responses(info_request, email)
@from = contact_from_name_and_email
@@ -147,7 +171,6 @@ class RequestMailer < ApplicationMailer
@body = { :count => @count, :info_request => info_request, :url => main_url(comment_url(earliest_unalerted_comment)) }
end
-
# Class function, called by script/mailin with all incoming responses.
# [ This is a copy (Monkeypatch!) of function from action_mailer/base.rb,
# but which additionally passes the raw_email to the member function, as we
diff --git a/app/views/admin_request/show.rhtml b/app/views/admin_request/show.rhtml
index 56539be0a..29989933b 100644
--- a/app/views/admin_request/show.rhtml
+++ b/app/views/admin_request/show.rhtml
@@ -15,6 +15,7 @@
<p>
<%= link_to 'Public page', main_url(request_url(@info_request)) %>
| <%= link_to 'Edit', '../edit/' + @info_request.id.to_s %>
+ | <%= link_to 'FOI officer upload URL', '../generate_upload_url/' + @info_request.id.to_s %> (see also links on incoming messages below)
</p>
<h2>Events</h2>
@@ -104,6 +105,9 @@
<%= submit_tag "Redeliver to another request" %>
</div>
<% end %>
+ <p>
+ <%= link_to 'FOI officer upload URL', '../generate_upload_url/' + @info_request.id.to_s + "?incoming_message_id=" + incoming_message.id.to_s %>
+ </p>
</td>
</tr>
<% end %>
diff --git a/app/views/comment/new.rhtml b/app/views/comment/new.rhtml
index 056d5f7ba..01692f4c7 100644
--- a/app/views/comment/new.rhtml
+++ b/app/views/comment/new.rhtml
@@ -13,56 +13,53 @@
<h1>Add an annotation to '<%=request_link(@info_request)%>'</h1>
+<p>
+Annotations will be posted publically here, and are
+<strong>not</strong> sent to the authority.
+</p>
-<% if true %>
- <p>
- Annotations will be posted publically here, and are
- <strong>not</strong> sent to the authority.
- </p>
+<p>
+Help the requester with their request.
+</p>
- <p>
- Help the requester with their request.
- </p>
+<ul>
- <ul>
-
- <% if [ 'waiting_clarification' ].include?(@info_request.described_state) %>
- <li> Advise on how to <strong>best clarify</strong> the request.</li>
- <% end %>
-
- <% if @info_request.awaiting_description %>
- <% end %>
+<% if [ 'waiting_clarification' ].include?(@info_request.described_state) %>
+ <li> Advise on how to <strong>best clarify</strong> the request.</li>
+<% end %>
- <% if not [ 'successful', 'partially_successful' ].include?(@info_request.described_state) %>
- <li> Link to the information requested, if it is <strong>already available</strong> on the Internet. </li>
- <li> Suggest <strong>where else</strong> the requester might find the information. </li>
- <li> Offer better ways of <strong>wording the request</strong> to get the information. </li>
- <% end %>
+<% if @info_request.awaiting_description %>
+<% end %>
- <% if [ 'successful', 'partially_successful' ].include?(@info_request.described_state) %>
- <li> <strong>Summarise</strong> the content of any information returned. </li>
- <li> Say how you've <strong>used the information</strong>, with links if possible. </li>
- <li> <strong>Thank</strong> the public authority or <%=h @info_request.user.name %>. </li>
- <% end %>
- <% if [ 'partially_successful' ].include?(@info_request.described_state) %>
- <li> Suggest how the requester can find the <strong>rest of the information</strong>. </li>
- <% end %>
- <% if [ 'successful', 'partially_successful' ].include?(@info_request.described_state) %>
- <li> Point to <strong>related information</strong>, campaigns or forums which may be useful. </li>
- <% end %>
+<% if not [ 'successful', 'partially_successful' ].include?(@info_request.described_state) %>
+ <li> Link to the information requested, if it is <strong>already available</strong> on the Internet. </li>
+ <li> Suggest <strong>where else</strong> the requester might find the information. </li>
+ <li> Offer better ways of <strong>wording the request</strong> to get the information. </li>
+<% end %>
- <% if [ 'not_held' ].include?(@info_request.described_state) %>
- <li> Ideas on what <strong>other documents to request</strong> which the authority may hold. </li>
- <% end %>
- <% if [ 'rejected' ].include?(@info_request.described_state) %>
- <li> Advise on whether the <strong>rejection is legal</strong>, and how to complain about if not. </li>
- <% end %>
+<% if [ 'successful', 'partially_successful' ].include?(@info_request.described_state) %>
+ <li> <strong>Summarise</strong> the content of any information returned. </li>
+ <li> Say how you've <strong>used the information</strong>, with links if possible. </li>
+ <li> <strong>Thank</strong> the public authority or <%=h @info_request.user.name %>. </li>
+<% end %>
+<% if [ 'partially_successful' ].include?(@info_request.described_state) %>
+ <li> Suggest how the requester can find the <strong>rest of the information</strong>. </li>
+<% end %>
+<% if [ 'successful', 'partially_successful' ].include?(@info_request.described_state) %>
+ <li> Point to <strong>related information</strong>, campaigns or forums which may be useful. </li>
+<% end %>
- <% if [ 'requires_admin' ].include?(@info_request.described_state) %>
- <li> Your thoughts on what the WhatDoTheyKnow <strong>administrators</strong> should do about the request. </li>
- <% end %>
+<% if [ 'not_held' ].include?(@info_request.described_state) %>
+ <li> Ideas on what <strong>other documents to request</strong> which the authority may hold. </li>
+<% end %>
+<% if [ 'rejected' ].include?(@info_request.described_state) %>
+ <li> Advise on whether the <strong>rejection is legal</strong>, and how to complain about if not. </li>
+<% end %>
- </ul>
+<% if [ 'requires_admin' ].include?(@info_request.described_state) %>
+ <li> Your thoughts on what the WhatDoTheyKnow <strong>administrators</strong> should do about the request. </li>
<% end %>
+</ul>
+
<%= render :partial => 'comment/comment_form', :locals => { :track_thing => @track_thing } %>
diff --git a/app/views/request/show.rhtml b/app/views/request/show.rhtml
index 2e0d79e18..4189a775f 100644
--- a/app/views/request/show.rhtml
+++ b/app/views/request/show.rhtml
@@ -107,9 +107,13 @@
</div>
<% end %>
- <div id="add_annotation">
+ <div id="after_actions">
+ <h2>Things to do with this request</h2>
<%= link_to "Add an annotation", new_comment_url(:url_title => @info_request.url_title) %> (to help
- the requester or others with this request)
+ the requester or others)
+ <br>
+ <%= link_to "Upload large response", upload_response_url(:url_title => @info_request.url_title) %> (FOI
+ officers only)
</div>
</div>
diff --git a/app/views/request/upload_response.rhtml b/app/views/request/upload_response.rhtml
new file mode 100644
index 000000000..f618dcadb
--- /dev/null
+++ b/app/views/request/upload_response.rhtml
@@ -0,0 +1,34 @@
+<% @title = "Upload a response to the FOI request '" + h(@info_request.title) + "' made by " + h(@info_request.user.name) %>
+
+<%= foi_error_messages_for :comment %>
+
+<h1>Upload a response to the FOI request '<%=request_link(@info_request)%>' made by <%=user_link(@info_request.user) %></h1>
+
+<% form_tag '', :html => { :id => 'upload_response_form' }, :multipart => true do %>
+ <p>
+ Your response will <strong>appear on the Internet</strong>, <a href="http://localhost:3000/help/about#officers">read why</a> and answers to other questions.
+ </p>
+
+ <p>
+ <label class="form_label" for="upload_response_body">Message (to go with file):</label>
+ <%= text_area_tag :body, "", :size => "55x10" %>
+ </p>
+
+ <p>
+ <label class="form_label" for="outgoing_message_body">File to upload (optional):</label>
+ <%= file_field_tag :file_1, :size => 35 %>
+ </p>
+
+ <p>
+ <%= hidden_field_tag 'submitted_upload_response', 1 %>
+ <%= submit_tag "Upload FOI response" %>
+ (<strong>patience</strong>, especially for large files, it may take a while!)
+ </p>
+
+ <p>If you prefer, you may send responses to this FOI request by email to
+ <a href="mailto:<%=h @info_request.incoming_email%>"><%=h @info_request.incoming_email%></a>.
+ </p>
+
+<% end %>
+
+
diff --git a/app/views/request_mailer/fake_response.rhtml b/app/views/request_mailer/fake_response.rhtml
new file mode 100644
index 000000000..e9858f03f
--- /dev/null
+++ b/app/views/request_mailer/fake_response.rhtml
@@ -0,0 +1 @@
+<%=@body%>
diff --git a/config/routes.rb b/config/routes.rb
index 6580e0e62..1d2f8374f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,7 +4,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: routes.rb,v 1.67 2008-08-13 01:39:43 francis Exp $
+# $Id: routes.rb,v 1.68 2008-09-02 17:44:15 francis Exp $
ActionController::Routing::Routes.draw do |map|
@@ -43,6 +43,8 @@ ActionController::Routing::Routes.draw do |map|
request.get_attachment '/request/:id/response/:incoming_message_id/attach/:part/*file_name', :action => 'get_attachment'
request.info_request_event '/request_event/:info_request_event_id', :action => 'show_request_event'
+
+ request.upload_response "/upload/request/:url_title", :action => 'upload_response'
end
map.with_options :controller => 'user' do |user|
diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css
index 485a27719..f6a5fa48f 100644
--- a/public/stylesheets/main.css
+++ b/public/stylesheets/main.css
@@ -559,7 +559,7 @@ div.pagination { text-align: center; padding-top: 0.3em;}
/*-------------------- Content : form errors */
-.errorExplanation
+#error, .errorExplanation
{
color: #FF0606;
font-size: 1.4em;
@@ -568,7 +568,9 @@ div.pagination { text-align: center; padding-top: 0.3em;}
border-width: 1px;
border-style: solid;
background-color: #ffeeee;
- padding-right: 0.3em;
+}
+#error {
+ padding: 0.5em;
}
.fieldWithErrors
{
@@ -653,7 +655,7 @@ div.comment_in_request
div.comment_in_request h2
{ text-align: right; font-size: 1em; }
-div#add_annotation
+div#after_actions
{
float: left;
margin-bottom: 1em;
diff --git a/todo.txt b/todo.txt
index 2abf33421..574f0390d 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,10 +1,9 @@
-Check email address of replies
- - validate the email address itself
- - and fix parser bug for @ in prefix
- - maybe use subject in followup
-
Test data for Tony
+Check speed of upload
+Look for pass by value efficiencies
+
+
Site move:
Install PostgresSQL 8.3
Move database
@@ -13,6 +12,8 @@ Site move:
Next
====
+Maybe move "send followup" into actions?
+
Add no robots to requested similar to stop google scanning
use HTML meta
@@ -42,6 +43,8 @@ Grrr - so here I wanted to clarify my request, but don't want the timer to be re
http://www.whatdotheyknow.com/request/online_petitions_documents_from#incoming-3248
Perhaps encourage user to annotate what they learnt after getting information?
+When they say "successful", encourage them to make an annotation?
+
Clear out all the need admin attention requests
Clear out all the need classifying requests
@@ -66,6 +69,7 @@ CSS things
- CSS error on "all councils" page on some browsers
- Need Icon for annotations in search results
- Icon for government departments is too Parliamentary
+ - Spacing on error boxes round form elements
Merge workflow into one stream - find information, if you can't find it then request it.
so just search is on front page, with popular stuff below a la Google Directory
@@ -79,10 +83,12 @@ Use spelling correction for public bodies search (in addition to substring?)
Flag bad comments, delete comments from admin interface
-
Later
=====
+Look at quote_address_if_necessary in actionmailer's quoting.rb - why did it
+not work for the email address with "@" in its name part?
+
Search FAQ and other help pages with normal search
- also the "notes" section on an authority