diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/incoming_message.rb | 2 | ||||
-rw-r--r-- | app/models/info_request.rb | 46 | ||||
-rw-r--r-- | app/models/info_request_event.rb | 2 | ||||
-rw-r--r-- | app/models/public_body.rb | 11 | ||||
-rw-r--r-- | app/models/raw_email.rb | 15 | ||||
-rw-r--r-- | app/models/request_mailer.rb | 22 |
6 files changed, 80 insertions, 18 deletions
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb index 3419956d6..593590fb8 100644 --- a/app/models/incoming_message.rb +++ b/app/models/incoming_message.rb @@ -344,7 +344,7 @@ class IncomingMessage < ActiveRecord::Base # Lotus notes quoting yeuch! def remove_lotus_quoting(text, replacement = "FOLDED_QUOTED_SECTION") text = text.dup - name = Regexp.escape(self.info_request.user.name) + name = Regexp.escape(self.info_request.user_name) # To end of message sections # http://www.whatdotheyknow.com/request/university_investment_in_the_arm diff --git a/app/models/info_request.rb b/app/models/info_request.rb index 45819bfe7..d09acbcf6 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -33,7 +33,7 @@ class InfoRequest < ActiveRecord::Base validates_format_of :title, :with => /[a-zA-Z]/, :message => N_("Please write a summary with some text in it"), :if => Proc.new { |info_request| !info_request.title.nil? && !info_request.title.empty? } belongs_to :user - #validates_presence_of :user_id # breaks during construction of new ones :( + validate :must_be_internal_or_external belongs_to :public_body validates_presence_of :public_body_id @@ -104,6 +104,43 @@ class InfoRequest < ActiveRecord::Base errors.add(:described_state, "is not a valid state") if !InfoRequest.enumerate_states.include? described_state end + + # The request must either be internal, in which case it has + # a foreign key reference to a User object and no external_url or external_user_name, + # or else be external in which case it has no user_id but does have an external_url, + # and may optionally also have an external_user_name. + # + # External requests are requests that have been added using the API, whereas internal + # requests are requests made using the site. + def must_be_internal_or_external + # We must permit user_id and external_user_name both to be nil, because the system + # allows a request to be created by a non-logged-in user. + if !user_id.nil? + errors.add(:external_user_name, "must be null for an internal request") if !external_user_name.nil? + errors.add(:external_url, "must be null for an internal request") if !external_url.nil? + end + end + + def is_external? + !external_url.nil? + end + + def user_name + is_external? ? external_user_name : user.name + end + + def user_name_slug + if is_external? + if external_user_name.nil? + fake_slug = "anonymous" + else + fake_slug = external_user_name.parameterize + end + public_body.url_name + "_"+fake_slug + else + user.url_name + end + end @@custom_states_loaded = false begin @@ -232,7 +269,7 @@ public return self.magic_email("request-") end def incoming_name_and_email - return TMail::Address.address_from_name_and_email(self.user.name, self.incoming_email).to_s + return TMail::Address.address_from_name_and_email(self.user_name, self.incoming_email).to_s end # Subject lines for emails about the request @@ -453,7 +490,7 @@ public self.save! end self.info_request_events.each { |event| event.xapian_mark_needs_index } # for the "waiting_classification" index - RequestMailer.deliver_new_response(self, incoming_message) + RequestMailer.deliver_new_response(self, incoming_message) if !is_external? end @@ -515,9 +552,6 @@ public return false end - def can_have_attention_requested? - end - # change status, including for last event for later historical purposes def set_described_state(new_state, set_by = nil) ActiveRecord::Base.transaction do diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb index 9a4f6d9fe..a827d19a4 100644 --- a/app/models/info_request_event.rb +++ b/app/models/info_request_event.rb @@ -118,7 +118,7 @@ class InfoRequestEvent < ActiveRecord::Base :eager_load => [ :outgoing_message, :comment, { :info_request => [ :user, :public_body, :censor_rules ] } ] def requested_by - self.info_request.user.url_name + self.info_request.user_name_slug end def requested_from # acts_as_xapian will detect translated fields via Globalize and add all the diff --git a/app/models/public_body.rb b/app/models/public_body.rb index 267b5d60c..a372de435 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -17,6 +17,7 @@ # notes :text default(""), not null # first_letter :string(255) not null # publication_scheme :text default(""), not null +# api_key :string(255) not null # # models/public_body.rb: @@ -28,6 +29,7 @@ # $Id: public_body.rb,v 1.160 2009-10-02 22:56:35 francis Exp $ require 'csv' +require 'securerandom' require 'set' class PublicBody < ActiveRecord::Base @@ -87,10 +89,13 @@ class PublicBody < ActiveRecord::Base end end - # Make sure publication_scheme gets the correct default value. - # (This would work automatically, were publication_scheme not a translated attribute) def after_initialize + # Make sure publication_scheme gets the correct default value. + # (This would work automatically, were publication_scheme not a translated attribute) self.publication_scheme = "" if self.publication_scheme.nil? + + # Set an API key if there isn’t one + self.api_key = SecureRandom.base64(32) if self.api_key.nil? end # like find_by_url_name but also search historic url_name if none found @@ -178,7 +183,7 @@ class PublicBody < ActiveRecord::Base end acts_as_versioned - self.non_versioned_columns << 'created_at' << 'updated_at' << 'first_letter' + self.non_versioned_columns << 'created_at' << 'updated_at' << 'first_letter' << 'api_key' class Version attr_accessor :created_at diff --git a/app/models/raw_email.rb b/app/models/raw_email.rb index 1466e5d9c..3bb794684 100644 --- a/app/models/raw_email.rb +++ b/app/models/raw_email.rb @@ -19,13 +19,12 @@ class RawEmail < ActiveRecord::Base has_one :incoming_message - # We keep the old data_text field (which is of type text) for backwards - # compatibility. We use the new data_binary field because only it works - # properly in recent versions of PostgreSQL (get seg faults escaping - # some binary strings). - def directory request_id = self.incoming_message.info_request.id.to_s + if request_id.empty? + raise "Failed to find the id number of the associated request: has it been saved?" + end + if ENV["RAILS_ENV"] == "test" return File.join(Rails.root, 'files/raw_email_test') else @@ -36,7 +35,11 @@ class RawEmail < ActiveRecord::Base end def filepath - File.join(self.directory, self.incoming_message.id.to_s) + incoming_message_id = self.incoming_message.id.to_s + if incoming_message_id.empty? + raise "Failed to find the id number of the associated incoming message: has it been saved?" + end + File.join(self.directory, incoming_message_id) end def data=(d) diff --git a/app/models/request_mailer.rb b/app/models/request_mailer.rb index 1b0bb48b9..03d26f237 100644 --- a/app/models/request_mailer.rb +++ b/app/models/request_mailer.rb @@ -28,6 +28,21 @@ class RequestMailer < ApplicationMailer :filename => attachment_name end end + + # Used when a response is uploaded using the API + def external_response(info_request, body, sent_at, attachments) + @from = blackhole_email + @recipients = info_request.incoming_name_and_email + @body = { :body => body } + + # ActionMailer only works properly when the time is in the local timezone: + # see https://rails.lighthouseapp.com/projects/8994/tickets/3113-actionmailer-only-works-correctly-with-sent_on-times-that-are-in-the-local-time-zone + @sent_on = sent_at.dup.localtime + + attachments.each do |attachment_hash| + attachment attachment_hash + end + end # Incoming message arrived for a request, but new responses have been stopped. def stopped_responses(info_request, email, raw_email_data) @@ -241,7 +256,12 @@ class RequestMailer < ApplicationMailer # Send email alerts for overdue requests def self.alert_overdue_requests() - info_requests = InfoRequest.find(:all, :conditions => [ "described_state = 'waiting_response' and awaiting_description = ?", false ], :include => [ :user ] ) + info_requests = InfoRequest.find(:all, + :conditions => [ + "described_state = 'waiting_response' and awaiting_description = ? and user_id is not null", false + ], + :include => [ :user ] + ) for info_request in info_requests alert_event_id = info_request.last_event_forming_initial_request.id # Only overdue requests |