aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/admin_controller.rb3
-rw-r--r--app/controllers/admin_request_controller.rb36
-rw-r--r--app/models/incoming_message.rb12
-rw-r--r--app/models/info_request.rb30
-rw-r--r--app/models/public_body.rb19
-rw-r--r--app/models/request_mailer.rb7
-rw-r--r--app/models/user.rb21
-rw-r--r--app/views/admin/index.rhtml14
-rw-r--r--app/views/admin_request/show.rhtml20
-rw-r--r--app/views/layouts/admin.rhtml4
-rw-r--r--spec/models/request_mailer_spec.rb9
-rw-r--r--todo.txt7
12 files changed, 158 insertions, 24 deletions
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index a40225a75..148853168 100644
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_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_controller.rb,v 1.16 2008-06-10 10:18:57 francis Exp $
+# $Id: admin_controller.rb,v 1.17 2008-07-08 09:41:04 francis Exp $
class AdminController < ApplicationController
layout "admin"
@@ -22,6 +22,7 @@ class AdminController < ApplicationController
@requires_admin_requests = InfoRequest.find(:all, :select => '*, ' + last_event_time_clause + ' as last_event_time', :conditions => ["described_state = 'requires_admin'"], :order => "last_event_time")
@blank_contacts = PublicBody.find(:all, :conditions => ["request_email = ''"], :order => "updated_at")
@one_week_old_unclassified = InfoRequest.find(:all, :select => '*, ' + last_event_time_clause + ' as last_event_time', :conditions => [ "awaiting_description and " + last_event_time_clause + " < ? and prominence != 'backpage'", Time.now() - 1.weeks ], :order => "last_event_time")
+ @holding_pen_messages = InfoRequest.holding_pen_request.incoming_messages
end
def timeline
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index 02481a9aa..adbcdc9e9 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.13 2008-05-19 12:01:21 francis Exp $
+# $Id: admin_request_controller.rb,v 1.14 2008-07-08 09:41:04 francis Exp $
class AdminRequestController < ApplicationController
layout "admin"
@@ -104,19 +104,12 @@ class AdminRequestController < ApplicationController
def destroy_incoming
@incoming_message = IncomingMessage.find(params[:incoming_message_id])
- @info_request_event = InfoRequestEvent.find_by_incoming_message_id(@incoming_message.id)
@info_request = @incoming_message.info_request
raw_data = @incoming_message
incoming_message_id = @incoming_message.id
- ActiveRecord::Base.transaction do
- @info_request_event.track_things_sent_emails.each { |a| a.destroy }
- @info_request_event.user_info_request_sent_alerts.each { |a| a.destroy }
- @info_request_event.destroy
- @incoming_message.destroy
- end
-
+ @incoming_message.fully_destroy
@incoming_message.info_request.log_event("destroy_incoming",
{ :editor => admin_http_auth_user(), :raw_data => raw_data })
@@ -124,6 +117,31 @@ class AdminRequestController < ApplicationController
redirect_to request_admin_url(@info_request)
end
+ def redeliver_incoming
+ incoming_message = IncomingMessage.find(params[:redeliver_incoming_message_id])
+
+ if params[:url_title].match(/^[0-9]+$/)
+ destination_request = InfoRequest.find(params[:url_title].to_i)
+ else
+ destination_request = InfoRequest.find_by_url_title(params[:url_title])
+ end
+
+ if destination_request.nil?
+ flash[:error] = "Failed to find destination request '" + params[:url_title] + "'"
+ redirect_to request_admin_url(incoming_message.info_request)
+ end
+
+ raw_email = incoming_message.raw_data
+ mail = TMail::Mail.parse(raw_email)
+ mail.base64_decode
+ destination_request.receive(mail, raw_email)
+
+ incoming_message.fully_destroy
+
+ flash[:notice] = "Message has been moved to this request"
+ redirect_to request_admin_url(destination_request)
+ end
+
private
end
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index e27613a48..390467bb5 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -18,7 +18,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: incoming_message.rb,v 1.116 2008-06-25 19:53:55 francis Exp $
+# $Id: incoming_message.rb,v 1.117 2008-07-08 09:41:04 francis Exp $
# TODO
# Move some of the (e.g. quoting) functions here into rblib, as they feel
@@ -688,6 +688,16 @@ class IncomingMessage < ActiveRecord::Base
def recently_arrived
(Time.now - self.created_at) <= 3.days
end
+
+ def fully_destroy
+ ActiveRecord::Base.transaction do
+ info_request_event = InfoRequestEvent.find_by_incoming_message_id(self.id)
+ info_request_event.track_things_sent_emails.each { |a| a.destroy }
+ info_request_event.user_info_request_sent_alerts.each { |a| a.destroy }
+ info_request_event.destroy
+ self.destroy
+ end
+ end
end
diff --git a/app/models/info_request.rb b/app/models/info_request.rb
index 33fc87357..e174dff7b 100644
--- a/app/models/info_request.rb
+++ b/app/models/info_request.rb
@@ -22,7 +22,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: info_request.rb,v 1.117 2008-06-11 15:00:35 francis Exp $
+# $Id: info_request.rb,v 1.118 2008-07-08 09:41:04 francis Exp $
require 'digest/sha1'
require File.join(File.dirname(__FILE__),'../../vendor/plugins/acts_as_xapian/lib/acts_as_xapian')
@@ -242,6 +242,34 @@ public
RequestMailer.deliver_new_response(self, incoming_message)
end
+ # The "holding pen" is a special request which stores incoming emails whose
+ # destination request is unknown.
+ def InfoRequest.holding_pen_request
+ ir = InfoRequest.find_by_url_title("holding_pen")
+ if ir.nil?
+ ir = InfoRequest.new(
+ :user => User.internal_admin_user,
+ :public_body => PublicBody.internal_admin_body,
+ :title => 'Holding pen',
+ :described_state => 'waiting_response',
+ :awaiting_description => false,
+ :prominence => 'backpage'
+ )
+ om = OutgoingMessage.new({
+ :status => 'ready',
+ :message_type => 'initial_request',
+ :body => 'This is the holding pen request. It shows responses that were sent to invalid addresses, and need moving to the correct request by an adminstrator.',
+ :last_sent_at => Time.now()
+ })
+ ir.outgoing_messages << om
+ om.info_request = ir
+ ir.save!
+ ir.log_event('sent', { :outgoing_message_id => om.id, :email => ir.public_body.request_email })
+ end
+
+ return ir
+ end
+
# Change status, including for last event for later historical purposes
def set_described_state(new_state)
ActiveRecord::Base.transaction do
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 5e7a9dd27..6745ede64 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -21,7 +21,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.79 2008-06-23 23:35:21 francis Exp $
+# $Id: public_body.rb,v 1.80 2008-07-08 09:41:04 francis Exp $
require 'csv'
require 'set'
@@ -193,6 +193,23 @@ class PublicBody < ActiveRecord::Base
end
end
+ # The "internal admin" is a special body for internal use.
+ def PublicBody.internal_admin_body
+ pb = PublicBody.find_by_url_name("internal_admin_authority")
+ if pb.nil?
+ pb = PublicBody.new(
+ :name => 'Internal admin authority',
+ :short_name => "",
+ :request_email => MySociety::Config.get("CONTACT_EMAIL", 'contact@localhost'),
+ :last_edit_editor => "internal_admin",
+ :last_edit_comment => "Made by PublicBody.internal_admin_body"
+ )
+ pb.save!
+ end
+
+ return pb
+ end
+
class ImportCSVDryRun < StandardError
end
diff --git a/app/models/request_mailer.rb b/app/models/request_mailer.rb
index a61a444e8..9c206d6f7 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.37 2008-06-13 09:15:44 francis Exp $
+# $Id: request_mailer.rb,v 1.38 2008-07-08 09:41:04 francis Exp $
class RequestMailer < ApplicationMailer
@@ -154,9 +154,10 @@ class RequestMailer < ApplicationMailer
reply_info_requests.push(reply_info_request) if reply_info_request
end
- # Nothing found
+ # Nothing found, so save in holding pen
if reply_info_requests.size == 0
- RequestMailer.deliver_bounced_message(email)
+ InfoRequest.holding_pen_request.receive(email, raw_email)
+ #RequestMailer.deliver_bounced_message(email)
return
end
diff --git a/app/models/user.rb b/app/models/user.rb
index cb0b6b867..aa7014a54 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -21,7 +21,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: user.rb,v 1.56 2008-05-21 10:51:24 francis Exp $
+# $Id: user.rb,v 1.57 2008-07-08 09:41:04 francis Exp $
require 'digest/sha1'
@@ -133,6 +133,25 @@ class User < ActiveRecord::Base
return self.name + " <" + self.email + ">"
end
+ # The "internal admin" is a special user for internal use.
+ def User.internal_admin_user
+ contact_email = MySociety::Config.get("CONTACT_EMAIL", 'contact@localhost')
+ u = User.find_by_email(contact_email)
+ if u.nil?
+ password = PostRedirect.generate_random_token
+ u = User.new(
+ :name => 'Internal admin user',
+ :email => contact_email,
+ :password => password,
+ :password_confirmation => password
+ )
+ u.save!
+ end
+
+ return u
+ end
+
+
private
def self.encrypted_password(password, salt)
diff --git a/app/views/admin/index.rhtml b/app/views/admin/index.rhtml
index b41ca78c4..18f61eab9 100644
--- a/app/views/admin/index.rhtml
+++ b/app/views/admin/index.rhtml
@@ -13,6 +13,20 @@
<h1>Things to do</h1>
+<% if @holding_pen_messages.size > 0 %>
+ <h3>Put misdelivered responses with the right request</h3>
+
+ <ul>
+ <% for message in @holding_pen_messages %>
+ <li>
+ <%= link_to excerpt(message.get_body_for_quoting, "", 60), "request/show/" + InfoRequest.holding_pen_request.id.to_s + "#incoming-" + message.id.to_s %>
+ (<%=simple_date(message.sent_at)%>)
+ </li>
+ <% end %>
+ </ul>
+
+<% end %>
+
<% if @one_week_old_unclassified.size > 0 %>
<h3>Classify responses that are still unclassified one week after response</h3>
diff --git a/app/views/admin_request/show.rhtml b/app/views/admin_request/show.rhtml
index 0099730cf..91b0646a4 100644
--- a/app/views/admin_request/show.rhtml
+++ b/app/views/admin_request/show.rhtml
@@ -79,7 +79,7 @@
</tr>
<% for incoming_message in @info_request.incoming_messages.find(:all, :order => 'created_at') %>
- <tr class="<%= cycle('odd', 'even') %>">
+ <tr class="<%= cycle('odd', 'even') %>" id="incoming-<%=incoming_message.id.to_s%>">
<td><%=h incoming_message.id %></td>
<% for column in IncomingMessage.content_columns.map { |c| c.name } %>
<% if column == 'raw_data' %>
@@ -90,12 +90,20 @@
<% end %>
<td>
<% form_tag '../destroy_incoming' do %>
- <div>
- <%= hidden_field_tag 'incoming_message_id', incoming_message.id %>
- <%= submit_tag "Destroy" %>
- </div>
- <% end %>
+ <div>
+ <%= hidden_field_tag 'incoming_message_id', incoming_message.id %>
+ <%= submit_tag "Destroy message" %>
+ </div>
+ <% end %>
+ <% form_tag '../redeliver_incoming' do %>
+ <div>
+ id or url_title of request:
+ <%= text_field_tag 'url_title', "", { :size => 20 } %>
+ <%= hidden_field_tag 'redeliver_incoming_message_id', incoming_message.id %>
+ <%= submit_tag "Redeliver to another request" %>
+ </div>
+ <% end %>
</td>
</tr>
<% end %>
diff --git a/app/views/layouts/admin.rhtml b/app/views/layouts/admin.rhtml
index 70da268eb..3c79b776e 100644
--- a/app/views/layouts/admin.rhtml
+++ b/app/views/layouts/admin.rhtml
@@ -23,6 +23,10 @@
| <%= link_to 'Tracks', admin_url('track/list') %>
</p>
+ <% if flash[:error] %>
+ <p id="error"><%= flash[:error] %></p>
+ <% end %>
+
<% if flash[:notice] %>
<p id="notice"><%= flash[:notice] %></p>
<% end %>
diff --git a/spec/models/request_mailer_spec.rb b/spec/models/request_mailer_spec.rb
index 98c27cca9..2a882b7c7 100644
--- a/spec/models/request_mailer_spec.rb
+++ b/spec/models/request_mailer_spec.rb
@@ -13,12 +13,19 @@ describe RequestMailer, " when receiving incoming mail" do
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email)
ir.incoming_messages.size.should == 2 # one more arrives
ir.info_request_events[-1].incoming_message_id.should_not be_nil
+
+ deliveries = ActionMailer::Base.deliveries
+ deliveries.size.should == 1
+ deliveries.clear
end
- it "should bounce email to admin when the email is not to any information request" do
+ it "should store mail in holding pen and send to admin when the email is not to any information request" do
ir = info_requests(:fancy_dog_request)
+ ir.incoming_messages.size.should == 1
+ InfoRequest.holding_pen_request.incoming_messages.size.should == 0
receive_incoming_mail('incoming-request-plain.email', 'dummy@localhost')
ir.incoming_messages.size.should == 1
+ InfoRequest.holding_pen_request.incoming_messages.size.should == 1
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
diff --git a/todo.txt b/todo.txt
index 10407272b..ddf7c1c2a 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,7 @@
Site move:
Install PostgresSQL 8.3
Move database
+ Move email foibackup to a new server
FOI requests (that need action)
============
@@ -29,6 +30,9 @@ pages.
Next
====
+Add ppt icon
+http://www.whatdotheyknow.com/request/presentations_made_at_climate_ch#incoming-1773
+
This infers the wrong calculated state due to followups
https://secure.mysociety.org/admin/foi/request/show/619
@@ -162,6 +166,9 @@ Quoting fixing TODO:
http://www.whatdotheyknow.com/request/364/response/1100
http://www.whatdotheyknow.com/request/council_housing_accommodation # over zealous half cuts
http://www.whatdotheyknow.com/request/621/response/1131 # virus footer
+ http://www.whatdotheyknow.com/request/231/response/338
+
+ http://www.whatdotheyknow.com/request/415/response/1041/attach/3/CONF%20FOI%209508%20Ian%20Holton.doc
Larger new features
-------------------