diff options
52 files changed, 204 insertions, 89 deletions
diff --git a/.gitignore b/.gitignore index 994f9a3a1..99c1ba9ff 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ config/httpd.conf config/general*.yml config/deploy.yml.* .sass-cache -alaveteli.sublime* +alaveteli*.sublime* webrat.log /.rbenv-version /db/development_structure.sql @@ -15,7 +15,7 @@ gem 'icalendar', '1.4.3' gem 'jquery-rails', '~> 3.0.4' gem 'jquery-ui-rails', '~> 4.1.0' gem 'json', '~> 1.8.1' -gem 'holidays', '~> 1.0.8' +gem 'holidays', '~> 1.2.0' gem 'iso_country_codes', '~> 0.6.1' gem 'mahoro', '~> 0.4' gem 'memcache-client', '~> 1.8.5' @@ -26,8 +26,7 @@ gem 'rack', '~> 1.4.5' gem 'rake', '0.9.2.2' gem 'rails-i18n', '~> 0.7.3' gem 'recaptcha', '~> 0.3.1', :require => 'recaptcha/rails' -# :require avoids "already initialized constant" warnings -gem 'rmagick', '~> 2.13.2', :require => 'RMagick' +gem 'rmagick', '~> 2.14.0' gem 'ruby-msg', '~> 1.5.0', :git => 'git://github.com/mysociety/ruby-msg.git' gem 'secure_headers', '~> 1.3.4' gem 'statistics2', '~> 0.54' @@ -36,7 +35,7 @@ gem 'thin', '~> 1.5.1' gem 'vpim', '~> 13.11.11' gem 'will_paginate', '~> 3.0.5' # when 1.2.9 is released by the maintainer, we can stop using this fork: -gem 'xapian-full-alaveteli', '~> 1.2.9.5' +gem 'xapian-full-alaveteli', '~> 1.2.9.7' gem 'xml-simple', '~> 1.1.2', :require => 'xmlsimple' gem 'zip', '~> 2.0.2' diff --git a/Gemfile.lock b/Gemfile.lock index 2f88a474e..32b09a723 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -127,7 +127,7 @@ GEM tilt highline (1.6.19) hike (1.2.3) - holidays (1.0.8) + holidays (1.2.0) i18n (0.6.11) icalendar (1.4.3) iso_country_codes (0.6.1) @@ -216,7 +216,7 @@ GEM ref (1.0.5) rest-client (1.6.7) mime-types (>= 1.16) - rmagick (2.13.2) + rmagick (2.14.0) routing-filter (0.3.1) actionpack rspec-core (2.13.1) @@ -291,7 +291,7 @@ GEM rack (>= 1.0) rack-test (>= 0.5.3) will_paginate (3.0.5) - xapian-full-alaveteli (1.2.9.5) + xapian-full-alaveteli (1.2.9.7) xml-simple (1.1.2) zip (2.0.2) @@ -318,7 +318,7 @@ DEPENDENCIES gettext (~> 2.3.9) gettext_i18n_rails (~> 0.9.4) globalize3! - holidays (~> 1.0.8) + holidays (~> 1.2.0) icalendar (= 1.4.3) iso_country_codes (~> 0.6.1) jquery-rails (~> 3.0.4) @@ -342,7 +342,7 @@ DEPENDENCIES rake (= 0.9.2.2) rdoc (~> 3.12.2) recaptcha (~> 0.3.1) - rmagick (~> 2.13.2) + rmagick (~> 2.14.0) routing-filter (~> 0.3.1) rspec-rails (~> 2.13.2) ruby-debug (~> 0.10.4) @@ -360,6 +360,6 @@ DEPENDENCIES vpim (~> 13.11.11) webrat (~> 0.7.3) will_paginate (~> 3.0.5) - xapian-full-alaveteli (~> 1.2.9.5) + xapian-full-alaveteli (~> 1.2.9.7) xml-simple (~> 1.1.2) zip (~> 2.0.2) diff --git a/app/assets/images/icon_application_octet-stream_large.png b/app/assets/images/icon_application_octet-stream_large.png Binary files differindex a239862e1..a23916e9c 100644 --- a/app/assets/images/icon_application_octet-stream_large.png +++ b/app/assets/images/icon_application_octet-stream_large.png diff --git a/app/assets/images/icon_application_pdf_large.png b/app/assets/images/icon_application_pdf_large.png Binary files differindex 9a38ca33c..990b96c0a 100644 --- a/app/assets/images/icon_application_pdf_large.png +++ b/app/assets/images/icon_application_pdf_large.png diff --git a/app/assets/images/icon_application_rtf_large.png b/app/assets/images/icon_application_rtf_large.png Binary files differindex 2ad990608..977972124 100644 --- a/app/assets/images/icon_application_rtf_large.png +++ b/app/assets/images/icon_application_rtf_large.png diff --git a/app/assets/images/icon_application_vnd.ms-excel_large.png b/app/assets/images/icon_application_vnd.ms-excel_large.png Binary files differindex 3f346f5ef..acca5d92c 100644 --- a/app/assets/images/icon_application_vnd.ms-excel_large.png +++ b/app/assets/images/icon_application_vnd.ms-excel_large.png diff --git a/app/assets/images/icon_application_vnd.ms-powerpoint_large.png b/app/assets/images/icon_application_vnd.ms-powerpoint_large.png Binary files differindex 82c225059..9a1582930 100644 --- a/app/assets/images/icon_application_vnd.ms-powerpoint_large.png +++ b/app/assets/images/icon_application_vnd.ms-powerpoint_large.png diff --git a/app/assets/images/icon_application_vnd.ms-word_large.png b/app/assets/images/icon_application_vnd.ms-word_large.png Binary files differindex 91a696ab5..2f3cb8efa 100644 --- a/app/assets/images/icon_application_vnd.ms-word_large.png +++ b/app/assets/images/icon_application_vnd.ms-word_large.png diff --git a/app/assets/images/icon_application_zip_large.png b/app/assets/images/icon_application_zip_large.png Binary files differindex 0a14e978e..c52d6d5aa 100644 --- a/app/assets/images/icon_application_zip_large.png +++ b/app/assets/images/icon_application_zip_large.png diff --git a/app/assets/images/icon_image_bmp_large.png b/app/assets/images/icon_image_bmp_large.png Binary files differindex f6e8dbaed..347bdaaf1 100644..120000 --- a/app/assets/images/icon_image_bmp_large.png +++ b/app/assets/images/icon_image_bmp_large.png diff --git a/app/assets/images/icon_image_gif_large.png b/app/assets/images/icon_image_gif_large.png Binary files differindex 424d1e0fd..347bdaaf1 100644..120000 --- a/app/assets/images/icon_image_gif_large.png +++ b/app/assets/images/icon_image_gif_large.png diff --git a/app/assets/images/icon_image_img_large.png b/app/assets/images/icon_image_img_large.png Binary files differnew file mode 100644 index 000000000..e19e7553c --- /dev/null +++ b/app/assets/images/icon_image_img_large.png diff --git a/app/assets/images/icon_image_jpeg_large.png b/app/assets/images/icon_image_jpeg_large.png Binary files differindex fd50a889d..347bdaaf1 100644..120000 --- a/app/assets/images/icon_image_jpeg_large.png +++ b/app/assets/images/icon_image_jpeg_large.png diff --git a/app/assets/images/icon_image_png_large.png b/app/assets/images/icon_image_png_large.png Binary files differindex f16edb08e..347bdaaf1 100644..120000 --- a/app/assets/images/icon_image_png_large.png +++ b/app/assets/images/icon_image_png_large.png diff --git a/app/assets/images/icon_image_tiff_large.png b/app/assets/images/icon_image_tiff_large.png Binary files differindex 356f63478..000bd0318 100644 --- a/app/assets/images/icon_image_tiff_large.png +++ b/app/assets/images/icon_image_tiff_large.png diff --git a/app/assets/images/icon_message_delivery-status_large.png b/app/assets/images/icon_message_delivery-status_large.png Binary files differindex a239862e1..dccdbbccd 100644 --- a/app/assets/images/icon_message_delivery-status_large.png +++ b/app/assets/images/icon_message_delivery-status_large.png diff --git a/app/assets/images/icon_text_html_large.png b/app/assets/images/icon_text_html_large.png Binary files differindex 914502cf4..3813d2582 100644 --- a/app/assets/images/icon_text_html_large.png +++ b/app/assets/images/icon_text_html_large.png diff --git a/app/assets/images/icon_text_plain_large.png b/app/assets/images/icon_text_plain_large.png Binary files differindex f74a997ba..f15b0dbdc 100644 --- a/app/assets/images/icon_text_plain_large.png +++ b/app/assets/images/icon_text_plain_large.png diff --git a/app/assets/images/icon_text_x-vcard_large.png b/app/assets/images/icon_text_x-vcard_large.png Binary files differindex cc44d3edc..804066af8 100644 --- a/app/assets/images/icon_text_x-vcard_large.png +++ b/app/assets/images/icon_text_x-vcard_large.png diff --git a/app/assets/images/icon_unknown.png b/app/assets/images/icon_unknown.png Binary files differindex 992c646c0..9a06d9baa 100644 --- a/app/assets/images/icon_unknown.png +++ b/app/assets/images/icon_unknown.png diff --git a/app/assets/javascripts/general.js b/app/assets/javascripts/general.js index 002eef760..856f4c6d4 100644 --- a/app/assets/javascripts/general.js +++ b/app/assets/javascripts/general.js @@ -34,12 +34,12 @@ $(document).ready(function() { box.width(location.length + " em"); box.find('input').val(location).attr('size', location.length + " em"); box.show(); - box.find('input').select(); box.position({ my: "right center", at: "left bottom", of: this, collision: "fit" }); + box.find('input').select(); return false; }); diff --git a/app/assets/stylesheets/responsive/_global_layout.scss b/app/assets/stylesheets/responsive/_global_layout.scss index d7b24df41..b34a6af74 100644 --- a/app/assets/stylesheets/responsive/_global_layout.scss +++ b/app/assets/stylesheets/responsive/_global_layout.scss @@ -98,3 +98,10 @@ textarea{ padding-right: 0.9375em; } } +.box { + padding: 1em; + + @include respond-min( $main_menu-mobile_menu_cutoff ){ + padding: 1.2em; + } +} diff --git a/app/assets/stylesheets/responsive/_global_style.scss b/app/assets/stylesheets/responsive/_global_style.scss index 24cddc0d9..27d238962 100644 --- a/app/assets/stylesheets/responsive/_global_style.scss +++ b/app/assets/stylesheets/responsive/_global_style.scss @@ -84,9 +84,6 @@ dd { dt + dd { margin-top: 0.5em; - > p { - margin-top: 0; - } } diff --git a/app/assets/stylesheets/responsive/_header_layout.scss b/app/assets/stylesheets/responsive/_header_layout.scss index b3103e3a9..7c7bdfe97 100644 --- a/app/assets/stylesheets/responsive/_header_layout.scss +++ b/app/assets/stylesheets/responsive/_header_layout.scss @@ -131,25 +131,25 @@ } form{ @include grid-row; - padding-right: 1em; + padding: 1em 1em 0; @include lte-ie7 { display: inline; } + @include respond-min( $main_menu-mobile_menu_cutoff ){ + padding-top: 0; + } } input{ - @include grid-column($columns:9); - margin:0; + @include grid-column($columns:10); + margin-right:0; @include lte-ie7 { width: 10.063em; } } - label{ + button[type="submit"]{ @include prefix-postfix-base; - @include grid-column($columns:3,$float:left); + @include grid-column($columns:2,$float:right); border:none; - img{ - max-width: 100%; - } @include lte-ie7 { width: 2.125em; } diff --git a/app/assets/stylesheets/responsive/_header_style.scss b/app/assets/stylesheets/responsive/_header_style.scss index 9008a73a7..ec1e8ea5c 100644 --- a/app/assets/stylesheets/responsive/_header_style.scss +++ b/app/assets/stylesheets/responsive/_header_style.scss @@ -2,3 +2,9 @@ #navigation { border-bottom: 1px solid #e9e9e9; } + +#navigation_search { + button[type="submit"] { + background:image-url('/assets/search.png') transparent no-repeat center center; + } +} diff --git a/app/assets/stylesheets/responsive/_request_style.scss b/app/assets/stylesheets/responsive/_request_style.scss index e6f36674a..44ca9a288 100644 --- a/app/assets/stylesheets/responsive/_request_style.scss +++ b/app/assets/stylesheets/responsive/_request_style.scss @@ -3,12 +3,9 @@ div.correspondence { border: 1px solid #ccc; margin: 0 0 1em; - padding: 1em; - @include respond-min( $main_menu-mobile_menu_cutoff ){ - padding: 1.5em; - } h2 { + margin-top: 0; text-align:right; font-size:1em; } @@ -31,7 +28,6 @@ div.correspondence { div.comment_in_request { border: 1px dotted #ccc; margin:0 0 1em 3em; - padding:0 0.5em; h2 { font-size:1em; @@ -42,13 +38,9 @@ div.comment_in_request { } .event_actions { + margin-bottom: 0; text-align:right; line-height: 1em; - margin-bottom: 1em; -} - -.comment_in_request_text { - margin:0 1.2em 0 0.9em; } .user_photo_on_request img { @@ -64,7 +56,6 @@ div.comment_in_request { height:36px; float:left; vertical-align:middle; - margin-top: 0.5em; margin-right:0.5em; } @@ -86,11 +77,9 @@ a img.attachment_image { } .describe_state_form,#other_recipients { - border-radius:3px; -moz-border-radius:3px; margin:1em 0; - padding:0.5em 1em; } .describe_state_form { diff --git a/app/assets/stylesheets/responsive/_utils.scss b/app/assets/stylesheets/responsive/_utils.scss index 68884fa7a..e19201475 100644 --- a/app/assets/stylesheets/responsive/_utils.scss +++ b/app/assets/stylesheets/responsive/_utils.scss @@ -33,3 +33,18 @@ $lte-ie7: false !default; @content; } } + +// Hide content visually, but keep it available to screen readers +// source: http://a11yproject.com/posts/how-to-hide-content/ +.visually-hidden { + // http://developer.yahoo.com/blogs/ydn/posts/2012/10/clip-your-hidden-content-for-better-accessibility/ + position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + padding:0 !important; + border:0 !important; + height: 1px !important; + width: 1px !important; + overflow: hidden; +} +body:hover .visually-hidden a, body:hover .visually-hidden input, body:hover .visually-hidden button { display: none !important; } diff --git a/app/models/info_request.rb b/app/models/info_request.rb index fd42ccd9c..7f6b358db 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -904,21 +904,24 @@ public # Completely delete this request and all objects depending on it def fully_destroy - self.track_things.each do |track_thing| + track_things.each do |track_thing| track_thing.track_things_sent_emails.each { |a| a.destroy } track_thing.destroy end - self.user_info_request_sent_alerts.each { |a| a.destroy } - self.info_request_events.each do |info_request_event| + user_info_request_sent_alerts.each { |a| a.destroy } + info_request_events.each do |info_request_event| info_request_event.track_things_sent_emails.each { |a| a.destroy } info_request_event.destroy end - self.mail_server_logs.each do |mail_server_log| + mail_server_logs.each do |mail_server_log| mail_server_log.destroy end - self.outgoing_messages.each { |a| a.destroy } - self.incoming_messages.each { |a| a.destroy } - self.destroy + outgoing_messages.each { |a| a.destroy } + incoming_messages.each { |a| a.destroy } + comments.each { |comment| comment.destroy } + censor_rules.each{ |censor_rule| censor_rule.destroy } + + destroy end # Called by incoming_email - and used to be called to generate separate diff --git a/app/models/public_body.rb b/app/models/public_body.rb index 232c0ffa1..cb412f9dc 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -774,10 +774,7 @@ class PublicBody < ActiveRecord::Base end def empty_translation_in_params?(attributes) - attrs_with_values = attributes.select do |key, value| - value != '' and key.to_s != 'locale' - end - attrs_with_values.empty? + attributes.select { |k, v| !v.blank? && k.to_s != 'locale' }.empty? end def request_email_if_requestable diff --git a/app/views/comment/_single_comment.html.erb b/app/views/comment/_single_comment.html.erb index 07017dabf..badc39d9a 100644 --- a/app/views/comment/_single_comment.html.erb +++ b/app/views/comment/_single_comment.html.erb @@ -1,4 +1,4 @@ -<div class="comment_in_request" id="comment-<%=comment.id.to_s%>"> +<div class="comment_in_request box" id="comment-<%=comment.id.to_s%>"> <% if comment.user && comment.user.profile_photo && !@render_to_file %> <div class="user_photo_on_comment"> <img src="<%= get_profile_photo_url(:url_name => comment.user.url_name) %>" alt=""> diff --git a/app/views/general/_responsive_topnav.html.erb b/app/views/general/_responsive_topnav.html.erb index 0af6629c8..c99864cab 100644 --- a/app/views/general/_responsive_topnav.html.erb +++ b/app/views/general/_responsive_topnav.html.erb @@ -21,11 +21,16 @@ </li> <li id="navigation_search"> - <form id="navigation_search_form" method="get" action="<%= search_redirect_path %>"> - <label for="navigation_search_button"> - <img src="/assets/search.png" alt="Search:"> + <form id="navigation_search_form" method="get" action="<%= search_redirect_path %>" role="search"> + <label class="visually-hidden" for="navigation_search_button"> + <%= _("Search") %> </label> - <%= text_field_tag 'query', params[:query], { :id => "navigation_search_button", :title => "type your search term here" } %> + <%= text_field_tag 'query', params[:query], { :id => "navigation_search_button", :type => "search", :placeholder => _("Search"), :title => _("type your search term here") } %> + <button type="submit"> + <span class="visually-hidden"> + <%= _("Submit Search") %> + </span> + </button> </form> </li> </ul> diff --git a/app/views/help/unhappy.html.erb b/app/views/help/unhappy.html.erb index 79e3f8273..c0444fb54 100644 --- a/app/views/help/unhappy.html.erb +++ b/app/views/help/unhappy.html.erb @@ -101,9 +101,8 @@ contact any registered user from their page. There may be an Internet forum or group that they hang out in. If it is a local matter, use <a href="http://www.groupsnearyou.com">GroupsNearYou</a> to find such a forum.</li> -<li><strong>Start a pledge</strong> on <a href="http://www.pledgebank.com">PledgeBank</a> to get -others to act together with you. For example, you could arrange a meeting with -staff from the authority. Or you could form a small local campaigns group. +<li>You could form a small local campaign group and arrange a meeting +with staff from the authority.</li> </ul> diff --git a/app/views/request/_followup.html.erb b/app/views/request/_followup.html.erb index 2643b767f..24cede824 100644 --- a/app/views/request/_followup.html.erb +++ b/app/views/request/_followup.html.erb @@ -20,7 +20,7 @@ </h2> <% end %> <% if @info_request.who_can_followup_to(incoming_message).count > 0 %> -<div id="other_recipients"> +<div id="other_recipients" class="box"> <%= _("Don't want to address your message to {{person_or_body}}? You can also write to:", :person_or_body => name_for_followup) %> <ul> <% @info_request.who_can_followup_to(incoming_message).each do |name, email, id| %> diff --git a/app/views/request/_incoming_correspondence.html.erb b/app/views/request/_incoming_correspondence.html.erb index 70bd25c7f..9d205204e 100644 --- a/app/views/request/_incoming_correspondence.html.erb +++ b/app/views/request/_incoming_correspondence.html.erb @@ -1,4 +1,4 @@ -<div class="incoming correspondence <%= incoming_message.prominence %>" id="incoming-<%=incoming_message.id.to_s%>"> +<div class="incoming correspondence box <%= incoming_message.prominence %>" id="incoming-<%=incoming_message.id.to_s%>"> <%- if not incoming_message.user_can_view?(@user) %> <%= render :partial => 'request/hidden_correspondence', :locals => { :message => incoming_message }%> <%- else %> diff --git a/app/views/request/_outgoing_correspondence.html.erb b/app/views/request/_outgoing_correspondence.html.erb index dced5c94c..3b85cae7f 100644 --- a/app/views/request/_outgoing_correspondence.html.erb +++ b/app/views/request/_outgoing_correspondence.html.erb @@ -1,4 +1,4 @@ -<div class="outgoing correspondence" id="outgoing-<%=outgoing_message.id.to_s%>"> +<div class="outgoing correspondence box" id="outgoing-<%=outgoing_message.id.to_s%>"> <%- if not outgoing_message.user_can_view?(@user) %> <%= render :partial => 'request/hidden_correspondence', :locals => { :message => outgoing_message }%> <%- else %> diff --git a/app/views/request/_resent_outgoing_correspondence.html.erb b/app/views/request/_resent_outgoing_correspondence.html.erb index 17b6b635b..287a5cac5 100644 --- a/app/views/request/_resent_outgoing_correspondence.html.erb +++ b/app/views/request/_resent_outgoing_correspondence.html.erb @@ -1,4 +1,4 @@ -<div class="outgoing correspondence" id="outgoing-<%=outgoing_message.id.to_s%>"> +<div class="outgoing correspondence box" id="outgoing-<%=outgoing_message.id.to_s%>"> <h2> <%= simple_date(info_request_event.created_at) %> </h2> diff --git a/app/views/request/new.html.erb b/app/views/request/new.html.erb index 486a89d45..23f7ad76a 100644 --- a/app/views/request/new.html.erb +++ b/app/views/request/new.html.erb @@ -144,7 +144,7 @@ <% if @info_request.public_body.info_requests.size > 0 %> <%= _("Browse <a href='{{url}}'>other requests</a> to '{{public_body_name}}' for examples of how to word your request.", :public_body_name=>h(@info_request.public_body.name), :url=>public_body_path(@info_request.public_body)) %> <% else %> - <%= _("Browse <a href='{{url}}'>other requests</a> for examples of how to word your request.", :url=>request_list_url) %> + <%= _("Browse <a href='{{url}}'>other requests</a> for examples of how to word your request.", :url=>request_list_successful_url) %> <% end %> </p> <% end %> @@ -156,7 +156,7 @@ this website <a href="{{url}}">forever</a>', :url => (help_privacy_path+"#public_request").html_safe)) %>. </p> <p> - <%= raw(_('<a href="{{url}}">Thinking of using a pseudonym?</a>.', :url => (help_privacy_path+"#real_name").html_safe)) %> + <%= raw(_('<a href="{{url}}">Thinking of using a pseudonym?</a>', :url => (help_privacy_path+"#real_name").html_safe)) %> </p> <% else %> <p> diff --git a/app/views/request/show.html.erb b/app/views/request/show.html.erb index 78e022aa9..5862413de 100644 --- a/app/views/request/show.html.erb +++ b/app/views/request/show.html.erb @@ -22,7 +22,7 @@ <% if ( @update_status || @info_request.awaiting_description ) && ! @info_request.is_external? %> - <div class="describe_state_form" id="describe_state_form_1"> + <div class="describe_state_form box" id="describe_state_form_1"> <%= render :partial => 'describe_state', :locals => { :id_suffix => "1" } %> </div> <% end %> @@ -146,7 +146,7 @@ <% end %> <% if @info_request.awaiting_description && ! @info_request.is_external? %> - <div class="describe_state_form" id="describe_state_form_2"> + <div class="describe_state_form box" id="describe_state_form_2"> <%= render :partial => 'describe_state', :locals => { :id_suffix => "2" } %> </div> <% end %> diff --git a/config/environments/production.rb b/config/environments/production.rb index a3e3cebd2..af2ca15b9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -17,7 +17,20 @@ Alaveteli::Application.configure do # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false - config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors + + config.action_mailer.delivery_method = AlaveteliConfiguration::production_mailer_delivery_method.to_sym + + if AlaveteliConfiguration::production_mailer_delivery_method.to_sym == :smtp + config.action_mailer.smtp_settings = { + :address => AlaveteliConfiguration::smtp_mailer_address, + :port => AlaveteliConfiguration.smtp_mailer_port, + :domain => AlaveteliConfiguration.smtp_mailer_domain, + :user_name => AlaveteliConfiguration.smtp_mailer_user_name, + :password => AlaveteliConfiguration.smtp_mailer_password, + :authentication => AlaveteliConfiguration.smtp_mailer_authentication, + :enable_starttls_auto => AlaveteliConfiguration.smtp_mailer_enable_starttls_auto + } + end config.active_support.deprecation = :notify diff --git a/config/general.yml-example b/config/general.yml-example index 8acea374b..88d89958d 100644 --- a/config/general.yml-example +++ b/config/general.yml-example @@ -775,3 +775,30 @@ ALLOW_BATCH_REQUESTS: false # # --- RESPONSIVE_STYLING: true + +# Define the mailer delivery method to be used only in the production environment. +# By default, use sendmail. +# +# The list of accepted options are available in the Rails ActionMailer configuration +# documentation: http://guides.rubyonrails.org/action_mailer_basics.html#example-action-mailer-configuration +# +# The most common alternative is to use 'smtp' +# If you choose to use an external SMTP service then you will need to also include the SMTP configuration settings. +# +# As a string this is coerced into a symbol in config/environments/production.rb +# +# PRODUCTION_MAILER_DELIVERY_METHOD - String (default: sendmail) +# +# Examples: +# +# PRODUCTION_MAILER_DELIVERY_METHOD: smtp +# SMTP_MAILER_ADDRESS: smtp.gmail.com +# SMTP_MAILER_PORT: 587 +# SMTP_MAILER_DOMAIN: example.com +# SMTP_MAILER_USER_NAME: jane322 +# SMTP_MAILER_PASSWORD: supersecretpassword +# SMTP_MAILER_AUTHENTICATION: 'plain' +# SMTP_MAILER_ENABLE_STARTTLS_AUTO: true +# --- +PRODUCTION_MAILER_DELIVERY_METHOD: sendmail + diff --git a/doc/CHANGES.md b/doc/CHANGES.md index a654f3b6a..9b54a0b52 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -1,3 +1,10 @@ +# rails-3-develop + +## Highlighted Features +* There is experimental support for using an STMP server, rather than sendmail, + for outgoing mail. There is not yet any ability to retry if the SMTP server is + unavailable. + # Version 0.21 ## Highlighted Features diff --git a/lib/alaveteli_text_masker.rb b/lib/alaveteli_text_masker.rb index 68ff0d318..5d836f66c 100644 --- a/lib/alaveteli_text_masker.rb +++ b/lib/alaveteli_text_masker.rb @@ -28,9 +28,7 @@ module AlaveteliTextMasker end def apply_pdf_masks!(text, options = {}) - uncompressed_text = nil - uncompressed_text = AlaveteliExternalCommand.run("pdftk", "-", "output", "-", "uncompress", - :stdin_string => text) + uncompressed_text = uncompress_pdf(text) # if we managed to uncompress the PDF... if !uncompressed_text.blank? # then censor stuff (making a copy so can compare again in a bit) @@ -39,19 +37,13 @@ module AlaveteliTextMasker # if the censor rule removed something... if censored_uncompressed_text != uncompressed_text # then use the altered file (recompressed) - recompressed_text = nil - if AlaveteliConfiguration::use_ghostscript_compression == true - command = ["gs", "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4", "-dPDFSETTINGS=/screen", "-dNOPAUSE", "-dQUIET", "-dBATCH", "-sOutputFile=-", "-"] - else - command = ["pdftk", "-", "output", "-", "compress"] - end - recompressed_text = AlaveteliExternalCommand.run(*(command + [{:stdin_string=>censored_uncompressed_text}])) + recompressed_text = compress_pdf(censored_uncompressed_text) if recompressed_text.blank? # buggy versions of pdftk sometimes fail on # compression, I don't see it's a disaster in # these cases to save an uncompressed version? recompressed_text = censored_uncompressed_text - logger.warn "Unable to compress PDF; problem with your pdftk version?" + Rails.logger.warn "Unable to compress PDF; problem with your pdftk version?" end if !recompressed_text.blank? text.replace recompressed_text @@ -62,6 +54,27 @@ module AlaveteliTextMasker private + def uncompress_pdf(text) + AlaveteliExternalCommand.run("pdftk", "-", "output", "-", "uncompress", :stdin_string => text) + end + + def compress_pdf(text) + if AlaveteliConfiguration::use_ghostscript_compression + command = ["gs", + "-sDEVICE=pdfwrite", + "-dCompatibilityLevel=1.4", + "-dPDFSETTINGS=/screen", + "-dNOPAUSE", + "-dQUIET", + "-dBATCH", + "-sOutputFile=-", + "-"] + else + command = ["pdftk", "-", "output", "-", "compress"] + end + AlaveteliExternalCommand.run(*(command + [ :stdin_string => text ])) + end + # Replace text in place def apply_binary_masks!(text, options = {}) # Keep original size, so can check haven't resized it diff --git a/lib/configuration.rb b/lib/configuration.rb index 90fd30d5f..7921b93fa 100644 --- a/lib/configuration.rb +++ b/lib/configuration.rb @@ -52,6 +52,7 @@ module AlaveteliConfiguration :MTA_LOG_TYPE => 'exim', :NEW_RESPONSE_REMINDER_AFTER_DAYS => [3, 10, 24], :OVERRIDE_ALL_PUBLIC_BODY_REQUEST_EMAILS => '', + :PRODUCTION_MAILER_DELIVERY_METHOD => 'sendmail', :PUBLIC_BODY_STATISTICS_PAGE => false, :PUBLIC_BODY_LIST_FALLBACK_TO_DEFAULT_LOCALE => false, :RAW_EMAILS_LOCATION => 'files/raw_emails', @@ -63,6 +64,13 @@ module AlaveteliConfiguration :RESPONSIVE_STYLING => true, :SITE_NAME => 'Alaveteli', :SKIP_ADMIN_AUTH => false, + :SMTP_MAILER_ADDRESS => 'localhost', + :SMTP_MAILER_PORT => 25, + :SMTP_MAILER_DOMAIN => '', + :SMTP_MAILER_USER_NAME => '', + :SMTP_MAILER_PASSWORD => '', + :SMTP_MAILER_AUTHENTICATION => 'plain', + :SMTP_MAILER_ENABLE_STARTTLS_AUTO => true, :SPECIAL_REPLY_VERY_LATE_AFTER_DAYS => 60, :THEME_BRANCH => false, :THEME_URL => "", @@ -77,9 +85,9 @@ module AlaveteliConfiguration :USE_MAILCATCHER_IN_DEVELOPMENT => true, :UTILITY_SEARCH_PATH => ["/usr/bin", "/usr/local/bin"], :VARNISH_HOST => '', - :WORKING_OR_CALENDAR_DAYS => 'working', + :WORKING_OR_CALENDAR_DAYS => 'working' } - end + end def AlaveteliConfiguration.method_missing(name) key = name.to_s.upcase diff --git a/spec/controllers/admin_public_body_categories_controller_spec.rb b/spec/controllers/admin_public_body_categories_controller_spec.rb index 1131b3c0b..c15ee77f1 100644 --- a/spec/controllers/admin_public_body_categories_controller_spec.rb +++ b/spec/controllers/admin_public_body_categories_controller_spec.rb @@ -310,7 +310,7 @@ describe AdminPublicBodyCategoriesController do post :update, :id => category.id, :public_body_category => category.serializable_hash.except(:title, :description) - expect(assigns(:tagged_public_bodies)).to eq(expected_bodies) + expect(assigns(:tagged_public_bodies)).to match_array(expected_bodies) end it "saves edits to a public body category's heading associations" do diff --git a/spec/integration/admin_public_body_edit_spec.rb b/spec/integration/admin_public_body_edit_spec.rb index aeec3e65a..21011b172 100644 --- a/spec/integration/admin_public_body_edit_spec.rb +++ b/spec/integration/admin_public_body_edit_spec.rb @@ -39,7 +39,7 @@ describe 'Editing a Public Body' do end end - it 'can add a translation for multiple locales', :focus => true do + it 'can add a translation for multiple locales' do @admin.visit edit_admin_body_path(@body) @admin.fill_in 'public_body_name__en', :with => 'New Quango EN' @admin.click_button 'Save' diff --git a/spec/integration/xapian_search_highlighting_spec.rb b/spec/integration/xapian_search_highlighting_spec.rb index 65a34cf91..b2994eb31 100644 --- a/spec/integration/xapian_search_highlighting_spec.rb +++ b/spec/integration/xapian_search_highlighting_spec.rb @@ -3,6 +3,10 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe 'highlighting search results' do include HighlightHelper + before do + get_fixtures_xapian_index + end + it 'ignores stopwords' do phrase = 'department of humpadinking' search = ActsAsXapian::Search.new([PublicBody], phrase, :limit => 1) diff --git a/spec/lib/alaveteli_text_masker_spec.rb b/spec/lib/alaveteli_text_masker_spec.rb index 1a4782a83..102d2582e 100644 --- a/spec/lib/alaveteli_text_masker_spec.rb +++ b/spec/lib/alaveteli_text_masker_spec.rb @@ -92,6 +92,23 @@ describe AlaveteliTextMasker do pdf.should_not == "" end + it 'should keep the uncensored original if uncompression of a PDF fails' do + orig_pdf = load_file_fixture('tfl.pdf') + pdf = orig_pdf.dup + stub!(:uncompress_pdf).and_return nil + apply_masks!(pdf, "application/pdf") + pdf.should == orig_pdf + end + + it 'should use the uncompressed PDF text if re-compression of a compressed PDF fails' do + orig_pdf = load_file_fixture('tfl.pdf') + pdf = orig_pdf.dup + stub!(:uncompress_pdf).and_return "something about foi@tfl.gov.uk" + stub!(:compress_pdf).and_return nil + apply_masks!(pdf, "application/pdf") + pdf.should match "something about xxx@xxx.xxx.xx" + end + it "should apply hard-coded privacy rules to HTML files" do data = "http://test.host/c/cheese" apply_masks!(data, 'text/html') diff --git a/spec/lib/mail_handler/mail_handler_spec.rb b/spec/lib/mail_handler/mail_handler_spec.rb index e7ad93300..ea7a99b05 100644 --- a/spec/lib/mail_handler/mail_handler_spec.rb +++ b/spec/lib/mail_handler/mail_handler_spec.rb @@ -9,7 +9,7 @@ end describe 'when creating a mail object from raw data' do - it "should be able to parse a large email without raising an exception", :focus => true do + it "should be able to parse a large email without raising an exception" do m = Mail.new m.add_file(:filename => "attachment.data", :content => "a" * (8 * 1024 * 1024)) raw_email = "From jamis_buck@byu.edu Mon May 2 16:07:05 2005\r\n#{m.to_s}" @@ -22,7 +22,7 @@ describe 'when creating a mail object from raw data' do mail.multipart?.should == true end - it "should not fail on invalid byte sequence in content-disposition header", :focus => true do + it "should not fail on invalid byte sequence in content-disposition header" do part = Mail::Part.new("Content-Disposition: inline; filename=a\xB8z\r\n\r\nThis is the body text.") lambda { part.inline? }.should_not raise_error end diff --git a/spec/models/info_request_batch_spec.rb b/spec/models/info_request_batch_spec.rb index 2881e7745..701422037 100644 --- a/spec/models/info_request_batch_spec.rb +++ b/spec/models/info_request_batch_spec.rb @@ -80,7 +80,7 @@ describe InfoRequestBatch, "when finding an existing batch" do end end -describe InfoRequestBatch, "when creating a batch", :focus => true do +describe InfoRequestBatch, "when creating a batch" do before do @title = 'A test title' diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb index 70947584b..c8bd2c338 100644 --- a/spec/models/info_request_spec.rb +++ b/spec/models/info_request_spec.rb @@ -1313,4 +1313,20 @@ describe InfoRequest do end + + describe 'when destroying a message' do + + it 'can destroy a request with comments and censor rules' do + info_request = FactoryGirl.create(:info_request) + censor_rule = FactoryGirl.create(:censor_rule, :info_request => info_request) + comment = FactoryGirl.create(:comment, :info_request => info_request) + info_request.reload + info_request.fully_destroy + + InfoRequest.where(:id => info_request.id).should be_empty + CensorRule.where(:id => censor_rule.id).should be_empty + Comment.where(:id => comment.id).should be_empty + end + + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 93bcfa1ba..4df1b5649 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -124,13 +124,6 @@ Spork.prefork do end end - # TODO: No idea what namespace/class/module to put this in - # Create a clean xapian index based on the fixture files and the raw_email data. - def create_fixtures_xapian_index - load_raw_emails_data - rebuild_xapian_index - end - # Use the before create job hook to simulate a race condition with # another process by creating an acts_as_xapian_job record for the # same model: |