diff options
58 files changed, 283 insertions, 73 deletions
diff --git a/.hound.yml b/.hound.yml new file mode 100644 index 000000000..574cfe7ac --- /dev/null +++ b/.hound.yml @@ -0,0 +1,11 @@ +# Configuration for https://houndci.com/ + +Style/IndentationWidth: + Description: 'Use 2 spaces for indentation.' + Enabled: false + +Style/HashSyntax: + Description: >- + Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax + { :a => 1, :b => 2 }. + Enabled: false diff --git a/Gemfile.lock b/Gemfile.lock index 32a1e77f5..fd02983c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -243,7 +243,7 @@ GEM hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) - tilt (!= 1.3.0, ~> 1.1) + tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.7) statistics2 (0.54) syslog_protocol (0.9.2) diff --git a/Vagrantfile b/Vagrantfile index 5d56914a5..31b2553a1 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -46,6 +46,15 @@ # Both have the same effect, but exporting will retain the variable for the # duration of your shell session. # +# Using Themes +# ------------ +# +# You can also use the built in theme switcher (script/switch-theme.rb). The +# ALAVETELI_THEMES_DIR will be shared in to /home/vagrant/alaveteli-themes so +# that the default location is used on the guest. You can use the env var +# ALAVETELI_THEMES_DIR to change where this Vagrantfile looks for the themes +# directory on the host. +# # Customization Options # ===================== ALAVETELI_FQDN = ENV['ALAVETELI_VAGRANT_FQDN'] || "alaveteli.10.10.10.30.xip.io" diff --git a/app/assets/images/status/classification.png b/app/assets/images/status/classification.png Binary files differnew file mode 100644 index 000000000..dcf4009f3 --- /dev/null +++ b/app/assets/images/status/classification.png diff --git a/app/assets/images/status/classification@2x.png b/app/assets/images/status/classification@2x.png Binary files differnew file mode 100644 index 000000000..dcf4009f3 --- /dev/null +++ b/app/assets/images/status/classification@2x.png diff --git a/app/assets/images/status/delayed.png b/app/assets/images/status/delayed.png Binary files differnew file mode 100644 index 000000000..637fed8d9 --- /dev/null +++ b/app/assets/images/status/delayed.png diff --git a/app/assets/images/status/delayed@2x.png b/app/assets/images/status/delayed@2x.png Binary files differnew file mode 100644 index 000000000..637fed8d9 --- /dev/null +++ b/app/assets/images/status/delayed@2x.png diff --git a/app/assets/images/status/delivery_error.png b/app/assets/images/status/delivery_error.png Binary files differnew file mode 100644 index 000000000..5865dd1e1 --- /dev/null +++ b/app/assets/images/status/delivery_error.png diff --git a/app/assets/images/status/delivery_error@2x.png b/app/assets/images/status/delivery_error@2x.png Binary files differnew file mode 100644 index 000000000..5865dd1e1 --- /dev/null +++ b/app/assets/images/status/delivery_error@2x.png diff --git a/app/assets/images/status/notheld.png b/app/assets/images/status/notheld.png Binary files differnew file mode 100644 index 000000000..9d20ac2e7 --- /dev/null +++ b/app/assets/images/status/notheld.png diff --git a/app/assets/images/status/notheld@2x.png b/app/assets/images/status/notheld@2x.png Binary files differnew file mode 100644 index 000000000..9d20ac2e7 --- /dev/null +++ b/app/assets/images/status/notheld@2x.png diff --git a/app/assets/images/status/overdue.png b/app/assets/images/status/overdue.png Binary files differnew file mode 100644 index 000000000..637fed8d9 --- /dev/null +++ b/app/assets/images/status/overdue.png diff --git a/app/assets/images/status/overdue@2x.png b/app/assets/images/status/overdue@2x.png Binary files differnew file mode 100644 index 000000000..637fed8d9 --- /dev/null +++ b/app/assets/images/status/overdue@2x.png diff --git a/app/assets/images/status/partiallysuccessful.png b/app/assets/images/status/partiallysuccessful.png Binary files differnew file mode 100644 index 000000000..2ff49770a --- /dev/null +++ b/app/assets/images/status/partiallysuccessful.png diff --git a/app/assets/images/status/partiallysuccessful@2x.png b/app/assets/images/status/partiallysuccessful@2x.png Binary files differnew file mode 100644 index 000000000..2ff49770a --- /dev/null +++ b/app/assets/images/status/partiallysuccessful@2x.png diff --git a/app/assets/images/status/postal.png b/app/assets/images/status/postal.png Binary files differnew file mode 100644 index 000000000..00df771ac --- /dev/null +++ b/app/assets/images/status/postal.png diff --git a/app/assets/images/status/postal@2x.png b/app/assets/images/status/postal@2x.png Binary files differnew file mode 100644 index 000000000..00df771ac --- /dev/null +++ b/app/assets/images/status/postal@2x.png diff --git a/app/assets/images/status/refused.png b/app/assets/images/status/refused.png Binary files differnew file mode 100644 index 000000000..1f768af5e --- /dev/null +++ b/app/assets/images/status/refused.png diff --git a/app/assets/images/status/refused@2x.png b/app/assets/images/status/refused@2x.png Binary files differnew file mode 100644 index 000000000..1f768af5e --- /dev/null +++ b/app/assets/images/status/refused@2x.png diff --git a/app/assets/images/status/reported.png b/app/assets/images/status/reported.png Binary files differnew file mode 100644 index 000000000..9d20ac2e7 --- /dev/null +++ b/app/assets/images/status/reported.png diff --git a/app/assets/images/status/reported@2x.png b/app/assets/images/status/reported@2x.png Binary files differnew file mode 100644 index 000000000..9d20ac2e7 --- /dev/null +++ b/app/assets/images/status/reported@2x.png diff --git a/app/assets/images/status/review.png b/app/assets/images/status/review.png Binary files differnew file mode 100644 index 000000000..639f72797 --- /dev/null +++ b/app/assets/images/status/review.png diff --git a/app/assets/images/status/review@2x.png b/app/assets/images/status/review@2x.png Binary files differnew file mode 100644 index 000000000..639f72797 --- /dev/null +++ b/app/assets/images/status/review@2x.png diff --git a/app/assets/images/status/successful.png b/app/assets/images/status/successful.png Binary files differnew file mode 100644 index 000000000..2ff49770a --- /dev/null +++ b/app/assets/images/status/successful.png diff --git a/app/assets/images/status/successful@2x.png b/app/assets/images/status/successful@2x.png Binary files differnew file mode 100644 index 000000000..2ff49770a --- /dev/null +++ b/app/assets/images/status/successful@2x.png diff --git a/app/assets/images/status/unusual.png b/app/assets/images/status/unusual.png Binary files differnew file mode 100644 index 000000000..637fed8d9 --- /dev/null +++ b/app/assets/images/status/unusual.png diff --git a/app/assets/images/status/unusual@2x.png b/app/assets/images/status/unusual@2x.png Binary files differnew file mode 100644 index 000000000..637fed8d9 --- /dev/null +++ b/app/assets/images/status/unusual@2x.png diff --git a/app/assets/images/status/waiting.png b/app/assets/images/status/waiting.png Binary files differnew file mode 100644 index 000000000..dcf4009f3 --- /dev/null +++ b/app/assets/images/status/waiting.png diff --git a/app/assets/images/status/waiting@2x.png b/app/assets/images/status/waiting@2x.png Binary files differnew file mode 100644 index 000000000..dcf4009f3 --- /dev/null +++ b/app/assets/images/status/waiting@2x.png diff --git a/app/assets/images/status/withdrawn.png b/app/assets/images/status/withdrawn.png Binary files differnew file mode 100644 index 000000000..d56aa213f --- /dev/null +++ b/app/assets/images/status/withdrawn.png diff --git a/app/assets/images/status/withdrawn@2x.png b/app/assets/images/status/withdrawn@2x.png Binary files differnew file mode 100644 index 000000000..d56aa213f --- /dev/null +++ b/app/assets/images/status/withdrawn@2x.png diff --git a/app/assets/stylesheets/responsive/_footer_layout.scss b/app/assets/stylesheets/responsive/_footer_layout.scss index 2b0c956fa..55b6839c2 100644 --- a/app/assets/stylesheets/responsive/_footer_layout.scss +++ b/app/assets/stylesheets/responsive/_footer_layout.scss @@ -45,6 +45,10 @@ img { display: inherit; + @include lte-ie7 { + display: block; + } } + } } diff --git a/app/assets/stylesheets/responsive/_lists_style.scss b/app/assets/stylesheets/responsive/_lists_style.scss index 762901a5f..9f18718f5 100644 --- a/app/assets/stylesheets/responsive/_lists_style.scss +++ b/app/assets/stylesheets/responsive/_lists_style.scss @@ -48,51 +48,135 @@ } } +$status-success: #69952F; +$status-failure: #C1272D; +$status-pending: #A68C2E; + /* Status lines and icons */ -.icon_waiting_response,.icon_waiting_classification,.icon_waiting_clarification { - background-image:image-url('status-pending.png'); - color:#A68C2E; +.icon_waiting_classification { + background-image:image-url('status/classification.png'); + color: $status-pending; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/classification@2x.png'); + } +} + +.icon_waiting_response,.icon_waiting_clarification { + background-image:image-url('status/waiting.png'); + color: $status-pending; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/waiting@2x.png'); + } +} + +.icon_attention_requested { + background-image:image-url('status/reported.png'); + color: $status-pending; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/reported@2x.png'); + } +} + +.icon_not_held { + background-image:image-url('status/notheld.png'); + color: $status-pending; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/notheld@2x.png'); + } +} + +.icon_successful { + background-image:image-url('status/successful.png'); + color: $status-success; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/successful@2x.png'); + } } +.icon_partially_successful { + background-image:image-url('status/partiallysuccessful.png'); + color: $status-success; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/partiallysuccessful@2x.png'); + } +} -.icon_not_held, .icon_attention_requested { - background-image:image-url('status-not-held.png'); - color:#A68C2E; +.icon_requires_admin { + background-image:image-url('status/unusual.png'); + color: $status-failure; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/unusual@2x.png'); + } } -.icon_successful,.icon_partially_successful { - background-image:image-url('status-complete.png'); - color:#69952F; +.icon_waiting_response_overdue { + background-image:image-url('status/delayed.png'); + color: $status-failure; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/delayed@2x.png'); + } } -.icon_requires_admin,.icon_waiting_response_overdue,.icon_waiting_response_very_overdue { - background-image:image-url('status-overdue.png'); - color:#C1272D; +.icon_waiting_response_very_overdue{ + background-image:image-url('status/overdue.png'); + color: $status-failure; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/overdue@2x.png'); + } } .icon_gone_postal { - background-image:image-url('status-gone-postal.png'); - color:#A68C2E; + background-image:image-url('status/postal.png'); + color: $status-pending; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/postal@2x.png'); + } } .icon_error_message { - background-image:image-url('status-error.png'); - color:#C1272D; + background-image:image-url('status/delivery_error.png'); + color: $status-failure; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/delivery_error@2x.png'); + } } .icon_internal_review { - background-image:image-url('status-internal-review.png'); - color:#A68C2E; + background-image:image-url('status/review.png'); + color: $status-pending; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/review@2x.png'); + } } .icon_user_withdrawn { - background-image:image-url('status-withdrawn.png'); - color:#A68C2E; + background-image:image-url('status/withdrawn.png'); + color: $status-pending; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/withdrawn@2x.png'); + } } .icon_failed,.icon_rejected { - background-image:image-url('status-denied.png'); - color:#C1272D; + background-image:image-url('status/refused.png'); + color: $status-failure; + background-size: 22px 22px; + @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image:image-url('status/refused@2x.png'); + } } #public_body_list { diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb index 6f0d29889..e2a2190b0 100644 --- a/app/controllers/general_controller.rb +++ b/app/controllers/general_controller.rb @@ -178,7 +178,9 @@ class GeneralController < ApplicationController format.json { render :json => { :alaveteli_git_commit => alaveteli_git_commit, :alaveteli_version => ALAVETELI_VERSION, - :ruby_version => RUBY_VERSION + :ruby_version => RUBY_VERSION, + :visible_request_count => InfoRequest.visible.count, + :confirmed_user_count => User.where(:email_confirmed => true).count }} end end diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb index 862f4b318..96e69d333 100644 --- a/app/controllers/public_body_controller.rb +++ b/app/controllers/public_body_controller.rb @@ -109,17 +109,17 @@ class PublicBodyController < ApplicationController # Restrict the public bodies shown according to the tag # parameter supplied in the URL: - if @tag.nil? or @tag == "all" - @tag = "all" + if @tag.nil? || @tag == 'all' + @tag = 'all' elsif @tag == 'other' - category_list = PublicBodyCategories::get().tags().map{|c| "'"+c+"'"}.join(",") + category_list = PublicBodyCategories.get.tags.map{ |c| %Q('#{ c }') }.join(",") where_condition += base_tag_condition + " AND has_tag_string_tags.name in (#{category_list})) = 0" elsif @tag.scan(/./mu).size == 1 - @tag = Unicode.upcase @tag + @tag = Unicode.upcase(@tag) # The first letter queries have to be done on # translations, so just indicate to add that later: first_letter = true - elsif @tag.include?(":") + elsif @tag.include?(':') name, value = HasTagString::HasTagStringTag.split_tag_into_name_value(@tag) where_condition += base_tag_condition + " AND has_tag_string_tags.name = ? AND has_tag_string_tags.value = ?) > 0" where_parameters.concat [name, value] @@ -128,16 +128,16 @@ class PublicBodyController < ApplicationController where_parameters.concat [@tag] end - if @tag == "all" - @description = "" + if @tag == 'all' + @description = '' elsif @tag.size == 1 - @description = _("beginning with ‘{{first_letter}}’", :first_letter=>@tag) + @description = _("beginning with ‘{{first_letter}}’", :first_letter => @tag) else - category_name = PublicBodyCategories::get().by_tag()[@tag] + category_name = PublicBodyCategories.get.by_tag[@tag] if category_name.nil? - @description = _("matching the tag ‘{{tag_name}}’", :tag_name=>@tag) + @description = _("matching the tag ‘{{tag_name}}’", :tag_name => @tag) else - @description = _("in the category ‘{{category_name}}’", :category_name=>category_name) + @description = _("in the category ‘{{category_name}}’", :category_name => category_name) end end @@ -151,15 +151,15 @@ class PublicBodyController < ApplicationController FROM public_bodies LEFT OUTER JOIN public_body_translations as current_locale ON (public_bodies.id = current_locale.public_body_id - AND current_locale.locale = ? AND #{get_public_body_list_translated_condition 'current_locale', first_letter}) + AND current_locale.locale = ? AND #{ get_public_body_list_translated_condition('current_locale', first_letter) }) LEFT OUTER JOIN public_body_translations as default_locale ON (public_bodies.id = default_locale.public_body_id - AND default_locale.locale = ? AND #{get_public_body_list_translated_condition 'default_locale', first_letter}) - WHERE #{where_condition} AND COALESCE(current_locale.name, default_locale.name) IS NOT NULL + AND default_locale.locale = ? AND #{ get_public_body_list_translated_condition('default_locale', first_letter) }) + WHERE #{ where_condition } AND COALESCE(current_locale.name, default_locale.name) IS NOT NULL ORDER BY display_name} - sql = [query, underscore_locale, like_query, like_query] + sql = [query, underscore_locale, like_query, like_query, like_query] sql.push @tag if first_letter - sql += [underscore_default_locale, like_query, like_query] + sql += [underscore_default_locale, like_query, like_query, like_query] sql.push @tag if first_letter sql += where_parameters @public_bodies = PublicBody.paginate_by_sql( @@ -170,17 +170,17 @@ class PublicBodyController < ApplicationController # The simpler case where we're just searching in the current locale: where_condition = get_public_body_list_translated_condition('public_body_translations', first_letter, true) + ' AND ' + where_condition - where_sql = [where_condition, like_query, like_query] + where_sql = [where_condition, like_query, like_query, like_query] where_sql.push @tag if first_letter where_sql += [underscore_locale] + where_parameters - @public_bodies = PublicBody.where(where_sql) \ - .joins(:translations) \ - .order("public_body_translations.name") \ - .paginate(:page => params[:page], :per_page => 100) + @public_bodies = PublicBody.where(where_sql). + joins(:translations). + order("public_body_translations.name"). + paginate(:page => params[:page], :per_page => 100) end respond_to do |format| - format.html { render :template => "public_body/list" } + format.html { render :template => 'public_body/list' } end end end @@ -344,9 +344,11 @@ class PublicBodyController < ApplicationController end private + def get_public_body_list_translated_condition(table, first_letter=false, locale=nil) result = "(upper(#{table}.name) LIKE upper(?)" \ - " OR upper(#{table}.notes) LIKE upper (?))" + " OR upper(#{table}.notes) LIKE upper(?)" \ + " OR upper(#{table}.short_name) LIKE upper(?))" if first_letter result += " AND #{table}.first_letter = ?" end diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb index d66c28275..55a03e7b4 100644 --- a/app/controllers/request_controller.rb +++ b/app/controllers/request_controller.rb @@ -303,6 +303,12 @@ class RequestController < ApplicationController return render_new_compose(batch=false) end + # Check we have :public_body_id - spammers seem to be using :public_body + # erroneously instead + if params[:info_request][:public_body_id].blank? + redirect_to frontpage_path and return + end + # See if the exact same request has already been submitted # XXX this check should theoretically be a validation rule in the # model, except we really want to pass @existing_request to the view so diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 8d6522923..12207362b 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -288,7 +288,7 @@ class UserController < ApplicationController :reason_params => { :web => "", :email => _("Then you can change your password on {{site_name}}",:site_name=>site_name), - :email_subject => _("Change your password {{site_name}}",:site_name=>site_name) + :email_subject => _("Change your password on {{site_name}}",:site_name=>site_name) }, :circumstance => "change_password" # special login that lets you change your password ) diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb index 6db145348..124db8d4a 100644 --- a/app/models/incoming_message.rb +++ b/app/models/incoming_message.rb @@ -834,14 +834,15 @@ class IncomingMessage < ActiveRecord::Base def fully_destroy ActiveRecord::Base.transaction do - for o in self.outgoing_message_followups - o.incoming_message_followup = nil - o.save! + outgoing_message_followups.each do |outgoing_message_followup| + outgoing_message_followup.incoming_message_followup = nil + outgoing_message_followup.save! + end + info_request_events.each do |info_request_event| + 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 end - info_request_event = InfoRequestEvent.find_by_incoming_message_id(self.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.raw_email.destroy_file_representation! self.destroy end diff --git a/app/views/admin_request/edit.html.erb b/app/views/admin_request/edit.html.erb index 0e9c68aea..552b31bbb 100644 --- a/app/views/admin_request/edit.html.erb +++ b/app/views/admin_request/edit.html.erb @@ -33,7 +33,7 @@ <p><label for="info_request_tag_string"><strong>Tags</strong> <small>(space separated, can use key:value)</small></label><br/> <%= text_field 'info_request', 'tag_string', :size => 60 %></p> - <p><%= submit_tag 'Save changes', :accesskey => 's' %> + <p><%= submit_tag 'Save changes', :accesskey => 's', :class => 'btn btn-primary' %> </p> <p><strong>Note:</strong> To edit the actual request body text, click edit @@ -49,13 +49,17 @@ <hr> +<div class="well"> + <%= form_tag admin_request_destroy_path(@info_request) do %> <p> - <strong>This is permanent and irreversible!</strong> <%= submit_tag 'Destroy request entirely' %> + <strong>This is permanent and irreversible!</strong> <%= submit_tag 'Destroy request entirely', :class => 'btn btn-danger' %> <br>Use it mainly if someone posts private information, e.g. made a Data Protection request. It destroys all responses and tracks as well. </p> <% end %> +</div> + <hr> diff --git a/app/views/general/_frontpage_bodies_list.html.erb b/app/views/general/_frontpage_bodies_list.html.erb index 44321f14a..1c35c55ad 100644 --- a/app/views/general/_frontpage_bodies_list.html.erb +++ b/app/views/general/_frontpage_bodies_list.html.erb @@ -3,9 +3,10 @@ <div id="examples_0"> <h3><%= _("Who can I request information from?") %></h3> <%= _("{{site_name}} covers requests to {{number_of_authorities}} authorities, including:", - :site_name => site_name, :number_of_authorities => PublicBody.visible.count) %> + :site_name => site_name, + :number_of_authorities => number_with_delimiter(PublicBody.visible.count)) %> <ul> - <% for popular_body in popular_bodies %> + <% popular_bodies.each do |popular_body| %> <li><%=public_body_link(popular_body)%> <%= n_('{{count}} request', '{{count}} requests', popular_body.info_requests_count, :count => popular_body.info_requests_count) %> </li> diff --git a/app/views/general/_frontpage_new_request.html.erb b/app/views/general/_frontpage_new_request.html.erb index 499b60eb5..5b987b320 100644 --- a/app/views/general/_frontpage_new_request.html.erb +++ b/app/views/general/_frontpage_new_request.html.erb @@ -4,4 +4,4 @@ Information<br/> request</strong>") %> </h1> -<a class="link_button_green_large" href="<%= select_authority_path %>"><%= _("Start now »") %></a> +<a class="link_button_green_large" href="<%= select_authority_path %>"><%= _("Make a request »") %></a> diff --git a/app/views/general/_frontpage_requests_list.html.erb b/app/views/general/_frontpage_requests_list.html.erb index d7d9184c4..39187f3f0 100644 --- a/app/views/general/_frontpage_requests_list.html.erb +++ b/app/views/general/_frontpage_requests_list.html.erb @@ -8,9 +8,10 @@ <% end %> </h3> <%= _("{{site_name}} users have made {{number_of_requests}} requests, including:", - :site_name => site_name, :number_of_requests => InfoRequest.visible.count) %> + :site_name => site_name, + :number_of_requests => number_with_delimiter(InfoRequest.visible.count)) %> <ul> - <% for event in @request_events %> + <% @request_events.each do |event| %> <li> <% if @request_events_all_successful %> <%= _("{{public_body_link}} answered a request about", diff --git a/app/views/general/_frontpage_search_box.html.erb b/app/views/general/_frontpage_search_box.html.erb index 890602416..f77bd97fc 100644 --- a/app/views/general/_frontpage_search_box.html.erb +++ b/app/views/general/_frontpage_search_box.html.erb @@ -2,7 +2,8 @@ <%= _("Search over<br/> <strong>{{number_of_requests}} requests</strong> <span>and</span><br/> <strong>{{number_of_authorities}} authorities</strong>", - :number_of_requests => InfoRequest.visible.count, :number_of_authorities => PublicBody.visible.count) %> + :number_of_requests => number_with_delimiter(InfoRequest.visible.count), + :number_of_authorities => number_with_delimiter(PublicBody.visible.count)) %> </h2> <form id="search_form" method="post" action="<%= search_redirect_path %>"> <div> diff --git a/app/views/general/_locale_switcher.html.erb b/app/views/general/_locale_switcher.html.erb index a318f61f3..7d64c9069 100644 --- a/app/views/general/_locale_switcher.html.erb +++ b/app/views/general/_locale_switcher.html.erb @@ -1,7 +1,7 @@ - <% if FastGettext.default_available_locales.length > 1 && !params.empty? %> + <% if FastGettext.default_available_locales.any? && !params.empty? %> <div id="user_locale_switcher"> <div class="btn-group"> - <% for possible_locale in FastGettext.default_available_locales %> + <% FastGettext.default_available_locales.each do |possible_locale| %> <% if possible_locale == FastGettext.locale %> <a href="#" class="btn disabled"><%= locale_name(possible_locale) %></a> <% else %> diff --git a/app/views/public_body/_list_sidebar_extra.html.erb b/app/views/public_body/_list_sidebar_extra.html.erb index 290593d6a..6e683d7a1 100644 --- a/app/views/public_body/_list_sidebar_extra.html.erb +++ b/app/views/public_body/_list_sidebar_extra.html.erb @@ -1,3 +1,8 @@ +<% if AlaveteliConfiguration::public_body_statistics_page %> + <p> + <%= link_to _('Public authority statistics'), public_bodies_statistics_path %> + </p> +<% end %> <p> <%= link_to _('Are we missing a public authority?'), help_requesting_path + '#missing_body' %> </p> diff --git a/app/views/public_body/show.html.erb b/app/views/public_body/show.html.erb index a9c50e657..9352747ea 100644 --- a/app/views/public_body/show.html.erb +++ b/app/views/public_body/show.html.erb @@ -127,7 +127,10 @@ <% if @xapian_requests.results.empty? %> <p><% _('There were no requests matching your query.') %></p> <% else %> - <p> <%= _('Only requests made using {{site_name}} are shown.', :site_name => site_name) %></p> + <p> + <%= _('Only requests made using {{site_name}} are shown.', :site_name => site_name) %> + <%= link_to _('?'), help_about_path %> + </p> <% end %> <% else %> diff --git a/app/views/public_body/statistics.html.erb b/app/views/public_body/statistics.html.erb index d935a9e47..0e7e7424e 100644 --- a/app/views/public_body/statistics.html.erb +++ b/app/views/public_body/statistics.html.erb @@ -1,6 +1,6 @@ <% @title = _("Public Body Statistics") %> <div id="main_content"> - <h1>Public Body Statistics</h1> + <h1><%= @title %></h1> <p><%= _("This page of public body statistics is currently \ experimental, so there are some caveats that should be borne \ @@ -33,6 +33,8 @@ requests to the authority through this site, rather than, \ say, all requests that have been made to the public body by \ any means.") %></li> + <li><%= _("Unclassified or hidden requests are not counted.") %></li> + </ul> <p><%= _("These graphs were partly inspired by \ @@ -47,7 +49,7 @@ are due to him.") %></p> <table border=0> <thead> <tr> - <th>Public Body</th> + <th><%= _('Public Body') %></th> <th><%= graph_data['y_axis'] %></th> </tr> </thead> diff --git a/app/views/request/upload_response.html.erb b/app/views/request/upload_response.html.erb index f5fd6f000..f07af34d5 100644 --- a/app/views/request/upload_response.html.erb +++ b/app/views/request/upload_response.html.erb @@ -9,7 +9,9 @@ <%= foi_error_messages_for :comment %> - <h1><%= _('Respond to the FOI request')%> '<%=request_link(@info_request)%>'<% _(' made by ')%><%=user_link(@info_request.user) %></h1> + <h1><%= _("Respond to the FOI request '{{request}}' made by {{user}}", + :request => request_link(@info_request), + :user => user_link(@info_request.user)) %></h1> <p> <%= raw(_('Your response will <strong>appear on the Internet</strong>, <a href="{{url}}">read why</a> and answers to other questions.', :url => help_officers_path.html_safe)) %> @@ -48,5 +50,3 @@ </p> <% end %> <% end %> - - diff --git a/config/general.yml-example b/config/general.yml-example index 6e223406e..803c1c6ae 100644 --- a/config/general.yml-example +++ b/config/general.yml-example @@ -26,7 +26,7 @@ ISO_COUNTRY_CODE: GB TIME_ZONE: Australia/Sydney # These feeds are displayed accordingly on the Alaveteli "blog" page: -BLOG_FEED: 'http://www.mysociety.org/category/projects/whatdotheyknow/feed/' +BLOG_FEED: 'https://www.mysociety.org/category/projects/whatdotheyknow/feed/' TWITTER_USERNAME: 'whatdotheyknow' # Set the widget_id to get the Twitter sidebar on the blog page. # To get one https://twitter.com/settings/widgets diff --git a/config/packages b/config/packages index 9a07c5f20..fda09cbc1 100644 --- a/config/packages +++ b/config/packages @@ -39,3 +39,4 @@ sqlite3 libsqlite3-dev libicu-dev memcached +ttf-bitstream-vera diff --git a/config/packages.debian-squeeze b/config/packages.debian-squeeze index 6cdf2f9d6..d82d66324 100644 --- a/config/packages.debian-squeeze +++ b/config/packages.debian-squeeze @@ -37,3 +37,4 @@ libsqlite3-dev libicu-dev postgresql postgresql-client +ttf-bitstream-vera diff --git a/config/packages.ubuntu-precise b/config/packages.ubuntu-precise index 177d504e2..68911359a 100644 --- a/config/packages.ubuntu-precise +++ b/config/packages.ubuntu-precise @@ -33,3 +33,4 @@ libsqlite3-dev libicu-dev postgresql postgresql-client +ttf-bitstream-vera diff --git a/db/migrate/20140528110536_update_track_things_index.rb b/db/migrate/20140528110536_update_track_things_index.rb new file mode 100644 index 000000000..55ee0b70b --- /dev/null +++ b/db/migrate/20140528110536_update_track_things_index.rb @@ -0,0 +1,17 @@ +class UpdateTrackThingsIndex < ActiveRecord::Migration + + def up + if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" + execute "ALTER TABLE track_things_sent_emails DROP CONSTRAINT fk_track_request_public_body" + execute "ALTER TABLE track_things_sent_emails ADD CONSTRAINT fk_track_request_public_body FOREIGN KEY (public_body_id) REFERENCES public_bodies(id)" + end + end + + def down + if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" + execute "ALTER TABLE track_things_sent_emails DROP CONSTRAINT fk_track_request_public_body" + execute "ALTER TABLE track_things_sent_emails ADD CONSTRAINT fk_track_request_public_body FOREIGN KEY (user_id) REFERENCES users(id)" + end + end + +end diff --git a/doc/INSTALL.md b/doc/INSTALL.md index 04cdb1352..f6563be99 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -255,7 +255,7 @@ Make sure that the user specified in database.yml exists, and has full permissions on these databases. As they need the ability to turn off constraints whilst running the tests they also need to be a superuser. If you don't want your database user to be a superuser, you can add a line -`disable_constraints: false` to the test config in database.yml, as seen in database.yml-example +`constraint_disabling: false` to the test config in database.yml, as seen in database.yml-example You can create a `foi` user from the command line, thus: diff --git a/lib/tasks/cleanup.rake b/lib/tasks/cleanup.rake new file mode 100644 index 000000000..9a8be9521 --- /dev/null +++ b/lib/tasks/cleanup.rake @@ -0,0 +1,20 @@ +namespace :cleanup do + + desc 'Clean up all message redelivery and destroy actions from the holding pen to make admin actions there faster' + task :holding_pen => :environment do + dryrun = ENV['DRYRUN'] != '0' + if dryrun + $stderr.puts "This is a dryrun - nothing will be deleted" + end + holding_pen = InfoRequest.find_by_url_title('holding_pen') + old_events = holding_pen.info_request_events.find_each(:conditions => ['event_type in (?)', + ['redeliver_incoming', + 'destroy_incoming']]) do |event| + puts event.inspect + if ! dryrun + event.destroy + end + end + end + +end diff --git a/spec/controllers/public_body_controller_spec.rb b/spec/controllers/public_body_controller_spec.rb index 63989baaa..6afbf24d1 100644 --- a/spec/controllers/public_body_controller_spec.rb +++ b/spec/controllers/public_body_controller_spec.rb @@ -184,6 +184,11 @@ describe PublicBodyController, "when listing bodies" do assigns[:public_bodies].should == [ public_bodies(:geraldine_public_body) ] end + it "should support simple searching of bodies by short_name" do + get :list, :public_body_query => 'DfH' + assigns[:public_bodies].should == [ public_bodies(:humpadink_public_body) ] + end + it "should support simple searching of bodies by notes" do get :list, :public_body_query => 'Albatross' assigns[:public_bodies].should == [ public_bodies(:humpadink_public_body) ] diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb index 9353efcb3..070511fb0 100644 --- a/spec/controllers/request_controller_spec.rb +++ b/spec/controllers/request_controller_spec.rb @@ -1007,6 +1007,17 @@ describe RequestController, "when creating a new request" do # post_redirect.post_params.should == params # XXX get this working. there's a : vs '' problem amongst others end + it 'redirects to the frontpage if the action is sent the invalid + public_body param' do + post :new, :info_request => { :public_body => @body.id, + :title => 'Why Geraldine?', + :tag_string => '' }, + :outgoing_message => { :body => 'This is a silly letter.' }, + :submitted_new_request => 1, + :preview => 1 + response.should redirect_to frontpage_url + end + it "should show preview when input is good" do session[:user_id] = @user.id post :new, { :info_request => { :public_body_id => @body.id, diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb index f06dcbeeb..3b6887f76 100644 --- a/spec/models/incoming_message_spec.rb +++ b/spec/models/incoming_message_spec.rb @@ -112,6 +112,24 @@ describe IncomingMessage, 'when asked if a user can view it' do end +describe 'when destroying a message' do + + before do + @incoming_message = FactoryGirl.create(:plain_incoming_message) + end + + it 'can destroy a message with more than one info request event' do + @info_request = @incoming_message.info_request + @info_request.log_event('response', + :incoming_message_id => @incoming_message.id) + @info_request.log_event('edit_incoming', + :incoming_message_id => @incoming_message.id) + @incoming_message.fully_destroy + IncomingMessage.where(:id => @incoming_message.id).should be_empty + end + +end + describe 'when asked if it is indexed by search' do before do |