aboutsummaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/incoming_message.rb54
-rw-r--r--app/models/info_request.rb18
-rw-r--r--app/models/info_request_event.rb32
-rw-r--r--app/models/public_body.rb49
-rw-r--r--app/models/request_mailer.rb24
-rw-r--r--app/models/track_mailer.rb12
-rw-r--r--app/models/track_thing.rb81
-rw-r--r--app/models/user.rb39
-rw-r--r--app/models/user_mailer.rb2
9 files changed, 194 insertions, 117 deletions
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index 16ae38b92..2b795ddf5 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(" ")
@@ -1305,10 +1304,15 @@ class IncomingMessage < ActiveRecord::Base
prefix = email
prefix =~ /^(.*)@/
prefix = $1
- if !prefix.nil? && prefix.downcase.match(/^(postmaster|mailer-daemon|auto_reply|donotreply|no.reply)$/)
+ if !prefix.nil? && prefix.downcase.match(/^(postmaster|mailer-daemon|auto_reply|do.?not.?reply|no.reply)$/)
+ return false
+ end
+ if !self.mail['return-path'].nil? && self.mail['return-path'].addr == "<>"
+ return false
+ end
+ if !self.mail['auto-submitted'].nil? && !self.mail['auto-submitted'].keys.empty?
return false
end
-
return true
end
@@ -1336,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/models/info_request.rb b/app/models/info_request.rb
index 9b0f1047b..92322f74f 100644
--- a/app/models/info_request.rb
+++ b/app/models/info_request.rb
@@ -117,13 +117,13 @@ class InfoRequest < ActiveRecord::Base
# only check on create, so existing models with mixed case are allowed
def validate_on_create
if !self.title.nil? && !MySociety::Validate.uses_mixed_capitals(self.title, 10)
- errors.add(:title, N_('Please write the summary using a mixture of capital and lower case letters. This makes it easier for others to read.'))
+ errors.add(:title, _('Please write the summary using a mixture of capital and lower case letters. This makes it easier for others to read.'))
end
if !self.title.nil? && title.size > 200
- errors.add(:title, N_('Please keep the summary short, like in the subject of an email. You can use a phrase, rather than a full sentence.'))
+ errors.add(:title, _('Please keep the summary short, like in the subject of an email. You can use a phrase, rather than a full sentence.'))
end
if !self.title.nil? && self.title =~ /^(FOI|Freedom of Information)\s*requests?$/i
- errors.add(:title, N_('Please describe more what the request is about in the subject. There is no need to say it is an FOI request, we add that on anyway.'))
+ errors.add(:title, _('Please describe more what the request is about in the subject. There is no need to say it is an FOI request, we add that on anyway.'))
end
end
@@ -780,8 +780,7 @@ public
# Display version of status
- def display_status
- status = self.calculate_status
+ def InfoRequest.get_status_description(status)
if status == 'waiting_classification'
_("Awaiting classification.")
elsif status == 'waiting_response'
@@ -819,6 +818,10 @@ public
end
end
+ def display_status
+ InfoRequest.get_status_description(self.calculate_status)
+ end
+
# Completely delete this request and all objects depending on it
def fully_destroy
self.track_things.each do |track_thing|
@@ -919,10 +922,13 @@ public
end
# List of incoming messages to followup, by unique email
- def who_can_followup_to
+ def who_can_followup_to(skip_message = nil)
ret = []
done = {}
for incoming_message in self.incoming_messages.reverse
+ if incoming_message == skip_message
+ next
+ end
incoming_message.safe_mail_from
email = OutgoingMailer.email_for_followup(self, incoming_message)
diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb
index 4003217b0..4ea89bf81 100644
--- a/app/models/info_request_event.rb
+++ b/app/models/info_request_event.rb
@@ -303,37 +303,7 @@ class InfoRequestEvent < ActiveRecord::Base
def display_status
if is_incoming_message?
status = self.calculated_state
- if !status.nil?
- if status == 'waiting_response'
- return _("Acknowledgement")
- elsif status == 'waiting_clarification'
- return _("Clarification required")
- elsif status == 'gone_postal'
- return _("Handled by post")
- elsif status == 'deadline_extended'
- return _("Deadline Extended")
- elsif status == 'wrong_response'
- return _("Wrong Response")
- elsif status == 'not_held'
- return _("Information not held")
- elsif status == 'rejected'
- return _("Refused")
- elsif status == 'partially_successful'
- return _("Some information sent")
- elsif status == 'successful'
- return _("All information sent")
- elsif status == 'internal_review'
- return _("Internal review acknowledgement")
- elsif status == 'user_withdrawn'
- return _("Withdrawn by requester")
- elsif status == 'error_message'
- return _("Delivery error")
- elsif status == 'requires_admin'
- return _("Unusual response")
- end
- raise "unknown status " + status
- end
- return "Response"
+ return status.nil? ? _("Response") : InfoRequest.get_status_description(status)
end
if is_outgoing_message?
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 81149e3c2..311e19001 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -112,16 +112,6 @@ class PublicBody < ActiveRecord::Base
end
end
- # XXX this should be saner; probably implement categories as data
- begin
- load "public_body_categories_#{I18n.locale.to_s}.rb"
- rescue MissingSourceFile
- begin
- load "public_body_categories_#{I18n.default_locale.to_s}.rb"
- rescue MissingSourceFile
- load "public_body_categories.rb"
- end
- end
# Set the first letter, which is used for faster queries
before_save(:set_first_letter)
def set_first_letter
@@ -255,8 +245,8 @@ class PublicBody < ActiveRecord::Base
types = []
first = true
for tag in self.tags
- if PublicBodyCategories::CATEGORIES_BY_TAG.include?(tag.name)
- desc = PublicBodyCategories::CATEGORY_SINGULAR_BY_TAG[tag.name]
+ if PublicBodyCategories::get().by_tag().include?(tag.name)
+ desc = PublicBodyCategories::get().singular_by_tag()[tag.name]
if first
# terrible that Ruby/Rails doesn't have an equivalent of ucfirst
# (capitalize shockingly converts later characters to lowercase)
@@ -344,7 +334,7 @@ class PublicBody < ActiveRecord::Base
# Import from CSV. Just tests things and returns messages if dry_run is true.
# Returns an array of [array of errors, array of notes]. If there are errors,
# always rolls back (as with dry_run).
- def self.import_csv(csv, tag, dry_run, editor, available_locales = [])
+ def self.import_csv(csv, tag, tag_behaviour, dry_run, editor, available_locales = [])
errors = []
notes = []
available_locales = [I18n.default_locale] if available_locales.empty?
@@ -357,7 +347,11 @@ class PublicBody < ActiveRecord::Base
bodies_by_name = {}
set_of_existing = Set.new()
PublicBody.with_locale(I18n.default_locale) do
- for existing_body in PublicBody.find_by_tag(tag)
+ bodies = (tag.nil? || tag.empty?) ? PublicBody.find(:all) : PublicBody.find_by_tag(tag)
+ for existing_body in bodies
+ # Hide InternalAdminBody from import notes
+ next if existing_body.id == PublicBody.internal_admin_body.id
+
bodies_by_name[existing_body.name] = existing_body
set_of_existing.add(existing_body.name)
end
@@ -391,15 +385,28 @@ class PublicBody < ActiveRecord::Base
next
end
- field_list = ['name', 'short_name', 'request_email', 'notes', 'publication_scheme', 'home_page']
+ field_list = ['name', 'short_name', 'request_email', 'notes', 'publication_scheme', 'home_page', 'tag_string']
- if public_body = bodies_by_name[name]
+ if public_body = bodies_by_name[name] # Existing public body
available_locales.each do |locale|
PublicBody.with_locale(locale) do
changed = {}
field_list.each do |field_name|
localized_field_name = (locale === I18n.default_locale) ? field_name : "#{field_name}.#{locale}"
localized_value = field_names[localized_field_name] && row[field_names[localized_field_name]]
+
+ # Tags are a special case, as we support adding to the field, not just setting a new value
+ if localized_field_name == 'tag_string'
+ if localized_value.nil?
+ localized_value = tag unless tag.empty?
+ else
+ if tag_behaviour == 'add'
+ localized_value = "#{localized_value} #{tag}" unless tag.empty?
+ localized_value = "#{localized_value} #{public_body.tag_string}"
+ end
+ end
+ end
+
if !localized_value.nil? and public_body.send(field_name) != localized_value
changed[field_name] = "#{public_body.send(field_name)}: #{localized_value}"
public_body.send("#{field_name}=", localized_value)
@@ -422,6 +429,11 @@ class PublicBody < ActiveRecord::Base
field_list.each do |field_name|
localized_field_name = (locale === I18n.default_locale) ? field_name : "#{field_name}.#{locale}"
localized_value = field_names[localized_field_name] && row[field_names[localized_field_name]]
+
+ if localized_field_name == 'tag_string' and tag_behaviour == 'add'
+ localized_value = "#{localized_value} #{tag}" unless tag.empty?
+ end
+
if !localized_value.nil? and public_body.send(field_name) != localized_value
changed[field_name] = localized_value
public_body.send("#{field_name}=", localized_value)
@@ -431,7 +443,6 @@ class PublicBody < ActiveRecord::Base
unless changed.empty?
notes.push "line #{line.to_s}: creating new authority '#{name}' (locale: #{locale}):\n\t#{changed.to_json}"
public_body.publication_scheme = public_body.publication_scheme || ""
- public_body.tag_string = tag
public_body.last_edit_editor = editor
public_body.last_edit_comment = 'Created from spreadsheet'
public_body.save!
@@ -446,7 +457,7 @@ class PublicBody < ActiveRecord::Base
# Give an error listing ones that are to be deleted
deleted_ones = set_of_existing - set_of_importing
if deleted_ones.size > 0
- notes.push "notes: Some " + tag + " bodies are in database, but not in CSV file:\n " + Array(deleted_ones).join("\n ") + "\nYou may want to delete them manually.\n"
+ notes.push "Notes: Some " + tag + " bodies are in database, but not in CSV file:\n " + Array(deleted_ones).join("\n ") + "\nYou may want to delete them manually.\n"
end
# Rollback if a dry run, or we had errors
@@ -515,7 +526,7 @@ class PublicBody < ActiveRecord::Base
end
def notes_without_html
# assume notes are reasonably behaved HTML, so just use simple regexp on this
- self.notes.gsub(/<\/?[^>]*>/, "")
+ self.notes.nil? ? '' : self.notes.gsub(/<\/?[^>]*>/, "")
end
def json_for_api
diff --git a/app/models/request_mailer.rb b/app/models/request_mailer.rb
index e244aaac9..f46ce33c5 100644
--- a/app/models/request_mailer.rb
+++ b/app/models/request_mailer.rb
@@ -61,7 +61,8 @@ class RequestMailer < ApplicationMailer
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = info_request.user.name_and_email
@subject = "New response to your FOI request - " + info_request.title
@body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
@@ -79,7 +80,8 @@ class RequestMailer < ApplicationMailer
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = user.name_and_email
@subject = "Delayed response to your FOI request - " + info_request.title
@body = { :info_request => info_request, :url => url }
@@ -97,7 +99,8 @@ class RequestMailer < ApplicationMailer
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = user.name_and_email
@subject = "You're long overdue a response to your FOI request - " + info_request.title
@body = { :info_request => info_request, :url => url }
@@ -116,7 +119,8 @@ class RequestMailer < ApplicationMailer
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = info_request.user.name_and_email
@subject = "Was the response you got to your FOI request any good?"
@body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
@@ -126,7 +130,8 @@ class RequestMailer < ApplicationMailer
def old_unclassified_updated(info_request)
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = info_request.user.name_and_email
@subject = "Someone has updated the status of your request"
url = main_url(request_url(info_request))
@@ -146,7 +151,8 @@ class RequestMailer < ApplicationMailer
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = info_request.user.name_and_email
@subject = "Clarify your FOI request - " + info_request.title
@body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
@@ -156,7 +162,8 @@ class RequestMailer < ApplicationMailer
def comment_on_alert(info_request, comment)
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = info_request.user.name_and_email
@subject = "Somebody added a note to your FOI request - " + info_request.title
@body = { :comment => comment, :info_request => info_request, :url => main_url(comment_url(comment)) }
@@ -164,7 +171,8 @@ class RequestMailer < ApplicationMailer
def comment_on_alert_plural(info_request, count, earliest_unalerted_comment)
@from = contact_from_name_and_email
headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
- 'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
+ 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'X-Auto-Response-Suppress' => 'OOF'
@recipients = info_request.user.name_and_email
@subject = "Some notes have been added to your FOI request - " + info_request.title
@body = { :count => count, :info_request => info_request, :url => main_url(comment_url(earliest_unalerted_comment)) }
diff --git a/app/models/track_mailer.rb b/app/models/track_mailer.rb
index 4b7c603a7..85b1fedd8 100644
--- a/app/models/track_mailer.rb
+++ b/app/models/track_mailer.rb
@@ -26,6 +26,12 @@ class TrackMailer < ApplicationMailer
@body = { :user => user, :email_about_things => email_about_things, :unsubscribe_url => unsubscribe_url }
end
+ def contact_from_name_and_email
+ contact_name = MySociety::Config.get("TRACK_SENDER_NAME", 'Alaveteli')
+ contact_email = MySociety::Config.get("TRACK_SENDER_EMAIL", 'contact@localhost')
+ return "#{contact_name} <#{contact_email}>"
+ end
+
# Send email alerts for tracked things. Never more than one email
# a day, nor about events which are more than a week old, nor
# events about which emails have been sent within the last two
@@ -40,6 +46,8 @@ class TrackMailer < ApplicationMailer
return false
end
for user in users
+ next if !user.should_be_emailed?
+
email_about_things = []
track_things = TrackThing.find(:all, :conditions => [ "tracking_user_id = ? and track_medium = ?", user.id, 'email_daily' ])
for track_thing in track_things
@@ -85,7 +93,11 @@ class TrackMailer < ApplicationMailer
# If we have anything to send, then send everything for the user in one mail
if email_about_things.size > 0
# Send the email
+
+ previous_locale = I18n.locale
+ I18n.locale = user.get_locale
TrackMailer.deliver_event_digest(user, email_about_things)
+ I18n.locale = previous_locale
end
# Record that we've now sent those alerts to that user
diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb
index 1cd957549..b74f7dad5 100644
--- a/app/models/track_thing.rb
+++ b/app/models/track_thing.rb
@@ -22,6 +22,7 @@
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
# $Id: track_thing.rb,v 1.53 2009-09-17 21:10:05 francis Exp $
+require 'set'
class TrackThing < ActiveRecord::Base
belongs_to :tracking_user, :class_name => 'User'
@@ -67,6 +68,63 @@ class TrackThing < ActiveRecord::Base
TrackThing.track_type_description(self.track_type)
end
+ def track_query_description
+ # XXX this is very brittle... we should probably ask users
+ # simply to name their tracks when they make them?
+ self.track_query = self.track_query.gsub(/([()]|OR)/, "")
+ filters = self.track_query.scan /\b\S+:\S+\b/
+ text = self.track_query
+ varieties = Set.new
+ date = ""
+ statuses = Set.new
+ for filter in filters
+ text = text.sub(filter, "")
+ if filter =~ /variety:user/
+ varieties << _("users")
+ end
+ if filter =~ /variety:comment/
+ varieties << _("comments")
+ end
+ if filter =~ /variety:authority/
+ varieties << _("authorities")
+ end
+ if filter =~ /(variety:(sent|followup_sent|response)|latest_status)/
+ varieties << _("requests")
+ end
+ if filter =~ /[0-9\/]+\.\.[0-9\/]+/
+ date = _("between two dates")
+ end
+ if filter =~ /(rejected|not_held)/
+ statuses << _("unsuccessful")
+ end
+ if filter =~ /(:successful|:partially_successful)/
+ statuses << _("successful")
+ end
+ if filter =~ /waiting/
+ statuses << _("awaiting a response")
+ end
+ end
+ if filters.empty?
+ text = self.track_query
+ end
+ descriptions = []
+ if varieties.include? _("requests")
+ descriptions << _("requests which are {{list_of_statuses}}", :list_of_statuses => Array(statuses).join(_(' or ')))
+ varieties -= [_("requests")]
+ end
+ if descriptions.empty? and varieties.empty?
+ varieties << _("anything")
+ end
+ descriptions += Array(varieties)
+ text = text.strip
+ descriptions = descriptions.join(_(" or "))
+ if !text.empty?
+ descriptions += _("{{list_of_things}} matching text '{{search_query}}'", :list_of_things => "", :search_query => text)
+ end
+ return descriptions
+ end
+
+
def TrackThing.create_track_for_request(info_request)
track_thing = TrackThing.new
track_thing.track_type = 'request_updates'
@@ -119,6 +177,11 @@ class TrackThing < ActiveRecord::Base
end
end
track_thing.track_query = query
+ # XXX should extract requested_by:, request:, requested_from:
+ # and stick their values into the respective relations.
+ # Should also update "params" to make the list_description
+ # nicer and more generic. It will need to do some clever
+ # parsing of the query to do this nicely
return track_thing
end
@@ -129,16 +192,16 @@ class TrackThing < ActiveRecord::Base
if self.track_type == 'request_updates'
@params = {
# Website
- :list_description => "'<a href=\"/request/" + CGI.escapeHTML(self.info_request.url_title) + "\">" + CGI.escapeHTML(self.info_request.title) + "</a>', a request", # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
+ :list_description => _("'{{link_to_request}}', a request", :link_to_request => "<a href=\"/request/" + CGI.escapeHTML(self.info_request.url_title) + "\">" + CGI.escapeHTML(self.info_request.title) + "</a>"), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
:verb_on_page => _("Track this request by email"),
:verb_on_page_already => _("You are already tracking this request by email"),
# Email
- :title_in_email => "New updates for the request '" + self.info_request.title + "'",
- :title_in_rss => "New updates for the request '" + self.info_request.title + "'",
+ :title_in_email => _("New updates for the request '{{request_title}}'", :request_title => self.info_request.title),
+ :title_in_rss => _("New updates for the request '{{request_title}}'", :request_title => self.info_request.title),
# Authentication
- :web => "To follow updates to the request '" + CGI.escapeHTML(self.info_request.title) + "'",
- :email => "Then you will be emailed whenever the request '" + CGI.escapeHTML(self.info_request.title) + "' is updated.",
- :email_subject => "Confirm you want to follow updates to the request '" + self.info_request.title + "'",
+ :web => _("To follow updates to the request '{{request_title}}'", :request_title => CGI.escapeHTML(self.info_request.title)),
+ :email => _("Then you will be emailed whenever the request '{{request_title}}' is updated.", :request_title => CGI.escapeHTML(self.info_request.title)),
+ :email_subject => _("Confirm you want to follow updates to the request '{{request_title}}'", :request_title => self.info_request.title),
# RSS sorting
:feed_sortby => 'newest'
}
@@ -180,7 +243,7 @@ class TrackThing < ActiveRecord::Base
elsif self.track_type == 'public_body_updates'
@params = {
# Website
- :list_description => "'<a href=\"/body/" + CGI.escapeHTML(self.public_body.url_name) + "\">" + CGI.escapeHTML(self.public_body.name) + "</a>', a public authority", # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
+ :list_description => _("'{{link_to_authority}}', a public authority", :link_to_authority => "<a href=\"/body/" + CGI.escapeHTML(self.public_body.url_name) + "\">" + CGI.escapeHTML(self.public_body.name) + "</a>"), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
:verb_on_page => _("Track requests to {{public_body_name}} by email",:public_body_name=>CGI.escapeHTML(self.public_body.name)),
:verb_on_page_already => _("You are already tracking requests to {{public_body_name}} by email", :public_body_name=>CGI.escapeHTML(self.public_body.name)),
# Email
@@ -196,7 +259,7 @@ class TrackThing < ActiveRecord::Base
elsif self.track_type == 'user_updates'
@params = {
# Website
- :list_description => "'<a href=\"/user/" + CGI.escapeHTML(self.tracked_user.url_name) + "\">" + CGI.escapeHTML(self.tracked_user.name) + "</a>', a person", # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
+ :list_description => _("'{{link_to_user}}', a person", :link_to_user => "<a href=\"/user/" + CGI.escapeHTML(self.tracked_user.url_name) + "\">" + CGI.escapeHTML(self.tracked_user.name) + "</a>"), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
:verb_on_page => _("Track this person by email"),
:verb_on_page_already => _("You are already tracking this person by email"),
# Email
@@ -212,7 +275,7 @@ class TrackThing < ActiveRecord::Base
elsif self.track_type == 'search_query'
@params = {
# Website
- :list_description => "'<a href=\"/search/" + CGI.escapeHTML(self.track_query) + "/newest\">" + CGI.escapeHTML(self.track_query) + "</a>' in new requests/responses", # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
+ :list_description => "<a href=\"/search/" + CGI.escapeHTML(self.track_query) + "/newest/advanced\">" + self.track_query_description + "</a>", # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how
:verb_on_page => _("Track things matching this search by email"),
:verb_on_page_already => _("You are already tracking things matching this search by email"),
# Email
diff --git a/app/models/user.rb b/app/models/user.rb
index fddb6b035..e98d777b1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -16,6 +16,8 @@
# admin_level :string(255) default("none"), not null
# ban_text :text default(""), not null
# about_me :text default(""), not null
+# email_bounced_at :datetime
+# email_bounce_message :text default(""), not null
#
# models/user.rb:
@@ -96,6 +98,15 @@ class User < ActiveRecord::Base
end
end
end
+
+ def get_locale
+ if !self.locale.nil?
+ locale = self.locale
+ else
+ locale = I18n.locale
+ end
+ return locale.to_s
+ end
def visible_comments
self.comments.find(:all, :conditions => 'visible')
@@ -341,15 +352,37 @@ class User < ActiveRecord::Base
}
end
+ def record_bounce(message)
+ self.email_bounced_at = Time.now
+ self.email_bounce_message = message
+ self.save!
+ end
+
+ def should_be_emailed?
+ return (self.email_confirmed && self.email_bounced_at.nil?)
+ end
+
+ ## Private instance methods
private
+ def create_new_salt
+ self.salt = self.object_id.to_s + rand.to_s
+ end
+
+ ## Class methods
def User.encrypted_password(password, salt)
string_to_hash = password + salt # XXX need to add a secret here too?
Digest::SHA1.hexdigest(string_to_hash)
end
-
- def create_new_salt
- self.salt = self.object_id.to_s + rand.to_s
+
+ def User.record_bounce_for_email(email, message)
+ user = User.find_user_by_email(email)
+ return false if user.nil?
+
+ if user.email_bounced_at.nil?
+ user.record_bounce(message)
+ end
+ return true
end
end
diff --git a/app/models/user_mailer.rb b/app/models/user_mailer.rb
index 0972e167d..7adf5b63c 100644
--- a/app/models/user_mailer.rb
+++ b/app/models/user_mailer.rb
@@ -46,7 +46,5 @@ class UserMailer < ApplicationMailer
@body[:old_email] = old_email
@body[:new_email] = new_email
end
-
-
end