aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/responsive/_global_style.scss3
-rw-r--r--app/assets/stylesheets/responsive/_new_request_layout.scss5
-rw-r--r--app/assets/stylesheets/responsive/_user_layout.scss5
-rw-r--r--app/controllers/general_controller.rb2
-rw-r--r--app/models/censor_rule.rb6
-rw-r--r--app/models/outgoing_message.rb216
-rw-r--r--app/models/public_body.rb20
-rw-r--r--app/views/admin_public_body/import_csv.html.erb18
-rw-r--r--config/general.yml-example750
-rw-r--r--doc/CHANGES.md11
-rw-r--r--lib/configuration.rb5
-rw-r--r--spec/models/censor_rule_spec.rb33
-rw-r--r--spec/models/public_body_spec.rb52
13 files changed, 884 insertions, 242 deletions
diff --git a/app/assets/stylesheets/responsive/_global_style.scss b/app/assets/stylesheets/responsive/_global_style.scss
index 290591b5f..af25fb0b0 100644
--- a/app/assets/stylesheets/responsive/_global_style.scss
+++ b/app/assets/stylesheets/responsive/_global_style.scss
@@ -17,6 +17,9 @@ a {
&:focus {
color: #333333;
}
+ &:visited {
+ color: darken(#2688dc, 10%);
+ }
}
h1, h2, h3, h4, h5, h6 {
diff --git a/app/assets/stylesheets/responsive/_new_request_layout.scss b/app/assets/stylesheets/responsive/_new_request_layout.scss
index eec95ae77..aba4ffc29 100644
--- a/app/assets/stylesheets/responsive/_new_request_layout.scss
+++ b/app/assets/stylesheets/responsive/_new_request_layout.scss
@@ -29,6 +29,11 @@
@include lte-ie7 {
width: 26.188em;
}
+ /* Don't nest public body grid row in this context */
+ #public_body_show {
+ @include grid-row();
+ }
+
}
/* Hide some elements of the public body that aren't appropriate in this
diff --git a/app/assets/stylesheets/responsive/_user_layout.scss b/app/assets/stylesheets/responsive/_user_layout.scss
index 8087f978c..a568a5fa3 100644
--- a/app/assets/stylesheets/responsive/_user_layout.scss
+++ b/app/assets/stylesheets/responsive/_user_layout.scss
@@ -1,2 +1,7 @@
/* Layout for user pages */
+#user_profile_search {
+ #search_form {
+ margin-top: 2rem;
+ }
+}
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 158492eb2..2c8abbaf4 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -32,7 +32,7 @@ class GeneralController < ApplicationController
if !content.empty?
@data = XmlSimple.xml_in(content)
@channel = @data['channel'][0]
- @blog_items = @channel['item']
+ @blog_items = @channel.fetch('item') { [] }
@feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}]
end
end
diff --git a/app/models/censor_rule.rb b/app/models/censor_rule.rb
index 3c5c77563..62cf8112f 100644
--- a/app/models/censor_rule.rb
+++ b/app/models/censor_rule.rb
@@ -30,7 +30,11 @@ class CensorRule < ActiveRecord::Base
attr_accessor :allow_global
validate :require_user_request_or_public_body, :unless => proc{ |rule| rule.allow_global == true }
validate :require_valid_regexp, :if => proc{ |rule| rule.regexp? == true }
- validates_presence_of :text
+
+ validates_presence_of :text,
+ :replacement,
+ :last_edit_comment,
+ :last_edit_editor
scope :global, {:conditions => {:info_request_id => nil,
:user_id => nil,
diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb
index 160f69d0b..9424113fc 100644
--- a/app/models/outgoing_message.rb
+++ b/app/models/outgoing_message.rb
@@ -28,106 +28,115 @@ class OutgoingMessage < ActiveRecord::Base
extend MessageProminence
include Rails.application.routes.url_helpers
include LinkToHelper
- self.default_url_options[:host] = AlaveteliConfiguration::domain
- # https links in emails if forcing SSL
- if AlaveteliConfiguration::force_ssl
- self.default_url_options[:protocol] = "https"
- end
- strip_attributes!
-
- has_prominence
+ # To override the default letter
+ attr_accessor :default_letter
- belongs_to :info_request
validates_presence_of :info_request
-
validates_inclusion_of :status, :in => ['ready', 'sent', 'failed']
- validates_inclusion_of :message_type, :in => ['initial_request', 'followup' ] #, 'complaint']
+ validates_inclusion_of :message_type, :in => ['initial_request', 'followup']
validate :format_of_body
+ belongs_to :info_request
belongs_to :incoming_message_followup, :foreign_key => 'incoming_message_followup_id', :class_name => 'IncomingMessage'
# can have many events, for items which were resent by site admin e.g. if
# contact address changed
has_many :info_request_events
- # To override the default letter
- attr_accessor :default_letter
-
+ after_initialize :set_default_letter
+ after_save :purge_in_cache
# reindex if body text is edited (e.g. by admin interface)
after_update :xapian_reindex_after_update
- def xapian_reindex_after_update
- if self.changes.include?('body')
- for info_request_event in self.info_request_events
- info_request_event.xapian_mark_needs_index
- end
- end
- end
- after_initialize :set_default_letter
+ strip_attributes!
+ has_prominence
- # How the default letter starts and ends
- def get_salutation
- if self.info_request.is_batch_request_template?
- return OutgoingMessage.placeholder_salutation
- end
- ret = ""
- if self.message_type == 'followup' && !self.incoming_message_followup.nil? && !self.incoming_message_followup.safe_mail_from.nil? && self.incoming_message_followup.valid_to_reply_to?
- ret = ret + OutgoingMailer.name_for_followup(self.info_request, self.incoming_message_followup)
- else
- return OutgoingMessage.default_salutation(self.info_request.public_body)
- end
- salutation = _("Dear {{public_body_name}},", :public_body_name => ret)
+ self.default_url_options[:host] = AlaveteliConfiguration.domain
+
+ # https links in emails if forcing SSL
+ if AlaveteliConfiguration::force_ssl
+ self.default_url_options[:protocol] = "https"
end
- def OutgoingMessage.default_salutation(public_body)
+ def self.default_salutation(public_body)
_("Dear {{public_body_name}},", :public_body_name => public_body.name)
end
- def OutgoingMessage.placeholder_salutation
+ def self.placeholder_salutation
_("Dear [Authority name],")
end
- def OutgoingMessage.fill_in_salutation(body, public_body)
+ def self.fill_in_salutation(body, public_body)
body.gsub(placeholder_salutation, default_salutation(public_body))
end
+ # How the default letter starts and ends
+ def get_salutation
+ if info_request.is_batch_request_template?
+ return OutgoingMessage.placeholder_salutation
+ end
+
+ ret = ""
+ if message_type == 'followup' &&
+ !incoming_message_followup.nil? &&
+ !incoming_message_followup.safe_mail_from.nil? &&
+ incoming_message_followup.valid_to_reply_to?
+
+ ret += OutgoingMailer.name_for_followup(info_request, incoming_message_followup)
+ else
+ return OutgoingMessage.default_salutation(info_request.public_body)
+ end
+ salutation = _("Dear {{public_body_name}},", :public_body_name => ret)
+ end
+
def get_signoff
- if self.message_type == 'followup' && !self.incoming_message_followup.nil? && !self.incoming_message_followup.safe_mail_from.nil? && self.incoming_message_followup.valid_to_reply_to?
- return _("Yours sincerely,")
+ if message_type == 'followup' &&
+ !incoming_message_followup.nil? &&
+ !incoming_message_followup.safe_mail_from.nil? &&
+ incoming_message_followup.valid_to_reply_to?
+
+ _("Yours sincerely,")
else
- return _("Yours faithfully,")
+ _("Yours faithfully,")
end
end
+
def get_internal_review_insert_here_note
- return _("GIVE DETAILS ABOUT YOUR COMPLAINT HERE")
+ _("GIVE DETAILS ABOUT YOUR COMPLAINT HERE")
end
- def get_default_letter
- if self.default_letter
- return self.default_letter
- end
- if self.what_doing == 'internal_review'
- _("Please pass this on to the person who conducts Freedom of Information reviews.") +
- "\n\n" +
- _("I am writing to request an internal review of {{public_body_name}}'s handling of my FOI request '{{info_request_title}}'.",
- :public_body_name => self.info_request.public_body.name,
- :info_request_title => self.info_request.title) +
- "\n\n\n\n [ " + self.get_internal_review_insert_here_note + " ] \n\n\n\n" +
- _("A full history of my FOI request and all correspondence is available on the Internet at this address: {{url}}",
- :url => request_url(self.info_request)) +
- "\n"
+ def get_default_letter
+ return default_letter if default_letter
+
+ if what_doing == 'internal_review'
+ letter = _("Please pass this on to the person who conducts Freedom of Information reviews.")
+ letter += "\n\n"
+ letter += _("I am writing to request an internal review of {{public_body_name}}'s handling of my FOI request '{{info_request_title}}'.",
+ :public_body_name => info_request.public_body.name,
+ :info_request_title => info_request.title)
+ letter += "\n\n\n\n [ #{ get_internal_review_insert_here_note } ] \n\n\n\n"
+ letter += _("A full history of my FOI request and all correspondence is available on the Internet at this address: {{url}}",
+ :url => request_url(info_request))
+ letter += "\n"
else
""
end
end
+
def get_default_message
- get_salutation + "\n\n" + get_default_letter + "\n\n" + get_signoff + "\n\n"
+ msg = get_salutation
+ msg += "\n\n"
+ msg += get_default_letter
+ msg += "\n\n"
+ msg += get_signoff
+ msg += "\n\n"
end
+
def set_signature_name(name)
# TODO: We use raw_body here to get unstripped one
- if self.raw_body == self.get_default_message
- self.body = self.raw_body + name
+ if raw_body == get_default_message
+ self.body = raw_body + name
end
end
@@ -142,84 +151,88 @@ class OutgoingMessage < ActiveRecord::Base
ret.gsub!(/(?:\n\s*){2,}/, "\n\n") # remove excess linebreaks that unnecessarily space it out
# Remove things from censor rules
- if !self.info_request.nil?
+ unless info_request.nil?
self.info_request.apply_censor_rules_to_text!(ret)
end
ret
end
+
def raw_body
read_attribute(:body)
end
# Used to give warnings when writing new messages
def contains_email?
- MySociety::Validate.email_find_regexp.match(self.body)
+ MySociety::Validate.email_find_regexp.match(body)
end
+
def contains_postcode?
- MySociety::Validate.contains_postcode?(self.body)
+ MySociety::Validate.contains_postcode?(body)
end
# Deliver outgoing message
# Note: You can test this from script/console with, say:
# InfoRequest.find(1).outgoing_messages[0].send_message
def send_message(log_event_type = 'sent')
- if self.status == 'ready'
- if self.message_type == 'initial_request'
+ if status == 'ready'
+ if message_type == 'initial_request'
self.last_sent_at = Time.now
self.status = 'sent'
self.save!
- mail_message = OutgoingMailer.initial_request(self.info_request, self).deliver
+ mail_message = OutgoingMailer.initial_request(info_request, self).deliver
self.info_request.log_event(log_event_type, {
:email => mail_message.to_addrs.join(", "),
:outgoing_message_id => self.id,
:smtp_message_id => mail_message.message_id
})
self.info_request.set_described_state('waiting_response')
- elsif self.message_type == 'followup'
+ elsif message_type == 'followup'
self.last_sent_at = Time.now
self.status = 'sent'
self.save!
- mail_message = OutgoingMailer.followup(self.info_request, self, self.incoming_message_followup).deliver
+ mail_message = OutgoingMailer.followup(info_request, self, incoming_message_followup).deliver
self.info_request.log_event('followup_' + log_event_type, {
:email => mail_message.to_addrs.join(", "),
:outgoing_message_id => self.id,
:smtp_message_id => mail_message.message_id
})
- if self.info_request.described_state == 'waiting_clarification'
+ if info_request.described_state == 'waiting_clarification'
self.info_request.set_described_state('waiting_response')
end
- if self.what_doing == 'internal_review'
+ if what_doing == 'internal_review'
self.info_request.set_described_state('internal_review')
end
else
- raise "Message id #{self.id} has type '#{self.message_type}' which send_message can't handle"
+ raise "Message id #{id} has type '#{message_type}' which send_message can't handle"
end
- elsif self.status == 'sent'
- raise "Message id #{self.id} has already been sent"
+ elsif status == 'sent'
+ raise "Message id #{id} has already been sent"
else
- raise "Message id #{self.id} not in state for send_message"
+ raise "Message id #{id} not in state for send_message"
end
end
# An admin function
def resend_message
- if ['initial_request', 'followup'].include?(self.message_type) and self.status == 'sent'
+ if ['initial_request', 'followup'].include?(message_type) and status == 'sent'
self.status = 'ready'
send_message('resent')
else
- raise "Message id #{self.id} has type '#{self.message_type}' status '#{self.status}' which resend_message can't handle"
+ raise "Message id #{id} has type '#{message_type}' status '#{status}' which resend_message can't handle"
end
end
# Returns the text to quote the original message when sending this one
def quoted_part_to_append_to_email
- if self.message_type == 'followup' && !self.incoming_message_followup.nil?
- return "\n\n-----Original Message-----\n\n" + self.incoming_message_followup.get_body_for_quoting + "\n"
+ if message_type == 'followup' && !incoming_message_followup.nil?
+ quoted = "\n\n-----Original Message-----\n\n"
+ quoted += incoming_message_followup.get_body_for_quoting
+ quoted += "\n"
else
- return ""
+ ""
end
end
@@ -229,8 +242,8 @@ class OutgoingMessage < ActiveRecord::Base
end
# Returns text for indexing / text display
- def get_text_for_indexing(strip_salutation=true)
- text = self.body.strip
+ def get_text_for_indexing(strip_salutation = true)
+ text = body.strip
# Remove salutation
text.sub!(/Dear .+,/, "") if strip_salutation
@@ -238,19 +251,20 @@ class OutgoingMessage < ActiveRecord::Base
# Remove email addresses from display/index etc.
self.remove_privacy_sensitive_things!(text)
- return text
+ text
end
# Return body for display as HTML
def get_body_for_html_display
- text = self.body.strip
+ text = body.strip
self.remove_privacy_sensitive_things!(text)
- text = MySociety::Format.wrap_email_body_by_lines(text) # reparagraph and wrap it so is good preview of emails
+ # reparagraph and wrap it so is good preview of emails
+ text = MySociety::Format.wrap_email_body_by_lines(text)
text = CGI.escapeHTML(text)
text = MySociety::Format.make_clickable(text, :contract => 1)
text.gsub!(/\[(email address|mobile number)\]/, '[<a href="/help/officers#mobiles">\1</a>]')
text = text.gsub(/\n/, '<br>')
- return text.html_safe
+ text.html_safe
end
# Return body for display as text
@@ -261,17 +275,16 @@ class OutgoingMessage < ActiveRecord::Base
def fully_destroy
ActiveRecord::Base.transaction do
- info_request_event = InfoRequestEvent.find_by_outgoing_message_id(self.id)
+ info_request_event = InfoRequestEvent.find_by_outgoing_message_id(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
+ destroy
end
end
- after_save(:purge_in_cache)
def purge_in_cache
- self.info_request.purge_in_cache
+ info_request.purge_in_cache
end
def for_admin_column
@@ -280,18 +293,24 @@ class OutgoingMessage < ActiveRecord::Base
end
end
+ def xapian_reindex_after_update
+ if changes.include?('body')
+ info_request_events.each do |event|
+ event.xapian_mark_needs_index
+ end
+ end
+ end
+
private
def set_default_letter
- if self.body.nil?
- self.body = get_default_message
- end
+ self.body = get_default_message if body.nil?
end
def format_of_body
- if self.body.empty? || self.body =~ /\A#{Regexp.escape(get_salutation)}\s+#{Regexp.escape(get_signoff)}/ || self.body =~ /#{Regexp.escape(get_internal_review_insert_here_note)}/
- if self.message_type == 'followup'
- if self.what_doing == 'internal_review'
+ if body.empty? || body =~ /\A#{Regexp.escape(get_salutation)}\s+#{Regexp.escape(get_signoff)}/ || body =~ /#{Regexp.escape(get_internal_review_insert_here_note)}/
+ if message_type == 'followup'
+ if what_doing == 'internal_review'
errors.add(:body, _("Please give details explaining why you want a review"))
else
errors.add(:body, _("Please enter your follow up message"))
@@ -299,16 +318,19 @@ class OutgoingMessage < ActiveRecord::Base
elsif
errors.add(:body, _("Please enter your letter requesting information"))
else
- raise "Message id #{self.id} has type '#{self.message_type}' which validate can't handle"
+ raise "Message id #{id} has type '#{message_type}' which validate can't handle"
end
end
- if self.body =~ /#{get_signoff}\s*\Z/m
+
+ if body =~ /#{get_signoff}\s*\Z/m
errors.add(:body, _("Please sign at the bottom with your name, or alter the \"{{signoff}}\" signature", :signoff => get_signoff))
end
- if !MySociety::Validate.uses_mixed_capitals(self.body)
+
+ unless MySociety::Validate.uses_mixed_capitals(body)
errors.add(:body, _('Please write your message using a mixture of capital and lower case letters. This makes it easier for others to read.'))
end
- if self.what_doing.nil? || !['new_information', 'internal_review', 'normal_sort'].include?(self.what_doing)
+
+ if what_doing.nil? || !['new_information', 'internal_review', 'normal_sort'].include?(what_doing)
errors.add(:what_doing_dummy, _('Please choose what sort of reply you are making.'))
end
end
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index b22482541..87b5c2227 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -60,6 +60,21 @@ class PublicBody < ActiveRecord::Base
translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme
+ # Default fields available for importing from CSV, in the format
+ # [field_name, 'short description of field (basic html allowed)']
+ cattr_accessor :csv_import_fields do
+ [
+ ['name', '(i18n)<strong>Existing records cannot be renamed</strong>'],
+ ['short_name', '(i18n)'],
+ ['request_email', '(i18n)'],
+ ['notes', '(i18n)'],
+ ['publication_scheme', '(i18n)'],
+ ['disclosure_log', '(i18n)'],
+ ['home_page', ''],
+ ['tag_string', '(tags separated by spaces)'],
+ ]
+ end
+
# Public: Search for Public Bodies whose name, short_name, request_email or
# tags contain the given query
#
@@ -477,7 +492,10 @@ class PublicBody < ActiveRecord::Base
next
end
- field_list = ['name', 'short_name', 'request_email', 'notes', 'publication_scheme', 'disclosure_log', 'home_page', 'tag_string']
+ field_list = []
+ self.csv_import_fields.each do |field_name, field_notes|
+ field_list.push field_name
+ end
if public_body = bodies_by_name[name] # Existing public body
available_locales.each do |locale|
diff --git a/app/views/admin_public_body/import_csv.html.erb b/app/views/admin_public_body/import_csv.html.erb
index d15ef1791..c690f0fc2 100644
--- a/app/views/admin_public_body/import_csv.html.erb
+++ b/app/views/admin_public_body/import_csv.html.erb
@@ -51,19 +51,11 @@ Another One,another@example.com,Otro organismo,a_tag
</pre>
<p><strong>Supported fields:</strong>
- <ul>
- <li>
- <code>name</code> (i18n)
- <strong>Existing records cannot be renamed</strong>
- </li>
- <li><code>short_name</code> (i18n)</li>
- <li><code>request_email</code> (i18n)</li>
- <li><code>notes</code> (i18n)</li>
- <li><code>publication_scheme</code> (i18n)</li>
- <li><code>disclosure_log</code> (i18n)</li>
- <li><code>home_page</code></li>
- <li><code>tag_string</code> (tags separated by spaces)</li>
- </ul>
+ <ul>
+ <% PublicBody.csv_import_fields.each do |field, notes| %>
+ <li><code><%= field %></code> <%= sanitize(notes) %></li>
+ <% end %>
+ </ul>
</p>
<p><strong>Note:</strong> Choose <strong>dry run</strong> to test, without
diff --git a/config/general.yml-example b/config/general.yml-example
index 0f32f6192..a80784712 100644
--- a/config/general.yml-example
+++ b/config/general.yml-example
@@ -5,256 +5,764 @@
#
# Copy this file to one called "general.yml" in the same directory. Or
# have multiple config files and use a symlink to change between them.
+#
+# Default values for these settings can be found in
+# RAILS_ROOT/lib/configuration.rb
+#
+# ==============================================================================
# Site name appears in various places throughout the site
+#
+# SITE_NAME - String name of the site (default: 'Alaveteli')
+#
+# Examples:
+#
+# SITE_NAME: 'Alaveteli'
+# SITE_NAME: 'WhatDoTheyKnow'
+#
+# ---
SITE_NAME: 'Alaveteli'
# Domain used in URLs generated by scripts (e.g. for going in some emails)
-DOMAIN: '127.0.0.1:3000'
+#
+# DOMAIN - String domain or IP address (default: 'localhost:3000')
+#
+# Examples:
+#
+# DOMAIN: '127.0.0.1:3000'
+# DOMAIN: 'www.example.com'
+#
+# ---
+DOMAIN: 'www.example.org'
-# If true forces everyone (in the production environment) to use encrypted connections
-# (via https) by redirecting unencrypted connections. This is *highly* recommended
-# so that logins can't be intercepted by naughty people.
+# If true forces everyone (in the production environment) to use encrypted
+# connections (via https) by redirecting unencrypted connections. This is
+# *highly* recommended so that logins can't be intercepted by naughty people.
+#
+# FORCE_SSL - Boolean (default: true)
+#
+# ---
FORCE_SSL: true
# ISO country code of country currrently deployed in
# (http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
+#
+# ISO_COUNTRY_CODE - String country code (default: GB)
+#
+# Examples:
+#
+# ISO_COUNTRY_CODE: GB
+#
+# ---
ISO_COUNTRY_CODE: GB
# This is the timezone that times and dates are displayed in
# If not set defaults to UTC.
-TIME_ZONE: Australia/Sydney
+#
+# TIME_ZONE - String time zone (default: UTC)
+#
+# Examples:
+#
+# TIME_ZONE: Australia/Sydney
+# TIME_ZONE: Europe/London
+#
+# ---
+TIME_ZONE: UTC
# These feeds are displayed accordingly on the Alaveteli "blog" page:
-BLOG_FEED: 'https://www.mysociety.org/category/projects/whatdotheyknow/feed/'
-TWITTER_USERNAME: 'whatdotheyknow'
+#
+# BLOG_FEED - String url to the blog feed (default: nil)
+#
+# Examples:
+#
+# BLOG_FEED: https://www.mysociety.org/category/projects/whatdotheyknow/feed/
+#
+# ---
+BLOG_FEED: ''
+
+# If you want a twitter feed displayed on the "blog" page, provide the
+# widget ID and username.
+#
+# TWITTER_USERNAME - String Twitter username (default: nil)
+#
+# Examples:
+#
+# TWITTER_USERNAME: 'whatdotheyknow'
+#
+# ---
+TWITTER_USERNAME: ''
+
# Set the widget_id to get the Twitter sidebar on the blog page.
# To get one https://twitter.com/settings/widgets
+#
+# TWITTER_WIDGET_ID - String widget ID (default: false)
+#
+# Examples:
+#
+# TWITTER_WIDGET_ID: '833549204689320031'
+#
+# ---
TWITTER_WIDGET_ID: ''
-# Locales we wish to support in this app, space-delimited
-AVAILABLE_LOCALES: 'en es'
+# The locales you want your site to support. If there is more than one, use
+# spaces betwween the entries.
+#
+# AVAILABLE_LOCALES – String of space-separated locales (default: nil)
+#
+# Examples:
+#
+# AVAILABLE_LOCALES: 'en es'
+#
+# ---
+AVAILABLE_LOCALES: 'en'
+
+# Nominate one of the AVAILABLE_LOCALES locales as the default
+#
+# DEFAULT_LOCALE – String locale (default: nil)
+#
+# Examples:
+#
+# DEFAULT_LOCALE: 'en'
+#
+# ---
DEFAULT_LOCALE: 'en'
+
+# Should Alaveteli try to use the default language of the user's browser?
+#
+# USE_DEFAULT_BROWSER_LANGUAGE - Boolean (default: true)
+#
+# Examples:
+#
+# USE_DEFAULT_BROWSER_LANGUAGE: true
+#
+# ---
USE_DEFAULT_BROWSER_LANGUAGE: true
-# If you don't want the default locale to be included in URLs generated
-# by the application, set this to false
+# Normally, Alaveteli will put the locale into its URLs, like this
+# www.example.com/en/body/list/all. If you don't want this behaviour whenever
+# the locale is the default one, set INCLUDE_DEFAULT_LOCALE_IN_URLS to false.
+#
+# INCLUDE_DEFAULT_LOCALE_IN_URLS: Boolean (default: true)
+#
+# Examples:
+#
+# INCLUDE_DEFAULT_LOCALE_IN_URLS: false
+#
+# ---
INCLUDE_DEFAULT_LOCALE_IN_URLS: true
-# How many days should have passed before an answer to a request is officially late?
+# The REPLY...AFTER_DAYS settings define how many days must have passed before
+# an answer to a request is officially late. The SPECIAL case is for some types
+# of authority (for example: in the UK, schools) which are granted a bit longer
+# than everyone else to respond to questions.
+#
+# REPLY_LATE_AFTER_DAYS - Integer (default: 20)
+# REPLY_VERY_LATE_AFTER_DAYS - Integer (default: 40)
+# SPECIAL_REPLY_VERY_LATE_AFTER_DAYS - Integer (default: 60)
+#
+# Examples:
+#
+# REPLY_LATE_AFTER_DAYS: 20
+# REPLY_VERY_LATE_AFTER_DAYS: 40
+# SPECIAL_REPLY_VERY_LATE_AFTER_DAYS: 60
+#
+# ---
REPLY_LATE_AFTER_DAYS: 20
REPLY_VERY_LATE_AFTER_DAYS: 40
-# We give some types of authority like schools a bit longer than everyone else
SPECIAL_REPLY_VERY_LATE_AFTER_DAYS: 60
-# Whether the days above are given in working or calendar days. Value can be "working" or "calendar".
-# Default is "working".
+
+# The WORKING_OR_CALENDAR_DAYS setting can be either "working" (the default) or
+# "calendar", and determines which days are counted when calculating whether a
+# request is officially late.
+#
+# WORKING_OR_CALENDAR_DAYS - String in [working, calendar] (default: working)
+#
+# Examples:
+#
+# WORKING_OR_CALENDAR_DAYS: working
+# WORKING_OR_CALENDAR_DAYS: calendar
+#
+# ---
WORKING_OR_CALENDAR_DAYS: working
-# example public bodies for the home page, semicolon delimited - short_names
-# Comment out if you want this to be auto-generated. WARNING: this is slow & don't use production!
-FRONTPAGE_PUBLICBODY_EXAMPLES: 'tgq'
+# Specify which public bodies you want to be listed as examples on the home
+# page, using their short_names. If you want more than one, separate them with
+# semicolons. List is auto-generated if not set.
+#
+# *Warning:* this is slow — don't use in production!
+#
+# FRONTPAGE_PUBLICBODY_EXAMPLES - String semicolon-separated list of public
+# bodies (default: nil)
+#
+# Examples:
+#
+# FRONTPAGE_PUBLICBODY_EXAMPLES: 'tgq'
+# FRONTPAGE_PUBLICBODY_EXAMPLES: 'tgq;foo;bar'
+#
+# ---
+FRONTPAGE_PUBLICBODY_EXAMPLES: ''
-# URLs of themes to download and use (when running rails-post-deploy
-# script). Earlier in the list means the templates have a higher
-# priority.
+# URLs of themes to download and use (when running the rails-post-deploy
+# script). The earlier in the list means the templates have a higher priority.
+#
+# THEME_URLS - Array of theme URLs (default: [])
+#
+# Examples:
+#
+# THEME_URLS:
+# - 'git://github.com/mysociety/alavetelitheme.git'
+# - 'git://github.com/mysociety/whatdotheyknow-theme.git'
+#
+# ---
THEME_URLS:
- - 'git://github.com/mysociety/alavetelitheme.git'
+ - 'git://github.com/mysociety/alavetelitheme.git'
-# When rails-post-deploy installs the themes it will try this branch first
-# (but only if this config is set). If the branch doesn't exist it will fall
-# back to using a tagged version specific to your installed alaveteli version.
-# If that doesn't exist it will back to master.
+# When rails-post-deploy installs the themes, it will try to use the branch
+# specified by THEME_BRANCH first. If the branch doesn't exist it will fall
+# back to using a tagged version specific to your installed alaveteli version,
+# and if that doesn't exist it will fall back to master.
+#
+# THEME_BRANCH - Boolean (default: false)
+#
+# Examples:
+#
+# # Use the develop branch if it exists, otherwise fall back as described
+# THEME_BRANCH: 'develop'
+#
+# # try the use-with-alaveteli-xxx branch/tag, otherwise fall back to HEAD
+# THEME_BRANCH: false
+#
+# ---
THEME_BRANCH: false
-# Whether a user needs to sign in to start the New Request process
+# Does a user needs to sign in to start the New Request process?
+#
+# FORCE_REGISTRATION_ON_NEW_REQUEST - Boolean (default: false)
+#
+# ---
FORCE_REGISTRATION_ON_NEW_REQUEST: false
-
-## Incoming email
-# Your email domain, e.g. 'foifa.com'
+# Your email domain for incoming mail.
+#
+# INCOMING_EMAIL_DOMAIN – String domain (default: localhost)
+#
+# Examples:
+#
+# INCOMING_EMAIL_DOMAIN: 'localhost'
+# INCOMING_EMAIL_DOMAIN: 'foifa.com'
+#
+# ---
INCOMING_EMAIL_DOMAIN: 'localhost'
-# An optional prefix to help you distinguish FOI requests, e.g. 'foi+'
-INCOMING_EMAIL_PREFIX: ''
+# An optional prefix to help you distinguish FOI requests.
+#
+# INCOMING_EMAIL_PREFIX - String (default: foi+)
+#
+# Examples:
+#
+# INCOMING_EMAIL_PREFIX: '' # No prefix
+# INCOMING_EMAIL_PREFIX: 'alaveteli+'
+#
+# ---
+INCOMING_EMAIL_PREFIX: 'foi+'
-# used for hash in request email address
+# Used for hash in request email address.
+#
+# INCOMING_EMAIL_SECRET - String (default: dummysecret)
+#
+# Examples:
+#
+# INCOMING_EMAIL_SECRET: '11ae 4e3b 70ff c001 3682 4a51 e86d ef5f'
+#
+# ---
INCOMING_EMAIL_SECRET: 'xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx'
-# used as envelope from at the incoming email domain for cases where we don't care about failure
+# Used as envelope from at the incoming email domain for cases where you don't
+# care about failure.
+#
+# BLACKHOLE_PREFIX - String (default: do-not-reply-to-this-address)
+#
+# Examples:
+#
+# BLACKHOLE_PREFIX: 'do-not-reply-to-this-address'
+# BLACKHOLE_PREFIX: 'do-not-reply'
+#
+# ---
BLACKHOLE_PREFIX: 'do-not-reply-to-this-address'
-## Administration
-
-# The emergency user
+# Emergency admin user login username. YOU SHOULD CHANGE THIS.
+#
+# ADMIN_USERNAME - String (default: nil)
+#
+# Examples:
+#
+# ADMIN_USERNAME: 'admin-alaveteli'
+#
+# ---
ADMIN_USERNAME: 'adminxxxx'
+
+# Emergency admin user login password. YOU SHOULD CHANGE THIS.
+#
+# ADMIN_USERNAME - String (default: nil)
+#
+# Examples:
+#
+# ADMIN_PASSWORD: 'b38bCHBl;28'
+#
+# ---
ADMIN_PASSWORD: 'passwordx'
+
+# Disable the emergency admin user?
+#
+# DISABLE_EMERGENCY_USER - Boolean (default: false)
+#
+# ---
DISABLE_EMERGENCY_USER: false
-# Set this to true, and the admin interface will be available to anonymous users
+# Set this to true, and the admin interface will be available to anonymous
+# users. Obviously, you should not set this to be true in production
+# environments.
+#
+# SKIP_ADMIN_AUTH - Boolean (default: false)
+#
+# ---
SKIP_ADMIN_AUTH: false
-# Email "from" details
-CONTACT_EMAIL: 'postmaster@localhost'
-CONTACT_NAME: 'Alaveteli Webmaster'
+# Email "from" email address
+#
+# CONTACT_EMAIL: String email address (default: contact@localhost)
+#
+# ---
+CONTACT_EMAIL: 'contact@localhost'
+
+# Email "from" name
+#
+# CONTACT_NAME - String contact name (default: Alaveteli)
+#
+# ---
+CONTACT_NAME: 'Alaveteli'
-# Email "from" details for track messages
-TRACK_SENDER_EMAIL: 'postmaster@localhost'
-TRACK_SENDER_NAME: 'Alaveteli Webmaster'
+# Email "from" email address for track messages
+#
+# TRACK_SENDER_EMAIL - String email address (default: contact@localhost)
+#
+# ---
+TRACK_SENDER_EMAIL: 'contact@localhost'
-# Where the raw incoming email data gets stored; make sure you back
+# Email "from" name for track messages
+#
+# TRACK_SENDER_NAME - String contact name (default: Alaveteli)
+#
+# ---
+TRACK_SENDER_NAME: 'Alaveteli'
+
+# Directory where the raw incoming email data gets stored; make sure you back
# this up!
+#
+# RAW_EMAILS_LOCATION - String path (default: files/raw_emails)
+#
+# ---
RAW_EMAILS_LOCATION: 'files/raw_emails'
-# Secret key for signing cookie_store sessions
+# Secret key for signing cookie_store sessions. Make it long and random.
+#
+# COOKIE_STORE_SESSION_SECRET - String (default: 'this default is insecure as
+# code is open source, please override
+# for live sites in config/general; this
+# will do for local development')
+#
+# Examples:
+#
+# COOKIE_STORE_SESSION_SECRET: 'uIngVC238Jn9NsaQizMNf89pliYmDBFugPjHS2JJmzOp8'
+#
+# ---
COOKIE_STORE_SESSION_SECRET: 'your secret key here, make it long and random'
# If present, puts the site in read only mode, and uses the text as reason
# (whole paragraph). Please use a read-only database user as well, as it only
-# checks in a few obvious places.
+# checks in a few obvious places. Typically, you do not want to run your site
+# in read-only mode.
+#
+# READ_ONLY - String (default: nil)
+#
+# Examples:
+#
+# READ_ONLY: 'The site is not currently accepting requests while we move the
+# server.'
+#
+# ---
READ_ONLY: ''
-# Is this a staging or dev site (1) or a live site (0).
-# Controls whether or not the rails-post-deploy script
-# will create the file config/rails_env.rb file to force
-# Rails into production environment.
-STAGING_SITE: 1
+# Is this a staging or development site? If not, it's a live production site.
+# This setting controls whether or not the rails-post-deploy script will create
+# the file config/rails_env.rb file to force Rails into production environment.
+#
+# STAGING_SITE: Integer in [0, 1]
+#
+# Examples:
+#
+# # For staging or development:
+# STAGING_SITE: 1
+#
+# # For production:
+# STAGING_SITE: 0
+#
+# ---
+STAGING_SITE: 0
-# Recaptcha, for detecting humans. Get keys here: http://recaptcha.net/whyrecaptcha.html
+# Recaptcha, for detecting humans. Get keys here:
+# http://recaptcha.net/whyrecaptcha.html
+#
+# RECAPTCHA_PUBLIC_KEY - String (default: 'x')
+#
+# ---
RECAPTCHA_PUBLIC_KEY: 'x'
+
+# Recaptcha, for detecting humans. Get keys here:
+# http://recaptcha.net/whyrecaptcha.html
+#
+# RECAPTCHA_PRIVATE_KEY - String (default: 'x')
+#
+# ---
RECAPTCHA_PRIVATE_KEY: 'x'
# Number of days after which to send a 'new response reminder'
+#
+# NEW_RESPONSE_REMINDER_AFTER_DAYS – Array of Integers (default: [3, 10, 24])
+#
+# Examples:
+#
+# NEW_RESPONSE_REMINDER_AFTER_DAYS: [3, 7]
+#
+# ---
NEW_RESPONSE_REMINDER_AFTER_DAYS: [3, 10, 24]
-# For debugging memory problems. If true, the app logs
-# the memory use increase of the Ruby process due to the
-# request (Linux only). Since Ruby never returns memory to the OS, if the
-# existing process previously served a larger request, this won't
-# show any consumption for the later request.
+# For debugging memory problems. If true, Alaveteli logs the memory use
+# increase of the Ruby process due to the request (Linux only). Since Ruby
+# never returns memory to the OS, if the existing process previously served a
+# larger request, this won't show any consumption for the later request.
+#
+# DEBUG_RECORD_MEMORY - Boolean (default: false)
+#
+# ---
DEBUG_RECORD_MEMORY: false
-# Currently we default to using pdftk to compress PDFs. You can
-# optionally try Ghostscript, which should do a better job of
-# compression. Some versions of pdftk are buggy with respect to
-# compression, in which case Alaveteli doesn't recompress the PDFs at
-# all and logs a warning message "Unable to compress PDF"; which would
-# be another reason to try this setting.
-USE_GHOSTSCRIPT_COMPRESSION: true
+# Currently we default to using pdftk to compress PDFs. You can optionally try
+# Ghostscript, which should do a better job of compression. Some versions of
+# pdftk are buggy with respect to compression, in which case Alaveteli doesn't
+# recompress the PDFs at all and logs a warning message "Unable to compress
+# PDF" — which would be another reason to try this setting.
+#
+# USE_GHOSTSCRIPT_COMPRESSION - Boolean (default: false)
+#
+# ---
+USE_GHOSTSCRIPT_COMPRESSION: false
-# mySociety's gazeteer service. Shouldn't change.
+# Alateveli uses mySociety's gazeteer service to determine country from
+# incoming IP address (this lets us suggest an Alaveteli in the user's country
+# if one exists). You shouldn't normally need to change this.
+#
+# GAZE_URL - String (default: http://gaze.mysociety.org)
+#
+# Examples:
+#
+# GAZE_URL: http://gaze.example.org
+#
+# ---
GAZE_URL: http://gaze.mysociety.org
-# The email address to which non-bounce responses should be forwarded
+# The email address to which non-bounce responses to emails sent out by
+# Alaveteli should be forwarded
+#
+# FORWARD_NONBOUNCE_RESPONSES_TO - String (default: user-support@localhost)
+#
+# Examples:
+#
+# FORWARD_NONBOUNCE_RESPONSES_TO: user-support@example.com
+#
+# ---
FORWARD_NONBOUNCE_RESPONSES_TO: user-support@localhost
-# Path to a program that converts an HTML page in a file to PDF. It
-#should take two arguments: the URL, and a path to an output file.
+# Path to a program that converts an HTML page in a file to PDF. Also used to
+# download a zip file of all the correspondence for a request. It should take
+# two arguments: the URL, and a path to an output file.
+#
# A static binary of wkhtmltopdf is recommended:
# http://code.google.com/p/wkhtmltopdf/downloads/list
# If the command is not present, a text-only version will be rendered
# instead.
+#
+# HTML_TO_PDF_COMMAND - String (default: nil)
+#
+# Examples:
+#
+# HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf
+# HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64
+#
+# ---
HTML_TO_PDF_COMMAND: /usr/local/bin/wkhtmltopdf-amd64
-# Exception notifications
-EXCEPTION_NOTIFICATIONS_FROM: do-not-reply-to-this-address@example.com
+# Email address used for sending exception notifications.
+#
+# EXCEPTION_NOTIFICATIONS_FROM - String (default: nil)
+#
+# Examples:
+#
+# EXCEPTION_NOTIFICATIONS_FROM: do-not-reply-to-this-address@example.com
+#
+# ---
+EXCEPTION_NOTIFICATIONS_FROM: do-not-reply-to-this-address@localhost
+
+# Email address(es) used for receiving exception notifications.
+#
+# EXCEPTION_NOTIFICATIONS_TO - Array of Strings (default: nil)
+#
+# Examples:
+#
+# EXCEPTION_NOTIFICATIONS_TO:
+# - robin@example.com
+# - seb@example.com
+#
+# ---
EXCEPTION_NOTIFICATIONS_TO:
- - robin@example.org
- - seb@example.org
+ - alaveteli@localhost
# This rate limiting can be turned off per-user via the admin interface
+#
+# MAX_REQUESTS_PER_USER_PER_DAY - Integer (default: 6)
+#
+# Examples:
+#
+# MAX_REQUESTS_PER_USER_PER_DAY: 1
+# MAX_REQUESTS_PER_USER_PER_DAY: '' # No limit
+#
+# ---
MAX_REQUESTS_PER_USER_PER_DAY: 6
+# If you're running behind Varnish set this to work out where to send purge
+# requests. Otherwise, don't set it.
+#
+# VARNISH_HOST - String (default: nil)
+#
+# Examples:
+#
+# VARNISH_HOST: localhost
+#
+# ---
+VARNISH_HOST: null
-# This is used to work out where to send purge requests. Should be
-# unset if you aren't running behind varnish
-VARNISH_HOST: localhost
-
-# Adding a value here will enable Google Analytics on all non-admin pages for non-admin users.
+# Adding a value here will enable Google Analytics on all non-admin pages for
+# non-admin users.
+#
+# GA_CODE - String (default: nil)
+#
+# Examples:
+#
+# GA_CODE: 'AB-8222142-14'
+#
+# ---
GA_CODE: ''
-# If you want to override *all* the public body request emails with your own
-# email so that request emails that would normally go to the public body
-# go to you, then uncomment below and fill in your email.
-# Useful for a staging server to play with the whole process of sending requests
-# without inadvertently sending an email to a real authority
-#OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS: test-email@foo.com
+# If you want to override all the public body request emails with your own
+# email address so that request emails that would normally go to the public
+# body go to you, use this setting. This is useful for a staging server, so you
+# can play with the whole process of sending requests without inadvertently
+# sending an email to a real authority.
+#
+# OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS - String (default: nil)
+#
+# Examples:
+#
+# OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS: test-email@example.com
+#
+# ---
+# OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS: test-email@example.com
-# Search path for external commandline utilities (such as pdftohtml, pdftk, unrtf)
+# Search path for external commandline utilities (such as pdftohtml, pdftk,
+# unrtf)
+#
+# UTILITY_SEARCH_PATH - Array of Strings
+# (default: ["/usr/bin", "/usr/local/bin"])
+#
+# Examples:
+#
+# UTILITY_SEARCH_PATH: ["/usr/bin"]
+# UTILITY_SEARCH_PATH: ["/usr/local/bin", "/opt/bin"]
+#
+# ---
UTILITY_SEARCH_PATH: ["/usr/bin", "/usr/local/bin"]
-# Path to your exim or postfix log files that will get sucked up by script/load-mail-server-logs
+# Path to your exim or postfix log files that will get sucked up by
+# script/load-mail-server-logs
+#
+# MTA_LOG_PATH - String (default: /var/log/exim4/exim-mainlog-*)
+#
+# Examples:
+#
+# MTA_LOG_PATH: '/var/log/exim4/exim-mainlog-*'
+#
+# ---
MTA_LOG_PATH: '/var/log/exim4/exim-mainlog-*'
-# Whether we are using "exim" or "postfix" for our MTA
-MTA_LOG_TYPE: "exim"
+# Are you using "exim" or "postfix" for your Mail Transfer Agent (MTA)?
+#
+# MTA_LOG_TYPE - String (default: exim)
+#
+# Examples:
+#
+# MTA_LOG_TYPE: exim
+# MTA_LOG_TYPE: postfix
+#
+# ---
+MTA_LOG_TYPE: exim
# URL where people can donate to the organisation running the site. If set,
# this will be included in the message people see when their request is
# successful.
+#
+# DONATION_URL - String (default: nil)
+#
+# Examples:
+#
+# DONATION_URL: http://www.mysociety.org/donate
+#
+# ---
DONATION_URL: "http://www.mysociety.org/donate/"
-# If you set this to 'true' then a page of statistics on the
-# performance of public bodies will be available:
+# If PUBLIC_BODY_STATISTICS_PAGE is set to true, Alaveteli will make a page of
+# statistics on the performance of public bodies (which you can see at
+# /body_statistics).
+#
+# PUBLIC_BODY_STATISTICS_PAGE - Boolean (default: false)
+#
+# ---
PUBLIC_BODY_STATISTICS_PAGE: false
# The page of statistics for public bodies will only consider public
-# bodies that have had at least this number of requests:
-MINIMUM_REQUESTS_FOR_STATISTICS: 50
+# bodies that have had at least the number of requests set by
+# MINIMUM_REQUESTS_FOR_STATISTICS.
+#
+# MINIMUM_REQUESTS_FOR_STATISTICS - Integer (default: 100)
+#
+# ---
+MINIMUM_REQUESTS_FOR_STATISTICS: 100
-# If only some of the public bodies have been translated into every
-# available locale, you can allow a fallback to the default locale for
-# listing of public bodies.
+# If you would like the public body list page to include bodies that have no
+# translation in the current locale (but which do have a translation in the
+# default locale), set this to true.
+#
+# PUBLIC_BODY_LIST_FALLBACK_TO_DEFAULT_LOCALE - Boolean (default: false)
+#
+# ---
PUBLIC_BODY_LIST_FALLBACK_TO_DEFAULT_LOCALE: false
# If true, while in development mode, try to send mail by SMTP to port
-# 1025 (the port the mailcatcher listens on by default):
+# 1025 (the port the mailcatcher listens on by default)
+#
+# USE_MAILCATCHER_IN_DEVELOPMENT - Boolean (default: true)
+#
+# ---
USE_MAILCATCHER_IN_DEVELOPMENT: true
-# Use memcached to cache HTML fragments for better performance. Will
+# Use memcached to cache HTML fragments for better performance. This will
# only have an effect in environments where
# config.action_controller.perform_caching is set to true
+#
+# CACHE_FRAGMENTS - Boolean (default: true)
+#
+# ---
CACHE_FRAGMENTS: true
-# The default bundle path is vendor/bundle; you can set this option to
-# change it.
+# The default bundle path is vendor/bundle; you can set this option to change it
+#
+# BUNDLE_PATH - String
+#
+# Examples:
+#
+# BUNDLE_PATH: vendor/bundle
+# BUNDLE_PATH: /var/alaveteli/bundle
+#
+# ---
BUNDLE_PATH: vendor/bundle
# In some deployments of Alaveteli you may wish to install each newly
# deployed version alongside the previous ones, in which case certain
-# files and resources should be shared between these installations:
-# for example, the 'files' directory, the 'cache' directory and the
+# files and resources should be shared between these installations.
+# For example, the 'files' directory, the 'cache' directory and the
# generated graphs such as 'public/foi-live-creation.png'. If you're
# installing Alaveteli in such a setup then set SHARED_FILES_PATH to
-# the directory you're keeping these files under. Otherwise, leave it
+# the directory you're keeping these files under. Otherwise, leave it
# blank.
+#
+# SHARED_FILES_PATH - String
+#
+# Examples:
+#
+# SHARED_FILES_PATH: /var/www/alaveteli/shared
+#
+# ---
SHARED_FILES_PATH: ''
# If you have SHARED_FILES_PATH set, then these options list the files
-# and directories that are shared; i.e. those that the deploy scripts
-# should create symlinks to from the repository.
+# that are shared; i.e. those that the deploy scripts should create symlinks to
+# from the repository.
+#
+# SHARED_FILES - Array of Strings
+#
+# Examples:
+#
+# SHARED_FILES:
+# - config/database.yml
+# - config/general.yml
+#
+# ---
SHARED_FILES:
- - config/database.yml
- - config/general.yml
- - config/rails_env.rb
- - config/newrelic.yml
- - config/httpd.conf
- - public/foi-live-creation.png
- - public/foi-user-use.png
- - config/aliases
+ - config/database.yml
+ - config/general.yml
+ - config/rails_env.rb
+ - config/newrelic.yml
+ - config/httpd.conf
+ - public/foi-live-creation.png
+ - public/foi-user-use.png
+ - config/aliases
+
+# If you have SHARED_FILES_PATH set, then these options list the directories
+# that are shared; i.e. those that the deploy scripts should create symlinks to
+# from the repository.
+#
+# SHARED_DIRECTORIES - Array of Strings
+#
+# Examples:
+#
+# SHARED_DIRECTORIES:
+# - files/
+# - cache/
+#
+# ---
SHARED_DIRECTORIES:
- - files/
- - cache/
- - lib/acts_as_xapian/xapiandbs/
- - log/
- - tmp/pids
- - vendor/bundle
- - public/assets
+ - files/
+ - cache/
+ - lib/acts_as_xapian/xapiandbs/
+ - log/
+ - tmp/pids
+ - vendor/bundle
+ - public/assets
# Allow some users to make batch requests to multiple authorities. Once
# this is set to true, you can enable batch requests for an individual
# user via the user admin page.
-
+#
+# ALLOW_BATCH_REQUESTS - Boolean (default: false)
+#
+# ---
ALLOW_BATCH_REQUESTS: false
-# Should we use the responsive stylesheets?
+# Use the responsive base stylesheets and templates, rather than those that
+# only render the site at a fixed width. They allow the site to render nicely
+# on mobile devices as well as larger screens. Set this to false if you want to
+# continue using fixed width stylesheets.
+#
+# RESPONSIVE_STYLING - Boolean (default: true)
+#
+# ---
RESPONSIVE_STYLING: true
diff --git a/doc/CHANGES.md b/doc/CHANGES.md
index 237355c1d..748b37665 100644
--- a/doc/CHANGES.md
+++ b/doc/CHANGES.md
@@ -1,3 +1,14 @@
+# rails-3-develop
+
+## Highlighted Features
+
+## Upgrade Notes
+
+* `CensorRule` now validates the presence of all attributes at the model layer,
+ rather than only as a database constraint. If you have added a `CensorRule` in
+ your theme, you will now have to satisfy the additional validations on the
+ `:replacement`, `:last_edit_comment` and `:last_edit_editor` attributes.
+
# Version 0.19
## Highlighted Features
diff --git a/lib/configuration.rb b/lib/configuration.rb
index bd2d31ac2..2144f9954 100644
--- a/lib/configuration.rb
+++ b/lib/configuration.rb
@@ -42,11 +42,12 @@ module AlaveteliConfiguration
:HTML_TO_PDF_COMMAND => '',
:INCLUDE_DEFAULT_LOCALE_IN_URLS => true,
:INCOMING_EMAIL_DOMAIN => 'localhost',
- :INCOMING_EMAIL_PREFIX => '',
+ :INCOMING_EMAIL_PREFIX => 'foi+',
:INCOMING_EMAIL_SECRET => 'dummysecret',
:ISO_COUNTRY_CODE => 'GB',
:MINIMUM_REQUESTS_FOR_STATISTICS => 100,
- :MAX_REQUESTS_PER_USER_PER_DAY => '',
+ :MAX_REQUESTS_PER_USER_PER_DAY => 6,
+ :MTA_LOG_PATH => '/var/log/exim4/exim-mainlog-*',
:MTA_LOG_TYPE => 'exim',
:NEW_RESPONSE_REMINDER_AFTER_DAYS => [3, 10, 24],
:OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS => '',
diff --git a/spec/models/censor_rule_spec.rb b/spec/models/censor_rule_spec.rb
index 5b41cc0d4..4ecd2d3e1 100644
--- a/spec/models/censor_rule_spec.rb
+++ b/spec/models/censor_rule_spec.rb
@@ -90,17 +90,32 @@ end
describe 'when validating rules' do
- it 'should be invalid without text' do
+ it 'must have the text to redact' do
censor_rule = CensorRule.new
- censor_rule.valid?.should == false
- censor_rule.errors[:text].should == ["can't be blank"]
+ expect(censor_rule).to have(1).error_on(:text)
+ expect(censor_rule.errors[:text]).to eql(["can't be blank"])
+ end
+
+ it 'must have a replacement' do
+ expect(CensorRule.new).to have(1).error_on(:replacement)
+ end
+
+ it 'must have a last_edit_editor' do
+ expect(CensorRule.new).to have(1).error_on(:last_edit_editor)
+ end
+
+ it 'must have a last_edit_comment' do
+ expect(CensorRule.new).to have(1).error_on(:last_edit_comment)
end
describe 'when validating a regexp rule' do
before do
@censor_rule = CensorRule.new(:regexp => true,
- :text => '*')
+ :text => '*',
+ :replacement => '---',
+ :last_edit_comment => 'test',
+ :last_edit_editor => 'rspec')
end
it 'should try to create a regexp from the text' do
@@ -133,7 +148,10 @@ describe 'when validating rules' do
describe 'when the allow_global flag has been set' do
before do
- @censor_rule = CensorRule.new(:text => 'some text')
+ @censor_rule = CensorRule.new(:text => 'some text',
+ :replacement => '---',
+ :last_edit_comment => 'test',
+ :last_edit_editor => 'rspec')
@censor_rule.allow_global = true
end
@@ -146,7 +164,10 @@ describe 'when validating rules' do
describe 'when the allow_global flag has not been set' do
before do
- @censor_rule = CensorRule.new(:text => '/./')
+ @censor_rule = CensorRule.new(:text => '/./',
+ :replacement => '---',
+ :last_edit_comment => 'test',
+ :last_edit_editor => 'rspec')
end
it 'should not allow a global text censor rule (without user_id, request_id or public_body_id)' do
diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb
index a7544c218..225958cac 100644
--- a/spec/models/public_body_spec.rb
+++ b/spec/models/public_body_spec.rb
@@ -546,6 +546,58 @@ CSV
errors.should include("error: line 3: Url name URL name is already taken for authority 'Foobar Test'")
end
+ it 'has a default list of fields to import' do
+ expected_fields = [
+ ['name', '(i18n)<strong>Existing records cannot be renamed</strong>'],
+ ['short_name', '(i18n)'],
+ ['request_email', '(i18n)'],
+ ['notes', '(i18n)'],
+ ['publication_scheme', '(i18n)'],
+ ['disclosure_log', '(i18n)'],
+ ['home_page', ''],
+ ['tag_string', '(tags separated by spaces)'],
+ ]
+
+ expect(PublicBody.csv_import_fields).to eq(expected_fields)
+ end
+
+ it 'allows you to override the default list of fields to import' do
+ old_csv_import_fields = PublicBody.csv_import_fields.clone
+ expected_fields = [
+ ['name', '(i18n)<strong>Existing records cannot be renamed</strong>'],
+ ['short_name', '(i18n)'],
+ ]
+
+ PublicBody.csv_import_fields = expected_fields
+
+ expect(PublicBody.csv_import_fields).to eq(expected_fields)
+
+ # Reset our change so that we don't affect other specs
+ PublicBody.csv_import_fields = old_csv_import_fields
+ end
+
+ it 'allows you to append to the default list of fields to import' do
+ old_csv_import_fields = PublicBody.csv_import_fields.clone
+ expected_fields = [
+ ['name', '(i18n)<strong>Existing records cannot be renamed</strong>'],
+ ['short_name', '(i18n)'],
+ ['request_email', '(i18n)'],
+ ['notes', '(i18n)'],
+ ['publication_scheme', '(i18n)'],
+ ['disclosure_log', '(i18n)'],
+ ['home_page', ''],
+ ['tag_string', '(tags separated by spaces)'],
+ ['a_new_field', ''],
+ ]
+
+ PublicBody.csv_import_fields << ['a_new_field', '']
+
+ expect(PublicBody.csv_import_fields).to eq(expected_fields)
+
+ # Reset our change so that we don't affect other specs
+ PublicBody.csv_import_fields = old_csv_import_fields
+ end
+
end
describe PublicBody do