diff options
author | Robin Houston <robin.houston@gmail.com> | 2012-07-05 12:17:57 +0100 |
---|---|---|
committer | Robin Houston <robin.houston@gmail.com> | 2012-07-05 12:17:57 +0100 |
commit | 6d6614ddfd582e5cde0b55e76521c05b96fb906a (patch) | |
tree | 09e2dba166b446e646b16e99181043ef26fa3741 | |
parent | b479373671365ba9377c23a8e984606ddab13330 (diff) | |
parent | d30312f2d13b561bc0f596a8a57b4a944401600e (diff) |
Merge branch 'develop' into wdtk
Conflicts:
doc/INSTALL.md
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | Gemfile.lock | 4 | ||||
-rw-r--r-- | app/controllers/api_controller.rb | 52 | ||||
-rw-r--r-- | app/models/info_request.rb | 6 | ||||
-rw-r--r-- | app/models/public_body.rb | 4 | ||||
-rw-r--r-- | app/models/user.rb | 3 | ||||
-rw-r--r-- | app/views/api/request_events.atom.builder | 25 | ||||
-rw-r--r-- | config/packages | 4 | ||||
-rw-r--r-- | config/routes.rb | 6 | ||||
-rw-r--r-- | doc/CHANGES.md | 16 | ||||
-rw-r--r-- | doc/INSTALL.md | 22 | ||||
-rw-r--r-- | spec/controllers/api_controller_spec.rb | 54 |
12 files changed, 170 insertions, 28 deletions
@@ -32,7 +32,7 @@ gem 'test-unit', '~> 1.2.3' if RUBY_VERSION.to_f >= 1.9 gem 'vpim' gem 'will_paginate', '~> 2.3.11' # when 1.2.9 is released by the maintainer, we can stop using this fork: -gem 'xapian-full-alaveteli', '~> 1.2.9.4' +gem 'xapian-full-alaveteli', '~> 1.2.9.5' gem 'xml-simple' gem 'zip' diff --git a/Gemfile.lock b/Gemfile.lock index cf21dc0ce..0d9d5cc1d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -63,7 +63,7 @@ GEM ruby-ole (1.2.11.3) vpim (0.695) will_paginate (2.3.16) - xapian-full-alaveteli (1.2.9.4) + xapian-full-alaveteli (1.2.9.5) xml-simple (1.1.1) zip (2.0.2) @@ -96,6 +96,6 @@ DEPENDENCIES ruby-msg (~> 1.5.0) vpim will_paginate (~> 2.3.11) - xapian-full-alaveteli (~> 1.2.9.4) + xapian-full-alaveteli (~> 1.2.9.5) xml-simple zip diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 524aa44b7..4db07b4c9 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -155,6 +155,58 @@ class ApiController < ApplicationController head :no_content end + def body_request_events + feed_type = params[:feed_type] + raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i + + @events = InfoRequestEvent.find_by_sql([ + %(select info_request_events.* + from info_requests + join info_request_events on info_requests.id = info_request_events.info_request_id + where info_requests.public_body_id = ? + and info_request_events.event_type in ( + 'sent', 'followup_sent', 'resent', 'followup_resent' + ) + order by info_request_events.created_at desc + ), @public_body.id + ]) + if feed_type == "atom" + render :template => "api/request_events.atom", :layout => false + elsif feed_type == "json" + # For the JSON feed, we take a "since" parameter that allows the client + # to restrict to events more recent than a certain other event + if params[:since_event_id] + @since_event_id = params[:since_event_id].to_i + end + @event_data = [] + @events.each do |event| + break if event.id == @since_event_id + + request = event.info_request + this_event = { + :request_id => request.id, + :event_id => event.id, + :created_at => event.created_at.iso8601, + :event_type => event.event_type, + :request_url => main_url(request_url(request)), + :request_email => request.incoming_email, + :title => request.title, + :body => event.outgoing_message.body, + + :user_name => request.user_name, + } + if request.user + this_event[:user_url] = main_url(user_url(request.user)) + end + + @event_data.push(this_event) + end + render :json => @event_data + else + raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: #{feed_type}") + end + end + protected def check_api_key raise "Missing required parameter 'k'" if params[:k].nil? diff --git a/app/models/info_request.rb b/app/models/info_request.rb index d09acbcf6..a41d6d2db 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -1,11 +1,10 @@ # == Schema Information -# Schema version: 114 # # Table name: info_requests # # id :integer not null, primary key # title :text not null -# user_id :integer not null +# user_id :integer # public_body_id :integer not null # created_at :datetime not null # updated_at :datetime not null @@ -17,10 +16,11 @@ # allow_new_responses_from :string(255) default("anybody"), not null # handle_rejected_responses :string(255) default("bounce"), not null # idhash :string(255) not null +# external_user_name :string(255) +# external_url :string(255) # attention_requested :boolean default(FALSE) # - require 'digest/sha1' class InfoRequest < ActiveRecord::Base diff --git a/app/models/public_body.rb b/app/models/public_body.rb index bc8f084bb..9efeadf55 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -1,5 +1,4 @@ # == Schema Information -# Schema version: 114 # # Table name: public_bodies # @@ -19,7 +18,6 @@ # publication_scheme :text default(""), not null # api_key :string(255) not null # - # models/public_body.rb: # A public body, from which information can be requested. # @@ -583,5 +581,3 @@ class PublicBody < ActiveRecord::Base end end - - diff --git a/app/models/user.rb b/app/models/user.rb index a21676f68..657ea2a4a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,4 @@ # == Schema Information -# Schema version: 114 # # Table name: users # @@ -21,9 +20,7 @@ # email_bounce_message :text default(""), not null # no_limit :boolean default(FALSE), not null # receive_email_alerts :boolean default(TRUE), not null -# user_similarity_id :integer # - # models/user.rb: # Model of people who use the site to file requests, make comments etc. # diff --git a/app/views/api/request_events.atom.builder b/app/views/api/request_events.atom.builder new file mode 100644 index 000000000..4f0133051 --- /dev/null +++ b/app/views/api/request_events.atom.builder @@ -0,0 +1,25 @@ +atom_feed("xmlns:alaveteli" => "http://www.alaveteli.org/API/v2/RequestEvents/Atom") do |feed| + feed.title("Events relating to #{@public_body.name}") + feed.updated(@events.first.created_at) + + for event in @events + feed.entry(event) do |entry| + request = event.info_request + + entry.published(event.created_at) + entry.tag!("alaveteli:event_type", event.event_type) + entry.tag!("alaveteli:request_url", main_url(request_url(request))) + entry.title(request.title) + + entry.content(event.outgoing_message.body, :type => 'text') + + entry.author do |author| + author.name(request.user_name) + if !request.user.nil? + author.uri(main_url(user_url(request.user))) + end + author.email(request.incoming_email) + end + end + end +end diff --git a/config/packages b/config/packages index b59c61b47..d059d2906 100644 --- a/config/packages +++ b/config/packages @@ -8,7 +8,7 @@ rdoc irb wv poppler-utils -pdftk (> 1.41+dfsg-1) | pdftk (< 1.41+dfsg-1) # that version has a non-functionining uncompress option +pdftk (>> 1.41+dfsg-1) | pdftk (<< 1.41+dfsg-1) # that version has a non-functionining uncompress option gs-gpl catdoc links @@ -32,5 +32,7 @@ libmagickwand-dev libpq-dev uuid-dev ruby1.8-dev +rubygems +rake build-essential bundler diff --git a/config/routes.rb b/config/routes.rb index 13ab6669e..a9c2c889a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -244,8 +244,10 @@ ActionController::Routing::Routes.draw do |map| map.with_options :controller => 'api' do |api| api.api_create_request '/api/v2/request.json', :action => 'create_request', :conditions => { :method => :post } - api.api_show_request '/api/v2/request/:id.json', :action => 'show_request', :conditions => { :method => :get } - api.api_add_correspondence '/api/v2/request/:id.json', :action => 'add_correspondence', :conditions => { :method => :post } + api.api_show_request '/api/v2/request/:id.json', :action => 'show_request', :conditions => { :method => :get } + api.api_add_correspondence '/api/v2/request/:id.json', :action => 'add_correspondence', :conditions => { :method => :post } + + api.api_body_request_events '/api/v2/body/:id/request_events.:feed_type', :action => 'body_request_events', :feed_type => '^(json|atom)$' end map.filter('conditionallyprependlocale') diff --git a/doc/CHANGES.md b/doc/CHANGES.md index 920c397de..34959f924 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -1,8 +1,24 @@ +# Version 0.6.2 +## Highlighted features + +* This is a minor release to fix small bugs in documentation and install/upgrade process +* It also includes support for [Continuous Integration using Travis](http://travis-ci.org/) + +## Upgrade notes + +* No special action required -- just check out this version and run + `rails-post-deploy` as usual. + # Version 0.6.1 ## Highlighted features * Fixes important security bug [issue #515](https://github.com/sebbacon/alaveteli/issues/515) * Show admin nav bar when browsing main site +* A new API for adding requests and correspondence to an Alaveteli + instance, designed for use by public bodies that wish to use + Alaveteli as a disclosure log. See + [the wiki](https://github.com/sebbacon/alaveteli/wiki/API) for some + documentation. * [Full list of changes on github](https://github.com/sebbacon/alaveteli/issues?milestone=8&state=closed) ## Upgrade notes diff --git a/doc/INSTALL.md b/doc/INSTALL.md index af54da108..325ccfbdd 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -2,7 +2,7 @@ These instructions assume Debian Squeeze or Ubuntu 10.04 LTS. [Install instructions for OS X](https://github.com/sebbacon/alaveteli/wiki/OS-X-Quickstart) are under development. Debian Squeeze is the best supported deployment platform. - + Commands are intended to be run via the terminal or over ssh. As an aid to evaluation, there is an @@ -33,15 +33,17 @@ used to parse documents, host the site, etc. There are also packages that contain headers necessary to compile some of the gem dependencies in the next step. -If you are running Debian, you can use specially compiled mysociety -packages by adding the following to `/etc/apt/sources.list` and -running `apt-get update`: +If you are running Debian, add the following repositories to +`/etc/apt/sources.list` and run `apt-get update`: deb http://debian.mysociety.org squeeze main + deb http://ftp.debian.org/debian/ testing main non-free contrib -If you don't set up that mySociety Debian source (e.g. if you're -running Ubuntu), you should comment out `wkhtmltopdf-static` from -`config/packages`, as it won't install in the next step +The repositories above allow us to install the packages +`wkthmltopdf-static` and `bundler` using `apt`; so if you're running +Ubuntu, you won't be able to use the above repositories, and you will +need to comment out those two lines in `config/packages` before +following the next step (and install bundler manually). Now install the packages that are listed in config/packages using apt-get e.g.: @@ -54,7 +56,7 @@ Some of the files also have a version number listed in config/packages # Install Ruby dependencies -Install rubygems 1.6.1 (we're not using the Debian package because we +Install rubygems 1.6.2 (we're not using the Debian package because we need an older version; see "Troubleshooting" below for an explanation): @@ -471,8 +473,4 @@ various other things that can be automated for deployment. deployments), you may need to do something like: ln -s /usr/lib/ruby/gems/1.8/bin/rake /usr/local/bin/ - - Or (Debian): - - ln -s /usr/lib/ruby/gems/1.8/bin/rake /usr/local/bin/ diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api_controller_spec.rb index 1f65576b6..98751a93a 100644 --- a/spec/controllers/api_controller_spec.rb +++ b/spec/controllers/api_controller_spec.rb @@ -260,4 +260,58 @@ describe ApiController, "when using the API" do # assigns them and changing assignment to an equality # check, which does not really test anything at all. end + + it "should show an Atom feed of new request events" do + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "atom" + + response.should be_success + response.should render_template("api/request_events.atom") + assigns[:events].size.should > 0 + assigns[:events].each do |event| + event.info_request.public_body.should == public_bodies(:geraldine_public_body) + event.outgoing_message.should_not be_nil + event.event_type.should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} + end + end + + it "should show a JSON feed of new request events" do + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "json" + + response.should be_success + assigns[:events].size.should > 0 + assigns[:events].each do |event| + event.info_request.public_body.should == public_bodies(:geraldine_public_body) + event.outgoing_message.should_not be_nil + event.event_type.should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} + end + + assigns[:event_data].size.should == assigns[:events].size + assigns[:event_data].each do |event_record| + event_record[:event_type].should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} + end + end + + it "should honour the since_event_id parameter" do + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "json" + response.should be_success + first_event = assigns[:event_data][0] + second_event_id = assigns[:event_data][1][:event_id] + + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "json", + :since_event_id => second_event_id + response.should be_success + assigns[:event_data].should == [first_event] + end end |