diff options
-rw-r--r-- | .ruby-version | 2 | ||||
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | Gemfile | 5 | ||||
-rw-r--r-- | Gemfile.lock | 58 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | Rakefile | 4 | ||||
-rw-r--r-- | app/controllers/admin_public_body_controller.rb | 2 | ||||
-rw-r--r-- | app/mailers/request_mailer.rb | 3 | ||||
-rw-r--r-- | app/models/foi_attachment.rb | 2 | ||||
-rw-r--r-- | app/models/public_body.rb | 23 | ||||
-rw-r--r-- | app/views/admin_public_body/_form.html.erb | 2 | ||||
-rw-r--r-- | app/views/comment/_single_comment.html.erb | 4 | ||||
-rw-r--r-- | app/views/general/_stylesheet_includes.html.erb | 2 | ||||
-rw-r--r-- | app/views/layouts/no_chrome.html.erb | 1 | ||||
-rw-r--r-- | app/views/request/_bubble.html.erb | 2 | ||||
-rw-r--r-- | config/application.rb | 2 | ||||
-rw-r--r-- | doc/INSTALL.md | 9 | ||||
-rw-r--r-- | doc/THEME-ASSETS-UPGRADE.md | 5 | ||||
-rw-r--r-- | lib/quiet_opener.rb | 37 | ||||
-rw-r--r-- | lib/tasks/import.rake | 12 | ||||
-rwxr-xr-x | script/switch-theme.rb | 25 | ||||
-rw-r--r-- | spec/mailers/request_mailer_spec.rb | 21 | ||||
-rw-r--r-- | spec/models/public_body_spec.rb | 14 |
23 files changed, 164 insertions, 74 deletions
diff --git a/.ruby-version b/.ruby-version index 2aaf2528c..7fa1d1ef4 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -ruby-1.9.3-p392 +2.0.0-p353 diff --git a/.travis.yml b/.travis.yml index 051dc0fae..d6ed72cf6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ branches: rvm: - 1.8.7 - 1.9.3 + - 2.0.0 before_install: - gem install rake --version=0.9.2.2 - git submodule update --init --recursive @@ -7,7 +7,7 @@ if File.exist? "/etc/debian_version" and File.open("/etc/debian_version").read.s end source 'https://rubygems.org' -gem 'rails', '3.2.15' +gem 'rails', '3.2.16' gem 'pg' @@ -23,7 +23,7 @@ gem 'jquery-ui-rails' gem 'json' gem 'mahoro' gem 'memcache-client' -gem 'net-http-local' +gem 'net-http-local', :platforms => [:ruby_18, :ruby_19] gem 'net-purge' gem 'newrelic_rpm' gem 'rack' @@ -48,7 +48,6 @@ gem 'zip' gem 'fast_gettext' gem 'gettext_i18n_rails' gem 'gettext' - gem 'globalize3', :git => 'git://github.com/globalize/globalize.git', :ref => '5fd95f2389dff1' gem 'locale' gem 'routing-filter' diff --git a/Gemfile.lock b/Gemfile.lock index 46c018352..62258c0c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,12 +18,12 @@ GIT GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.15) - actionpack (= 3.2.15) + actionmailer (3.2.16) + actionpack (= 3.2.16) mail (~> 2.5.4) - actionpack (3.2.15) - activemodel (= 3.2.15) - activesupport (= 3.2.15) + actionpack (3.2.16) + activemodel (= 3.2.16) + activesupport (= 3.2.16) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) @@ -31,23 +31,23 @@ GEM rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.2.1) - activemodel (3.2.15) - activesupport (= 3.2.15) + activemodel (3.2.16) + activesupport (= 3.2.16) builder (~> 3.0.0) - activerecord (3.2.15) - activemodel (= 3.2.15) - activesupport (= 3.2.15) + activerecord (3.2.16) + activemodel (= 3.2.16) + activesupport (= 3.2.16) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.15) - activemodel (= 3.2.15) - activesupport (= 3.2.15) - activesupport (3.2.15) + activeresource (3.2.16) + activemodel (= 3.2.16) + activesupport (= 3.2.16) + activesupport (3.2.16) i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) annotate (2.5.0) rake - arel (3.0.2) + arel (3.0.3) bootstrap-sass (2.3.1.2) sass (~> 3.2) builder (3.0.4) @@ -113,7 +113,7 @@ GEM tilt highline (1.6.19) hike (1.2.3) - i18n (0.6.5) + i18n (0.6.9) journey (1.0.4) jquery-rails (3.0.4) railties (>= 3.0, < 5.0) @@ -139,7 +139,7 @@ GEM sqlite3 (~> 1.3) thin (~> 1.5.0) memcache-client (1.8.5) - mime-types (1.25) + mime-types (1.25.1) multi_json (1.8.2) net-http-local (0.1.2) net-purge (0.1.0) @@ -166,19 +166,19 @@ GEM rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.15) - actionmailer (= 3.2.15) - actionpack (= 3.2.15) - activerecord (= 3.2.15) - activeresource (= 3.2.15) - activesupport (= 3.2.15) + rails (3.2.16) + actionmailer (= 3.2.16) + actionpack (= 3.2.16) + activerecord (= 3.2.16) + activeresource (= 3.2.16) + activesupport (= 3.2.16) bundler (~> 1.0) - railties (= 3.2.15) + railties (= 3.2.16) rails-i18n (0.7.3) i18n (~> 0.5) - railties (3.2.15) - actionpack (= 3.2.15) - activesupport (= 3.2.15) + railties (3.2.16) + actionpack (= 3.2.16) + activesupport (= 3.2.16) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) @@ -261,7 +261,7 @@ GEM multi_json (~> 1.0, >= 1.0.2) unicode (0.4.4) unidecoder (1.1.2) - vpim (0.695) + vpim (13.11.11) webrat (0.7.3) nokogiri (>= 1.2.0) rack (>= 1.0) @@ -306,7 +306,7 @@ DEPENDENCIES nokogiri pg rack - rails (= 3.2.15) + rails (= 3.2.16) rails-i18n rake (= 0.9.2.2) rdoc @@ -19,7 +19,7 @@ drop a line to hello@alaveteli.org to let us know that you're using Alaveteli. Some documentation can be found in the [`doc/` folder](https://github.com/mysociety/alaveteli/tree/master/doc). -There's background information and a more documentation on +There's background information and more documentation on [our wiki](https://github.com/mysociety/alaveteli/wiki/Home/), and lots of useful information (including a blog) on [the project website](http://alaveteli.org) @@ -5,5 +5,7 @@ require File.expand_path('../config/application', __FILE__) require 'rake' Alaveteli::Application.load_tasks if Rails.env == 'test' - Dir[File.join(File.dirname(__FILE__),'commonlib','rblib','tests','*.rake')].each { |file| load(file) } + Dir[Rails.root.join('commonlib','rblib','tests','*.rake')].each { |file| load(file) } end +# Make sure the the acts_as_xapian tasks are also loaded: +Dir[Rails.root.join('lib','acts_as_xapian','tasks','*.rake')].each { |file| load(file) } diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb index e0da234b0..88e275960 100644 --- a/app/controllers/admin_public_body_controller.rb +++ b/app/controllers/admin_public_body_controller.rb @@ -143,6 +143,8 @@ class AdminPublicBodyController < AdminController @errors = "" if request.post? dry_run_only = (params['commit'] == 'Upload' ? false : true) + # (FIXME: both of these cases could now be changed to use + # PublicBody.import_csv_from_file.) # Read file from params if params[:csv_file] csv_contents = params[:csv_file].read diff --git a/app/mailers/request_mailer.rb b/app/mailers/request_mailer.rb index c8a19afa8..af1a75df9 100644 --- a/app/mailers/request_mailer.rb +++ b/app/mailers/request_mailer.rb @@ -19,7 +19,8 @@ class RequestMailer < ApplicationMailer end mail(:from => from_user.name_and_email, - :to => info_request.incoming_name_and_email) + :to => info_request.incoming_name_and_email, + :subject => info_request.email_subject_followup) end # Used when a response is uploaded using the API diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb index 914420a2b..acbfc8a34 100644 --- a/app/models/foi_attachment.rb +++ b/app/models/foi_attachment.rb @@ -69,7 +69,7 @@ class FoiAttachment < ActiveRecord::Base tries = 0 delay = 1 begin - binary_data = File.open(self.filepath, "rb" ).read + binary_data = File.open(self.filepath, "rb" ){ |file| file.read } if self.content_type =~ /^text/ @cached_body = convert_string_to_utf8_or_binary(binary_data, 'UTF-8') else diff --git a/app/models/public_body.rb b/app/models/public_body.rb index 8e474c797..eb0905f9e 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -369,10 +369,24 @@ class PublicBody < ActiveRecord::Base class ImportCSVDryRun < StandardError end - # Import from CSV. Just tests things and returns messages if dry_run is true. - # Returns an array of [array of errors, array of notes]. If there are errors, - # always rolls back (as with dry_run). + # Import from a string in CSV format. + # Just tests things and returns messages if dry_run is true. + # Returns an array of [array of errors, array of notes]. If there + # are errors, always rolls back (as with dry_run). def self.import_csv(csv, tag, tag_behaviour, dry_run, editor, available_locales = []) + tmp_csv = nil + Tempfile.open('alaveteli') do |f| + f.write csv + tmp_csv = f + end + PublicBody.import_csv_from_file(tmp_csv.path, tag, tag_behaviour, dry_run, editor, available_locales) + end + + # Import from a CSV file. + # Just tests things and returns messages if dry_run is true. + # Returns an array of [array of errors, array of notes]. If there + # are errors, always rolls back (as with dry_run). + def self.import_csv_from_file(csv_filename, tag, tag_behaviour, dry_run, editor, available_locales = []) errors = [] notes = [] available_locales = [I18n.default_locale] if available_locales.empty? @@ -398,7 +412,8 @@ class PublicBody < ActiveRecord::Base set_of_importing = Set.new() field_names = { 'name'=>1, 'request_email'=>2 } # Default values in case no field list is given line = 0 - CSV.parse(csv) do |row| + + CSV.foreach(csv_filename) do |row| line = line + 1 # Parse the first line as a field list if it starts with '#' diff --git a/app/views/admin_public_body/_form.html.erb b/app/views/admin_public_body/_form.html.erb index c577d1e18..18bf1d15b 100644 --- a/app/views/admin_public_body/_form.html.erb +++ b/app/views/admin_public_body/_form.html.erb @@ -82,7 +82,7 @@ </div> </div> <div class="control-group"> - <label for="public_body_home_page"><%=_("Home page")%></label> + <label for="public_body_home_page" class="control-label"><%=_("Home page")%></label> <div class="controls"> <%= f.text_field :home_page, :class => "span4" %> <p class="help-block">(of whole authority, not just their FOI page; set to <strong>blank</strong> (empty string) to guess it from the email)</p> diff --git a/app/views/comment/_single_comment.html.erb b/app/views/comment/_single_comment.html.erb index d2edc8dbe..a6d234b34 100644 --- a/app/views/comment/_single_comment.html.erb +++ b/app/views/comment/_single_comment.html.erb @@ -17,10 +17,10 @@ </div> <p class="event_actions"> <% if !comment.id.nil? %> - <%= link_to "Link to this", comment_path(comment), :class => "link_to_this" %> <% if !@user.nil? && @user.admin_page_links? %> - | <%= link_to "Admin", admin_request_edit_comment_path(comment) %> + <%= link_to "Admin", admin_request_edit_comment_path(comment) %> | <% end %> + <%= link_to "Link to this", comment_path(comment), :class => "link_to_this" %> <!-- | <%= link_to _('Report abuse'), comment_path(comment) %> --> <% end %> </p> diff --git a/app/views/general/_stylesheet_includes.html.erb b/app/views/general/_stylesheet_includes.html.erb index b3f32054c..7a1648efd 100644 --- a/app/views/general/_stylesheet_includes.html.erb +++ b/app/views/general/_stylesheet_includes.html.erb @@ -17,6 +17,6 @@ <%= stylesheet_link_tag 'ie7.css' %> <![endif]--> <% if AlaveteliConfiguration::force_registration_on_new_request %> - <%= stylesheet_link_tag 'jquery.fancybox-1.3.4.pack.js', :rel => "stylesheet" %> + <%= stylesheet_link_tag 'jquery.fancybox-1.3.4.css', :rel => "stylesheet" %> <% end %> <% end %> diff --git a/app/views/layouts/no_chrome.html.erb b/app/views/layouts/no_chrome.html.erb index 589e1bb76..e613b8ca2 100644 --- a/app/views/layouts/no_chrome.html.erb +++ b/app/views/layouts/no_chrome.html.erb @@ -14,7 +14,6 @@ <%= stylesheet_link_tag 'application', :title => "Main", :rel => "stylesheet" %> <%= stylesheet_link_tag 'fonts', :rel => "stylesheet" %> - <%= stylesheet_link_tag 'theme', :rel => "stylesheet" %> <!--[if LT IE 7]> <%= stylesheet_link_tag 'ie6', :rel => "stylesheet" %> <![endif]--> diff --git a/app/views/request/_bubble.html.erb b/app/views/request/_bubble.html.erb index 8827d114d..e038bb3dc 100644 --- a/app/views/request/_bubble.html.erb +++ b/app/views/request/_bubble.html.erb @@ -13,7 +13,7 @@ :file_name => a.display_filename + '.html') %> <% img_filename = "icon_" + a.content_type.sub('/', '_') + "_large.png" - full_filename = File.expand_path(File.join(File.dirname(__FILE__), "../../assets/images", img_filename)) + full_filename = File.expand_path(Rails.root.join('app', 'assets', 'images', img_filename)) if File.exist?(full_filename) %> <%= link_to image_tag(img_filename, :class => "attachment_image", :alt => "Attachment"), attachment_path %> <% else %> diff --git a/config/application.rb b/config/application.rb index f2b662abc..3c749a531 100644 --- a/config/application.rb +++ b/config/application.rb @@ -31,6 +31,7 @@ module Alaveteli # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de + I18n.config.enforce_available_locales = false # JavaScript files you want as :defaults (application.js is always included). # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) @@ -93,6 +94,7 @@ module Alaveteli # ... while these are individual files that can't easily be # grouped: config.assets.precompile += ['jquery.fancybox-1.3.4.pack.js', + 'jquery.fancybox-1.3.4.css', 'jquery.Jcrop.css', 'excanvas.min.js', 'fonts.css', diff --git a/doc/INSTALL.md b/doc/INSTALL.md index f39789936..3decb53a3 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -15,11 +15,10 @@ This creates an instance that runs in development mode, so we wouldn't recommend you use it for a production system without changing the configuration. -If you haven't used Amazon Web Services before, then you can get -a Micro instance which will be -[free for a year](http://aws.amazon.com/free/). You will find -that a micro instance isn't powerful enough for anything other -very basic testing of Alaveteli, however. +Unfortunately, Alaveteli will not run properly on a free Micro +instance due to the low amount of memory available on those +instances; you will need to use at least a Small instance, which +Amazon will charge for. The AMI can be found in the EU West (Ireland) region, with the ID ami-0f24c678 and name “Basic Alaveteli installation diff --git a/doc/THEME-ASSETS-UPGRADE.md b/doc/THEME-ASSETS-UPGRADE.md index 66a1e95f4..2c6e49986 100644 --- a/doc/THEME-ASSETS-UPGRADE.md +++ b/doc/THEME-ASSETS-UPGRADE.md @@ -67,3 +67,8 @@ should be mentioned in `lib/alavetelitheme.rb` with: You should be left with nothing in the `public` directory after making these changes, except possibly custom error pages. + +Remove the code that symlinks the theme 'public' directory to a +subdirectory of the main application's 'public' directory from +install.rb. Also remove the code from uninstall.rb that removes that +symlink. The asset pipeline will handle making assets available. diff --git a/lib/quiet_opener.rb b/lib/quiet_opener.rb index ae6605c43..16ea27b8e 100644 --- a/lib/quiet_opener.rb +++ b/lib/quiet_opener.rb @@ -1,6 +1,8 @@ require 'open-uri' require 'net-purge' -require 'net/http/local' +if RUBY_VERSION.to_f < 2.0 + require 'net/http/local' +end def quietly_try_to_open(url) begin @@ -12,17 +14,36 @@ def quietly_try_to_open(url) return result end +# On Ruby versions before 2.0, we need to use the net-http-local gem +# to force the use of 127.0.0.1 as the local interface for the +# connection. However, at the time of writing this gem doesn't work +# on Ruby 2.0 and it's not necessary with that Ruby version - one can +# supply a :local_host option to Net::HTTP:start. So, this helper +# function is to abstract away that difference, and can be used as you +# would Net::HTTP.start(host) when passed a block. +def http_from_localhost(host) + if RUBY_VERSION.to_f >= 2.0 + Net::HTTP.start(host, :local_host => '127.0.0.1') do |http| + yield http + end + else + Net::HTTP.bind '127.0.0.1' do + Net::HTTP.start(host) do |http| + yield http + end + end + end +end + def quietly_try_to_purge(host, url) begin result = "" result_body = "" - Net::HTTP.bind '127.0.0.1' do - Net::HTTP.start(host) {|http| - request = Net::HTTP::Purge.new(url) - response = http.request(request) - result = response.code - result_body = response.body - } + http_from_localhost(host) do |http| + request = Net::HTTP::Purge.new(url) + response = http.request(request) + result = response.code + result_body = response.body end rescue OpenURI::HTTPError, SocketError, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET, Errno::ENETUNREACH Rails.logger.warn("PURGE: Unable to reach host #{host}") diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index 0e8397fde..c8183c745 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -54,12 +54,12 @@ namespace :import do STDERR.puts "Now importing the public bodies..." # Now it's (probably) safe to try to import: - errors, notes = PublicBody.import_csv(tmp_csv.path, - tag='', - tag_behaviour='replace', - dryrun, - editor="#{ENV['USER']} (Unix user)", - I18n.available_locales) do |row_number, fields| + errors, notes = PublicBody.import_csv_from_file(tmp_csv.path, + tag='', + tag_behaviour='replace', + dryrun, + editor="#{ENV['USER']} (Unix user)", + I18n.available_locales) do |row_number, fields| percent_complete = (100 * row_number.to_f / number_of_rows).to_i STDERR.print "#{row_number} out of #{number_of_rows} " STDERR.puts "(#{percent_complete}% complete)" diff --git a/script/switch-theme.rb b/script/switch-theme.rb index e6afcebb9..980853687 100755 --- a/script/switch-theme.rb +++ b/script/switch-theme.rb @@ -31,6 +31,7 @@ require 'tempfile' +$no_theme_name = 'none' theme_directory = ENV['ALAVETELI_THEMES_DIR'] alaveteli_directory = File.expand_path(File.join(File.dirname(__FILE__), "..")) @@ -53,7 +54,9 @@ $available_themes = Dir.entries(theme_directory).find_all do |local_theme_name| next unless File.directory? full_path next unless File.directory? File.join(full_path, '.git') local_theme_name -end +end.sort + +$available_themes.unshift $no_theme_name if $available_themes.empty? STDERR.puts "There were no theme directories found in '#{theme_directory}'" @@ -62,7 +65,7 @@ end def usage_and_exit STDERR.puts "Usage: #{$0} <THEME-NAME>" - $available_themes.sort.each do |theme_name| + $available_themes.each do |theme_name| STDERR.puts " #{theme_name}" end exit 1 @@ -108,13 +111,19 @@ symlink(File.basename(theme_filename), config_directory, "general.yml") -symlink(File.join(full_theme_path, 'public'), - File.join(alaveteli_directory, 'public'), - 'alavetelitheme') +public_directory = File.join(alaveteli_directory, 'public') -symlink(full_theme_path, - File.join(alaveteli_directory, 'lib', 'themes'), - requested_theme) +if requested_theme == $no_theme_name + File.unlink File.join(public_directory, 'alavetelitheme') +else + symlink(File.join(full_theme_path, 'public'), + public_directory, + 'alavetelitheme') + + symlink(full_theme_path, + File.join(alaveteli_directory, 'lib', 'themes'), + requested_theme) +end STDERR.puts """Switched to #{requested_theme}! You will need to: diff --git a/spec/mailers/request_mailer_spec.rb b/spec/mailers/request_mailer_spec.rb index 4e0765921..516d13127 100644 --- a/spec/mailers/request_mailer_spec.rb +++ b/spec/mailers/request_mailer_spec.rb @@ -332,6 +332,27 @@ describe RequestMailer, 'when sending mail when someone has updated an old uncla end +describe RequestMailer, 'when generating a fake response for an upload' do + + before do + @foi_officer = mock_model(User, :name_and_email => "FOI officer's name and email") + @request_user = mock_model(User) + @public_body = mock_model(PublicBody, :name => 'Test public body') + @info_request = mock_model(InfoRequest, :user => @request_user, + :email_subject_followup => 'Re: Freedom of Information - Test request', + :incoming_name_and_email => 'Someone <someone@example.org>') + end + + it 'should should generate a "fake response" email with a reasonable subject line' do + fake_email = RequestMailer.fake_response(@info_request, + @foi_officer, + "The body of the email...", + "blah.txt", + "The content of blah.txt") + fake_email.subject.should == "Re: Freedom of Information - Test request" + end + +end describe RequestMailer, 'when sending a new response email' do diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb index 23842ccff..d1e2e233d 100644 --- a/spec/models/public_body_spec.rb +++ b/spec/models/public_body_spec.rb @@ -473,6 +473,20 @@ describe PublicBody, " when loading CSV files" do PublicBody.count.should == original_count end + + it "should be able to load CSV from a file as well as a string" do + # Essentially the same code is used for import_csv_from_file + # as import_csv, so this is just a basic check that + # import_csv_from_file can load from a file at all. (It would + # be easy to introduce a regression that broke this, because + # of the confusing change in behaviour of CSV.parse between + # Ruby 1.8 and 1.9.) + original_count = PublicBody.count + filename = file_fixture_name('fake-authority-type-with-field-names.csv') + PublicBody.import_csv_from_file(filename, '', 'replace', false, 'someadmin') + PublicBody.count.should == original_count + 3 + end + end describe PublicBody do |