diff options
-rw-r--r-- | app/controllers/public_body_controller.rb | 12 | ||||
-rw-r--r-- | app/models/public_body.rb | 2 | ||||
-rw-r--r-- | app/views/request/new.rhtml | 4 | ||||
-rw-r--r-- | config/general.yml-example | 2 | ||||
-rw-r--r-- | doc/CHANGES.md | 2 | ||||
-rw-r--r-- | doc/THEMES.md | 53 | ||||
-rw-r--r-- | lib/public_body_categories.rb | 7 | ||||
-rwxr-xr-x | script/load-sample-data | 2 | ||||
-rw-r--r-- | spec/controllers/admin_public_body_controller_spec.rb | 12 | ||||
-rw-r--r-- | spec/controllers/public_body_controller_spec.rb | 5 | ||||
-rw-r--r-- | spec/fixtures/has_tag_string_tags.yml | 36 | ||||
-rw-r--r-- | spec/spec_helper.rb | 8 |
12 files changed, 120 insertions, 25 deletions
diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb index 659433c9e..00d1cc1e0 100644 --- a/app/controllers/public_body_controller.rb +++ b/app/controllers/public_body_controller.rb @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # app/controllers/public_body_controller.rb: # Show information about a public body. # @@ -117,14 +118,17 @@ class PublicBodyController < ApplicationController and has_tag_string_tags.model = \'PublicBody\' and has_tag_string_tags.name = ?) > 0', @query, @query, default_locale, @tag] end + if @tag == "all" @description = "" elsif @tag.size == 1 - @description = _("beginning with") + " '" + @tag + "'" + @description = _("beginning with ‘{{first_letter}}’", :first_letter=>@tag) else - @description = PublicBodyCategories::get().by_tag()[@tag] - if @description.nil? - @description = @tag + category_name = PublicBodyCategories::get().by_tag()[@tag] + if category_name.nil? + @description = _("matching the tag ‘{{tag_name}}’", :tag_name=>@tag) + else + @description = _("in the category ‘{{category_name}}’", :category_name=>category_name) end end PublicBody.with_locale(@locale) do diff --git a/app/models/public_body.rb b/app/models/public_body.rb index 453e3a6cf..9ac668b10 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -275,7 +275,7 @@ class PublicBody < ActiveRecord::Base ret = ret + types[-1] return ret else - return "A public authority" + return _("A public authority") end end diff --git a/app/views/request/new.rhtml b/app/views/request/new.rhtml index 2e554a20b..23212fc0b 100644 --- a/app/views/request/new.rhtml +++ b/app/views/request/new.rhtml @@ -47,12 +47,12 @@ <% end %> </div> - <div id="request_header_text"> <% if @info_request.public_body.has_notes? %> + <div id="request_header_text"> <h3><%= _('Special note for this authority!') %></h3> <p><%= @info_request.public_body.notes_as_html %></p> + </div> <% end %> - </div> <% if @info_request.public_body.eir_only? %> <h3><%= _('Please ask for environmental information only') %></h3> diff --git a/config/general.yml-example b/config/general.yml-example index 86399f0bc..98f04d0bf 100644 --- a/config/general.yml-example +++ b/config/general.yml-example @@ -137,3 +137,5 @@ EXCEPTION_NOTIFICATIONS_TO: - robin@example.org - seb@example.org +# This rate limiting can be turned off per-user via the admin interface +MAX_REQUESTS_PER_USER_PER_DAY: 6 diff --git a/doc/CHANGES.md b/doc/CHANGES.md index 99aaf7c98..d80acec3c 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -6,6 +6,7 @@ * It is now possible to rebuild the xapian index for specific terms, rather than having to drop and rebuild the entire database every time (as previously). See rake xapian:rebuild_index for more info. * When listing authorities, show all authorities in default locale, rather than only those in the currently selected locale. * Ensure incoming emails are only ever parsed once (should give a performance boost) +* Added a simple rate-limiting feature: restrict the number of requests users can make per day, except if explicitly unrestricted in the admin interface * [Full list of changes on github](https://github.com/sebbacon/alaveteli/issues?state=closed&milestone=9) ## Upgrade notes @@ -19,6 +20,7 @@ * Ensure you have values for new config variables (see `config/general.yml-example`): * EXCEPTION_NOTIFICATIONS_FROM * EXCEPTION_NOTIFICATIONS_TO +* The new optional config variable MAX_REQUESTS_PER_USER_PER_DAY can be set to limit the number of requests each user can make per day. * The recommended Varnish config has changed, so that we ignore more cookies. You should review your Varnish config with respect to the example at `config/varnish-alaveteli.vcl`. * Consider setting elinks global config as described in the "Troubleshooting" section of INSTALL.md diff --git a/doc/THEMES.md b/doc/THEMES.md index a7dd2d31f..4184d0aba 100644 --- a/doc/THEMES.md +++ b/doc/THEMES.md @@ -4,7 +4,11 @@ might want to do to customise it, beyond the available settings in the The most common requirement is to brand the site: at a minimum, inserting your own logo and colour scheme. You may also want to tweak -the different states that a request can go through. +the different states that a request can go through. You'll also want +to edit the categories that public bodies can appear in (i.e. the +groupings on the left hand side of the +"[View authorities](http://www.whatdotheyknow.com/body/list/all)" page +on WhatDoTheyKnow. There may also be other things you want to customise; drop a line on the developer's mailing list to discuss, if so. We're still working @@ -44,11 +48,18 @@ For example, the template for the home page lives at `app/views/general/frontpage.rhtml`, and the template for the "about us" page is at `app/views/help/about.rhtml`. -Any of these pages can be overridden in your own theme, by placing -them at a corresponding location within your theme's `lib/` directory. -These means that a file at -`vendor/plugins/alavetelitheme/lib/help/about.rhml` will appear in -place of the core "about us" file. +Obviously, you *could* edit those core files directly, but this would +be a Bad Idea, because you would find it increasingly hard to do +upgrades. Having said that, sometimes you may want to change the core +templates in a way that would benefit everyone, in which case, discuss +the changes on the mailing list, make them in a fork of Alaveteli, and +then issue a pull request. + +Normally, however, you should override these pages **in your own +theme**, by placing them at a corresponding location within your +theme's `lib/` directory. These means that a file at +`vendor/plugins/alavetelitheme/lib/help/about.rhml` will appear +instead of the core "about us" file. Rails expects all its stylesheets to live at `<railshome>/public`, which presents a problem for plugins. Here's how we solve it: the @@ -64,7 +75,18 @@ custom CSS in your theme's stylesheet folder (by convention, in <%= stylesheet_link_tag "/alavetelitheme/stylesheets/custom" %> -...which will, of course, need changing for your theme. +...which will, usually, need changing for your theme. + +# Adding your own categories for public bodies + +Categories are implemented in Alaveteli using tags. Specific tags can +be designated to group authorities together as a category. + +There's a file in the sample theme, +`alavetelitheme/lib/public_body_categories_en.rb`, which contains a +nested structure that defines categories. It contains a comment +describing its structure. You should make a copy of this file for each +locale you support. # Customising the request states @@ -75,12 +97,14 @@ as "overdue" in the main site config file. If you can't live with the states as they are, there's a very basic way to add to them (which will get improved over time). There's not -currently a way to remove any. +currently a way to remove any easily. There is an example of how to +do this in the `alavetelitheme`. -To do this, create two modules in your theme, +To do add states, create two modules in your theme, `InfoRequestCustomStates` and `RequestControllerCustomStates`. The former must have these two methods: +* `theme_calculate_status`: return a tag to identify the current state of the request * `theme_extra_states`: return a list of tags which identify the extra states you'd like to support * `theme_display_status`: return human-readable strings corresponding with these tags @@ -107,3 +131,14 @@ You can see examples of these customisations in for the Kosovan version of Alaveteli, Informata Zyrtare (ignore the file `lib/views/general/_custom_state_transitions.rhtml`, which is unused). + +# Adding new pages in the navigation + +`alavetelitheme/lib/config/custom-routes.rb` allows you to extend the base routes in +Alaveteli. The example in `alavetelitheme` adds an extra help page. +You can also use this to override the behaviour of specific pages if +necessary. + +# Adding or overriding models and controllers + +If you need to extend the behaviour of Alaveteli at the controller or model level, see `alavetelitheme/lib/controller_patches.rb` and `alavetelitheme/lib/model_patches.rb` for examples. diff --git a/lib/public_body_categories.rb b/lib/public_body_categories.rb index 21a021d39..796b1d53d 100644 --- a/lib/public_body_categories.rb +++ b/lib/public_body_categories.rb @@ -20,7 +20,7 @@ class PublicBodyCategories end def PublicBodyCategories.get - load_categories() if @@CATEGORIES.nil? + load_categories if @@CATEGORIES.empty? @@CATEGORIES[I18n.locale.to_s] || @@CATEGORIES[I18n.default_locale.to_s] || PublicBodyCategories.new([]) end @@ -30,10 +30,9 @@ class PublicBodyCategories end private - @@CATEGORIES = nil + @@CATEGORIES = {} def PublicBodyCategories.load_categories() - @@CATEGORIES = {} if @@CATEGORIES.nil? I18n.available_locales.each do |locale| begin load "public_body_categories_#{locale}.rb" @@ -41,4 +40,4 @@ class PublicBodyCategories end end end -end
\ No newline at end of file +end diff --git a/script/load-sample-data b/script/load-sample-data index 92846ce17..e5f1be4cd 100755 --- a/script/load-sample-data +++ b/script/load-sample-data @@ -16,4 +16,4 @@ ENV["RAILS_ENV"] = env # so restore to what it was before load_raw_emails_data END -echo "Loaded fixtures." +echo "Loaded fixtures. You may now wish to run $LOC/update-xapian-index" diff --git a/spec/controllers/admin_public_body_controller_spec.rb b/spec/controllers/admin_public_body_controller_spec.rb index a2f458025..08d465ca5 100644 --- a/spec/controllers/admin_public_body_controller_spec.rb +++ b/spec/controllers/admin_public_body_controller_spec.rb @@ -8,8 +8,14 @@ describe AdminPublicBodyController, "when administering public bodies" do username = MySociety::Config.get('ADMIN_USERNAME', '') password = MySociety::Config.get('ADMIN_PASSWORD', '') basic_auth_login @request + + @old_filters = ActionController::Routing::Routes.filters + ActionController::Routing::Routes.filters = RoutingFilter::Chain.new end + after do + ActionController::Routing::Routes.filters = @old_filters + end it "shows the index page" do get :index @@ -78,7 +84,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying it "disallows non-authenticated users to do anything" do @request.env["HTTP_AUTHORIZATION"] = "" - n = PublicBody.count.should + n = PublicBody.count post :destroy, { :id => 3 } response.code.should == "401" PublicBody.count.should == n @@ -113,7 +119,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying config['ADMIN_USERNAME'] = 'biz' config['ADMIN_PASSWORD'] = 'fuz' @request.env["HTTP_AUTHORIZATION"] = "" - n = PublicBody.count.should + n = PublicBody.count basic_auth_login(@request, "baduser", "badpassword") post :destroy, { :id => public_bodies(:forlorn_public_body).id } response.code.should == "401" @@ -206,11 +212,11 @@ describe AdminPublicBodyController, "when creating public bodies with i18n" do @old_filters = ActionController::Routing::Routes.filters ActionController::Routing::Routes.filters = RoutingFilter::Chain.new end + after do ActionController::Routing::Routes.filters = @old_filters end - it "creates a new public body in one locale" do n = PublicBody.count post :create, { :public_body => { :name => "New Quango", :short_name => "", :tag_string => "blah", :request_email => 'newquango@localhost', :last_edit_comment => 'From test code' } } diff --git a/spec/controllers/public_body_controller_spec.rb b/spec/controllers/public_body_controller_spec.rb index 4d27ea3f5..06077ac60 100644 --- a/spec/controllers/public_body_controller_spec.rb +++ b/spec/controllers/public_body_controller_spec.rb @@ -1,3 +1,4 @@ +# -*- coding: undecided -*- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require 'json' @@ -138,13 +139,15 @@ describe PublicBodyController, "when listing bodies" do end it "should list a tagged thing on the appropriate list page, and others on the other page, and all still on the all page" do + load_test_categories + public_bodies(:humpadink_public_body).tag_string = "foo local_council" get :list, :tag => "local_council" response.should render_template('list') assigns[:public_bodies].should == [ public_bodies(:humpadink_public_body) ] assigns[:tag].should == "local_council" - assigns[:description].should == "Local councils" + assigns[:description].should == "in the category ‘Local councils’" get :list, :tag => "other" response.should render_template('list') diff --git a/spec/fixtures/has_tag_string_tags.yml b/spec/fixtures/has_tag_string_tags.yml new file mode 100644 index 000000000..fe3d4fd28 --- /dev/null +++ b/spec/fixtures/has_tag_string_tags.yml @@ -0,0 +1,36 @@ +lonely_tag: + name: lonely_agency + id: "1" + created_at: 2007-10-24 10:51:01.161639 + model: PublicBody + model_id: 4 +useless_tag_1: + name: useless_agency + id: "2" + created_at: 2007-10-24 10:51:01.161639 + model: PublicBody + model_id: 3 +useless_tag_2: + name: useless_agency + id: "3" + created_at: 2007-10-24 10:51:01.161639 + model: PublicBody + model_id: 4 +useless_tag_3: + name: useless_agency + id: "4" + created_at: 2007-10-24 10:51:01.161639 + model: PublicBody + model_id: 5 +popular_tag_1: + name: popular_agency + id: "5" + created_at: 2007-10-24 10:51:01.161639 + model: PublicBody + model_id: 2 +popular_tag_2: + name: popular_agency + id: "6" + created_at: 2007-10-24 10:51:01.161639 + model: PublicBody + model_id: 3 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 065d9d080..fbc115c38 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -190,3 +190,11 @@ end def parse_all_incoming_messages IncomingMessage.find(:all).each{|x| x.parse_raw_email!} end + +def load_test_categories + PublicBodyCategories.add(:en, [ + "Local and regional", + [ "local_council", "Local councils", "a local council" ], + "Miscellaneous", + [ "other", "Miscellaneous", "miscellaneous" ],]) +end |