diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/contact_validator.rb | 2 | ||||
-rw-r--r-- | app/models/foi_attachment.rb | 81 | ||||
-rw-r--r-- | app/models/info_request_batch.rb | 7 | ||||
-rw-r--r-- | app/models/public_body.rb | 43 | ||||
-rw-r--r-- | app/models/request_classification.rb | 4 | ||||
-rw-r--r-- | app/models/spam_address.rb | 21 | ||||
-rw-r--r-- | app/models/track_thing.rb | 137 | ||||
-rw-r--r-- | app/models/user.rb | 37 |
8 files changed, 147 insertions, 185 deletions
diff --git a/app/models/contact_validator.rb b/app/models/contact_validator.rb index 65e539669..e9a6e491c 100644 --- a/app/models/contact_validator.rb +++ b/app/models/contact_validator.rb @@ -7,7 +7,7 @@ class ContactValidator include ActiveModel::Validations - attr_accessor :name, :email, :subject, :message + attr_accessor :name, :email, :subject, :message, :comment validates_presence_of :name, :message => N_("Please enter your name") validates_presence_of :email, :message => N_("Please enter your email address") diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb index ecd4a1872..6f198249a 100644 --- a/app/models/foi_attachment.rb +++ b/app/models/foi_attachment.rb @@ -292,83 +292,10 @@ class FoiAttachment < ActiveRecord::Base end # For "View as HTML" of attachment - def body_as_html(dir) - html = nil - wrapper_id = "wrapper" - - # simple cases, can never fail - if self.content_type == 'text/plain' - text = self.body.strip - text = CGI.escapeHTML(text) - text = MySociety::Format.make_clickable(text) - html = text.gsub(/\n/, '<br>') - return '<!DOCTYPE html><html><head><title></title></head><body>' + html + "</body></html>", wrapper_id - end - - # the extractions will also produce image files, which go in the - # current directory, so change to the directory the function caller - # wants everything in - - html = nil - if ['application/pdf', 'application/rtf'].include?(self.content_type) - text = self.body - Dir.chdir(dir) do - if RUBY_VERSION.to_f >= 1.9 - tempfile = Tempfile.new('foiextract', '.', :encoding => text.encoding) - else - tempfile = Tempfile.new('foiextract', '.') - end - tempfile.print text - tempfile.flush - - - if self.content_type == 'application/pdf' - # We set a timeout here, because pdftohtml can spiral out of control - # on some PDF files and we don't want to crash the whole server. - html = AlaveteliExternalCommand.run("pdftohtml", "-nodrm", "-zoom", "1.0", "-stdout", "-enc", "UTF-8", "-noframes", tempfile.path, :timeout => 30) - elsif self.content_type == 'application/rtf' - html = AlaveteliExternalCommand.run("unrtf", "--html", tempfile.path, :timeout => 120) - end - - tempfile.close - tempfile.delete - end - end - if html.nil? - if self.has_google_docs_viewer? - html = '' # force error and using Google docs viewer - else - raise "No HTML conversion available for type " + self.content_type - end - end - - - - # We need to look at: - # a) Any error code - # b) The output size, as pdftohtml does not return an error code upon error. - # c) For cases when there is no text in the body of the HTML, or - # images, so nothing will be rendered. This is to detect some bug in - # pdftohtml, which sometimes makes it return just <hr>s and no other - # content. - html.match(/(\<body[^>]*\>.*)/mi) - body = $1.to_s - body_without_tags = body.gsub(/\s+/,"").gsub(/\<[^\>]*\>/, "") - contains_images = html.match(/<img/mi) ? true : false - if html.size == 0 || !$?.success? || (body_without_tags.size == 0 && !contains_images) - ret = "<html><head></head><body>"; - if self.has_google_docs_viewer? - wrapper_id = "wrapper_google_embed" - protocol = AlaveteliConfiguration::force_ssl ? 'https' : 'http' - ret = ret + "<iframe src='#{protocol}://docs.google.com/viewer?url=<attachment-url-here>&embedded=true' width='100%' height='100%' style='border: none;'></iframe>"; - else - ret = ret + "<p>Sorry, we were unable to convert this file to HTML. Please use the download link at the top right.</p>" - end - ret = ret + "</body></html>" - return ret, wrapper_id - end - - return html, wrapper_id + def body_as_html(dir, opts = {}) + attachment_url = opts.fetch(:attachment_url, nil) + to_html_opts = opts.merge(:tmpdir => dir, :attachment_url => attachment_url) + AttachmentToHTML.to_html(self, to_html_opts) end end diff --git a/app/models/info_request_batch.rb b/app/models/info_request_batch.rb index 498ab4951..d7c5eb9af 100644 --- a/app/models/info_request_batch.rb +++ b/app/models/info_request_batch.rb @@ -1,13 +1,14 @@ # == Schema Information -# Schema version: 20131024114346 # # Table name: info_request_batches # # id :integer not null, primary key # title :text not null # user_id :integer not null -# created_at :datetime -# updated_at :datetime +# created_at :datetime not null +# updated_at :datetime not null +# body :text +# sent_at :datetime # class InfoRequestBatch < ActiveRecord::Base diff --git a/app/models/public_body.rb b/app/models/public_body.rb index 7b1ded820..03ec270ee 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -6,7 +6,7 @@ # # id :integer not null, primary key # name :text not null -# short_name :text not null +# short_name :text default(""), not null # request_email :text not null # version :integer not null # last_edit_editor :string(255) not null @@ -37,7 +37,8 @@ class PublicBody < ActiveRecord::Base validates_presence_of :name, :message => N_("Name can't be blank") validates_presence_of :url_name, :message => N_("URL name can't be blank") - validates_uniqueness_of :short_name, :message => N_("Short name is already taken"), :if => Proc.new { |pb| pb.short_name != "" } + validates_uniqueness_of :short_name, :message => N_("Short name is already taken"), :allow_blank => true + validates_uniqueness_of :url_name, :message => N_("URL name is already taken") validates_uniqueness_of :name, :message => N_("Name is already taken") validate :request_email_if_requestable @@ -59,6 +60,34 @@ class PublicBody < ActiveRecord::Base translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme + # Public: Search for Public Bodies whose name, short_name, request_email or + # tags contain the given query + # + # query - String to query the searchable fields + # locale - String to specify the language of the seach query + # (default: I18n.locale) + # + # Returns an ActiveRecord::Relation + def self.search(query, locale = I18n.locale) + locale = locale.to_s.gsub('-', '_') # Clean the locale string + + sql = <<-SQL + ( + lower(public_body_translations.name) like lower('%'||?||'%') + OR lower(public_body_translations.short_name) like lower('%'||?||'%') + OR lower(public_body_translations.request_email) like lower('%'||?||'%' ) + OR lower(has_tag_string_tags.name) like lower('%'||?||'%' ) + ) + AND has_tag_string_tags.model_id = public_bodies.id + AND has_tag_string_tags.model = 'PublicBody' + AND (public_body_translations.locale = ?) + SQL + + PublicBody.joins(:translations, :tags). + where([sql, query, query, query, query, locale]). + uniq + end + # Convenience methods for creating/editing translations via forms def find_translation_by_locale(locale) self.translations.find_by_locale(locale) @@ -505,7 +534,15 @@ class PublicBody < ActiveRecord::Base public_body.publication_scheme = public_body.publication_scheme || "" public_body.last_edit_editor = editor public_body.last_edit_comment = 'Created from spreadsheet' - public_body.save! + + begin + public_body.save! + rescue ActiveRecord::RecordInvalid + public_body.errors.full_messages.each do |msg| + errors.push "error: line #{ line }: #{ msg } for authority '#{ name }'" + end + next + end end end end diff --git a/app/models/request_classification.rb b/app/models/request_classification.rb index 6873d468b..478a543d3 100644 --- a/app/models/request_classification.rb +++ b/app/models/request_classification.rb @@ -5,8 +5,8 @@ # id :integer not null, primary key # user_id :integer # info_request_event_id :integer -# created_at :datetime -# updated_at :datetime +# created_at :datetime not null +# updated_at :datetime not null # class RequestClassification < ActiveRecord::Base diff --git a/app/models/spam_address.rb b/app/models/spam_address.rb new file mode 100644 index 000000000..2c84beaa0 --- /dev/null +++ b/app/models/spam_address.rb @@ -0,0 +1,21 @@ +# == Schema Information +# +# Table name: spam_addresses +# +# id :integer not null, primary key +# email :string(255) not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class SpamAddress < ActiveRecord::Base + attr_accessible :email + + validates_presence_of :email, :message => 'Please enter the email address to mark as spam' + validates_uniqueness_of :email, :message => 'This address is already marked as spam' + + def self.spam?(email_address) + exists?(:email => email_address) + end + +end diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb index d5dda7bb5..13b6f78dd 100644 --- a/app/models/track_thing.rb +++ b/app/models/track_thing.rb @@ -69,66 +69,30 @@ class TrackThing < ActiveRecord::Base end def track_query_description - # XXX this is very brittle... we should probably ask users - # simply to name their tracks when they make them? - original_text = parsed_text = self.track_query.gsub(/([()]|OR)/, "") - filters = parsed_text.scan /\b\S+:\S+\b/ - varieties = Set.new - date = "" - statuses = Set.new - for filter in filters - parsed_text = parsed_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? - parsed_text = original_text - end - descriptions = [] - if varieties.include? _("requests") - if statuses.empty? - # HACK: Relies on the 'descriptions.sort' below to luckily put this first - descriptions << _("all requests") + filter_description = query_filter_description('(variety:sent OR variety:followup_sent OR variety:response OR variety:comment)', + :no_query => N_("all requests or comments"), + :query => N_("all requests or comments matching text '{{query}}'")) + return filter_description if filter_description + filter_description = query_filter_description('(latest_status:successful OR latest_status:partially_successful)', + :no_query => N_("requests which are successful"), + :query => N_("requests which are successful matching text '{{query}}'")) + return filter_description if filter_description + return _("anything matching text '{{query}}'", :query => track_query) + end + + # Return a readable query description for queries involving commonly used filter clauses + def query_filter_description(string, options) + parsed_query = track_query.gsub(string, '') + if parsed_query != track_query + parsed_query.strip! + if parsed_query.empty? + _(options[:no_query]) else - descriptions << _("requests which are {{list_of_statuses}}", :list_of_statuses => Array(statuses).sort.join(_(' or '))) + _(options[:query], :query => parsed_query) end - varieties -= [_("requests")] end - if descriptions.empty? and varieties.empty? - varieties << _("anything") - end - descriptions += Array(varieties) - parsed_text = parsed_text.strip - descriptions = descriptions.sort.join(_(" or ")) - if !parsed_text.empty? - descriptions += _("{{list_of_things}} matching text '{{search_query}}'", :list_of_things => "", :search_query => parsed_text) - end - return descriptions end - def TrackThing.create_track_for_request(info_request) track_thing = TrackThing.new track_thing.track_type = 'request_updates' @@ -194,30 +158,32 @@ class TrackThing < ActiveRecord::Base end # Return hash of text parameters describing the request etc. - include LinkToHelper def params if @params.nil? if self.track_type == 'request_updates' @params = { # Website - :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>").html_safe), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how + :verb_on_page => _("Follow this request"), :verb_on_page_already => _("You are already following this request"), # Email - :title_in_email => _("New updates for the request '{{request_title}}'", :request_title => self.info_request.title.html_safe), - :title_in_rss => _("New updates for the request '{{request_title}}'", :request_title => self.info_request.title), + :title_in_email => _("New updates for the request '{{request_title}}'", + :request_title => self.info_request.title.html_safe), + :title_in_rss => _("New updates for the request '{{request_title}}'", + :request_title => self.info_request.title), # Authentication - :web => _("To follow the request '{{request_title}}'", :request_title => CGI.escapeHTML(self.info_request.title)), - :email => _("Then you will be updated whenever the request '{{request_title}}' is updated.", :request_title => CGI.escapeHTML(self.info_request.title)), - :email_subject => _("Confirm you want to follow the request '{{request_title}}'", :request_title => self.info_request.title), + :web => _("To follow the request '{{request_title}}'", + :request_title => self.info_request.title), + :email => _("Then you will be updated whenever the request '{{request_title}}' is updated.", + :request_title => self.info_request.title), + :email_subject => _("Confirm you want to follow the request '{{request_title}}'", + :request_title => self.info_request.title), # RSS sorting :feed_sortby => 'newest' } elsif self.track_type == 'all_new_requests' @params = { # Website - :list_description => _("any <a href=\"/list\">new requests</a>"), :verb_on_page => _("Follow all new requests"), :verb_on_page_already => _("You are already following new requests"), # Email @@ -233,7 +199,6 @@ class TrackThing < ActiveRecord::Base elsif self.track_type == 'all_successful_requests' @params = { # Website - :list_description => _("any <a href=\"/list/successful\">successful requests</a>"), :verb_on_page => _("Follow new successful responses"), :verb_on_page_already => _("You are following all new successful responses"), # Email @@ -252,39 +217,51 @@ class TrackThing < ActiveRecord::Base elsif self.track_type == 'public_body_updates' @params = { # Website - :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>").html_safe), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how - :verb_on_page => _("Follow requests to {{public_body_name}}",:public_body_name=>CGI.escapeHTML(self.public_body.name)), - :verb_on_page_already => _("You are already following requests to {{public_body_name}}", :public_body_name=>CGI.escapeHTML(self.public_body.name)), + :verb_on_page => _("Follow requests to {{public_body_name}}", + :public_body_name => self.public_body.name), + :verb_on_page_already => _("You are already following requests to {{public_body_name}}", + :public_body_name => self.public_body.name), # Email - :title_in_email => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'", - :title_in_rss => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'", + :title_in_email => _("{{foi_law}} requests to '{{public_body_name}}'", + :foi_law => self.public_body.law_only_short, + :public_body_name => self.public_body.name), + :title_in_rss => _("{{foi_law}} requests to '{{public_body_name}}'", + :foi_law => self.public_body.law_only_short, + :public_body_name => self.public_body.name), # Authentication - :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'", :site_name=>AlaveteliConfiguration::site_name, :public_body_name=>CGI.escapeHTML(self.public_body.name)), - :email => _("Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'.", :public_body_name=>CGI.escapeHTML(self.public_body.name)), - :email_subject => _("Confirm you want to follow requests to '{{public_body_name}}'", :public_body_name=>self.public_body.name), + :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'", + :site_name => AlaveteliConfiguration::site_name, + :public_body_name => self.public_body.name), + :email => _("Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'.", + :public_body_name => self.public_body.name), + :email_subject => _("Confirm you want to follow requests to '{{public_body_name}}'", + :public_body_name => self.public_body.name), # RSS sorting :feed_sortby => 'newest' } elsif self.track_type == 'user_updates' @params = { # Website - :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>").html_safe), # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how :verb_on_page => _("Follow this person"), :verb_on_page_already => _("You are already following this person"), # Email - :title_in_email => _("FOI requests by '{{user_name}}'", :user_name=>self.tracked_user.name.html_safe), - :title_in_rss => _("FOI requests by '{{user_name}}'", :user_name=>self.tracked_user.name), + :title_in_email => _("FOI requests by '{{user_name}}'", + :user_name => self.tracked_user.name.html_safe), + :title_in_rss => _("FOI requests by '{{user_name}}'", + :user_name => self.tracked_user.name), # Authentication - :web => _("To follow requests by '{{user_name}}'", :user_name=>CGI.escapeHTML(self.tracked_user.name)), - :email => _("Then you will be notified whenever '{{user_name}}' requests something or gets a response.", :user_name=>CGI.escapeHTML(self.tracked_user.name)), - :email_subject => _("Confirm you want to follow requests by '{{user_name}}'", :user_name=>self.tracked_user.name), + :web => _("To follow requests by '{{user_name}}'", + :user_name=> self.tracked_user.name), + :email => _("Then you will be notified whenever '{{user_name}}' requests something or gets a response.", + :user_name => self.tracked_user.name), + :email_subject => _("Confirm you want to follow requests by '{{user_name}}'", + :user_name => self.tracked_user.name), # RSS sorting :feed_sortby => 'newest' } elsif self.track_type == 'search_query' @params = { # Website - :list_description => ("<a href=\"/search/" + CGI.escapeHTML(self.track_query) + "/newest/advanced\">" + CGI.escapeHTML(self.track_query_description) + "</a>").html_safe, # XXX yeuch, sometimes I just want to call view helpers from the model, sorry! can't work out how :verb_on_page => _("Follow things matching this search"), :verb_on_page_already => _("You are already following things matching this search"), # Email diff --git a/app/models/user.rb b/app/models/user.rb index e63ce8129..d75622b37 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,26 +1,25 @@ # == Schema Information -# Schema version: 20131024114346 # # Table name: users # -# id :integer not null, primary key -# email :string(255) not null -# name :string(255) not null -# hashed_password :string(255) not null -# salt :string(255) not null -# created_at :datetime not null -# updated_at :datetime not null -# email_confirmed :boolean default(FALSE), not null -# url_name :text not null -# last_daily_track_email :datetime default(2000-01-01 00:00:00 UTC) -# admin_level :string(255) default("none"), not null -# ban_text :text default(""), not null -# about_me :text default(""), not null -# locale :string(255) -# email_bounced_at :datetime -# email_bounce_message :text default(""), not null -# no_limit :boolean default(FALSE), not null -# receive_email_alerts :boolean default(TRUE), not null +# id :integer not null, primary key +# email :string(255) not null +# name :string(255) not null +# hashed_password :string(255) not null +# salt :string(255) not null +# created_at :datetime not null +# updated_at :datetime not null +# email_confirmed :boolean default(FALSE), not null +# url_name :text not null +# last_daily_track_email :datetime default(Sat Jan 01 00:00:00 UTC 2000) +# admin_level :string(255) default("none"), not null +# ban_text :text default(""), not null +# about_me :text default(""), not null +# locale :string(255) +# email_bounced_at :datetime +# email_bounce_message :text default(""), not null +# no_limit :boolean default(FALSE), not null +# receive_email_alerts :boolean default(TRUE), not null # can_make_batch_requests :boolean default(FALSE), not null # |